]> BookStack Code Mirror - bookstack/blobdiff - app/Entities/SearchService.php
Update settings.php
[bookstack] / app / Entities / SearchService.php
index 0bfdab7eabe2c7237084b3a545fe7730b3ca9bdb..ee9b87786a57a1e059ed050621f0c694427b17cb 100644 (file)
@@ -1,31 +1,35 @@
 <?php namespace BookStack\Entities;
 
-use BookStack\Entities\Book;
-use BookStack\Entities\Bookshelf;
-use BookStack\Entities\Chapter;
-use BookStack\Entities\Entity;
-use BookStack\Entities\Page;
-use BookStack\Entities\SearchTerm;
 use BookStack\Auth\Permissions\PermissionService;
 use Illuminate\Database\Connection;
+use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
 use Illuminate\Database\Query\Builder;
 use Illuminate\Database\Query\JoinClause;
 use Illuminate\Support\Collection;
+use Illuminate\Support\Str;
 
 class SearchService
 {
+    /**
+     * @var SearchTerm
+     */
     protected $searchTerm;
-    protected $bookshelf;
-    protected $book;
-    protected $chapter;
-    protected $page;
+
+    /**
+     * @var EntityProvider
+     */
+    protected $entityProvider;
+
+    /**
+     * @var Connection
+     */
     protected $db;
-    protected $permissionService;
 
     /**
-     * @var Entity[]
+     * @var PermissionService
      */
-    protected $entities;
+    protected $permissionService;
+
 
     /**
      * Acceptable operators to be used in a query
@@ -36,27 +40,15 @@ class SearchService
     /**
      * SearchService constructor.
      * @param SearchTerm $searchTerm
-     * @param Bookshelf $bookshelf
-     * @param \BookStack\Entities\Book $book
-     * @param \BookStack\Entities\Chapter $chapter
-     * @param Page $page
+     * @param EntityProvider $entityProvider
      * @param Connection $db
      * @param PermissionService $permissionService
      */
-    public function __construct(SearchTerm $searchTerm, Bookshelf $bookshelf, Book $book, Chapter $chapter, Page $page, Connection $db, PermissionService $permissionService)
+    public function __construct(SearchTerm $searchTerm, EntityProvider $entityProvider, Connection $db, PermissionService $permissionService)
     {
         $this->searchTerm = $searchTerm;
-        $this->bookshelf = $bookshelf;
-        $this->book = $book;
-        $this->chapter = $chapter;
-        $this->page = $page;
+        $this->entityProvider = $entityProvider;
         $this->db = $db;
-        $this->entities = [
-            'bookshelf' => $this->bookshelf,
-            'page' => $this->page,
-            'chapter' => $this->chapter,
-            'book' => $this->book
-        ];
         $this->permissionService = $permissionService;
     }
 
@@ -81,7 +73,7 @@ class SearchService
     public function searchEntities($searchString, $entityType = 'all', $page = 1, $count = 20, $action = 'view')
     {
         $terms = $this->parseSearchString($searchString);
-        $entityTypes = array_keys($this->entities);
+        $entityTypes = array_keys($this->entityProvider->all());
         $entityTypesToSearch = $entityTypes;
 
         if ($entityType !== 'all') {
@@ -178,17 +170,17 @@ class SearchService
      * @param array $terms
      * @param string $entityType
      * @param string $action
-     * @return \Illuminate\Database\Eloquent\Builder
+     * @return EloquentBuilder
      */
     protected function buildEntitySearchQuery($terms, $entityType = 'page', $action = 'view')
     {
-        $entity = $this->getEntity($entityType);
+        $entity = $this->entityProvider->get($entityType);
         $entitySelect = $entity->newQuery();
 
         // Handle normal search terms
         if (count($terms['search']) > 0) {
             $subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', \DB::raw('SUM(score) as score'));
-            $subQuery->where('entity_type', '=', 'BookStack\\' . ucfirst($entityType));
+            $subQuery->where('entity_type', '=', $entity->getMorphClass());
             $subQuery->where(function (Builder $query) use ($terms) {
                 foreach ($terms['search'] as $inputTerm) {
                     $query->orWhere('term', 'like', $inputTerm .'%');
@@ -202,9 +194,9 @@ class SearchService
 
         // Handle exact term matching
         if (count($terms['exact']) > 0) {
-            $entitySelect->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($terms, $entity) {
+            $entitySelect->where(function (EloquentBuilder $query) use ($terms, $entity) {
                 foreach ($terms['exact'] as $inputTerm) {
-                    $query->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($inputTerm, $entity) {
+                    $query->where(function (EloquentBuilder $query) use ($inputTerm, $entity) {
                         $query->where('name', 'like', '%'.$inputTerm .'%')
                             ->orWhere($entity->textField, 'like', '%'.$inputTerm .'%');
                     });
@@ -219,7 +211,7 @@ class SearchService
 
         // Handle filters
         foreach ($terms['filters'] as $filterTerm => $filterValue) {
-            $functionName = camel_case('filter_' . $filterTerm);
+            $functionName = Str::camel('filter_' . $filterTerm);
             if (method_exists($this, $functionName)) {
                 $this->$functionName($entitySelect, $entity, $filterValue);
             }
@@ -292,14 +284,14 @@ class SearchService
 
     /**
      * Apply a tag search term onto a entity query.
-     * @param \Illuminate\Database\Eloquent\Builder $query
+     * @param EloquentBuilder $query
      * @param string $tagTerm
      * @return mixed
      */
-    protected function applyTagSearch(\Illuminate\Database\Eloquent\Builder $query, $tagTerm)
+    protected function applyTagSearch(EloquentBuilder $query, $tagTerm)
     {
         preg_match("/^(.*?)((".$this->getRegexEscapedOperators().")(.*?))?$/", $tagTerm, $tagSplit);
-        $query->whereHas('tags', function (\Illuminate\Database\Eloquent\Builder $query) use ($tagSplit) {
+        $query->whereHas('tags', function (EloquentBuilder $query) use ($tagSplit) {
             $tagName = $tagSplit[1];
             $tagOperator = count($tagSplit) > 2 ? $tagSplit[3] : '';
             $tagValue = count($tagSplit) > 3 ? $tagSplit[4] : '';
@@ -324,16 +316,6 @@ class SearchService
         return $query;
     }
 
-    /**
-     * Get an entity instance via type.
-     * @param $type
-     * @return Entity
-     */
-    protected function getEntity($type)
-    {
-        return $this->entities[strtolower($type)];
-    }
-
     /**
      * Index the given entity.
      * @param Entity $entity
@@ -381,7 +363,7 @@ class SearchService
     {
         $this->searchTerm->truncate();
 
-        foreach ($this->entities as $entityModel) {
+        foreach ($this->entityProvider->all() as $entityModel) {
             $selectFields = ['id', 'name', $entityModel->textField];
             $entityModel->newQuery()->select($selectFields)->chunk(1000, function ($entities) {
                 $this->indexEntities($entities);
@@ -435,7 +417,7 @@ class SearchService
      * Custom entity search filters
      */
 
-    protected function filterUpdatedAfter(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterUpdatedAfter(EloquentBuilder $query, Entity $model, $input)
     {
         try {
             $date = date_create($input);
@@ -445,7 +427,7 @@ class SearchService
         $query->where('updated_at', '>=', $date);
     }
 
-    protected function filterUpdatedBefore(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterUpdatedBefore(EloquentBuilder $query, Entity $model, $input)
     {
         try {
             $date = date_create($input);
@@ -455,7 +437,7 @@ class SearchService
         $query->where('updated_at', '<', $date);
     }
 
-    protected function filterCreatedAfter(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterCreatedAfter(EloquentBuilder $query, Entity $model, $input)
     {
         try {
             $date = date_create($input);
@@ -465,7 +447,7 @@ class SearchService
         $query->where('created_at', '>=', $date);
     }
 
-    protected function filterCreatedBefore(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterCreatedBefore(EloquentBuilder $query, Entity $model, $input)
     {
         try {
             $date = date_create($input);
@@ -475,7 +457,7 @@ class SearchService
         $query->where('created_at', '<', $date);
     }
 
-    protected function filterCreatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterCreatedBy(EloquentBuilder $query, Entity $model, $input)
     {
         if (!is_numeric($input) && $input !== 'me') {
             return;
@@ -486,7 +468,7 @@ class SearchService
         $query->where('created_by', '=', $input);
     }
 
-    protected function filterUpdatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterUpdatedBy(EloquentBuilder $query, Entity $model, $input)
     {
         if (!is_numeric($input) && $input !== 'me') {
             return;
@@ -497,43 +479,43 @@ class SearchService
         $query->where('updated_by', '=', $input);
     }
 
-    protected function filterInName(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterInName(EloquentBuilder $query, Entity $model, $input)
     {
         $query->where('name', 'like', '%' .$input. '%');
     }
 
-    protected function filterInTitle(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterInTitle(EloquentBuilder $query, Entity $model, $input)
     {
         $this->filterInName($query, $model, $input);
     }
 
-    protected function filterInBody(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterInBody(EloquentBuilder $query, Entity $model, $input)
     {
         $query->where($model->textField, 'like', '%' .$input. '%');
     }
 
-    protected function filterIsRestricted(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterIsRestricted(EloquentBuilder $query, Entity $model, $input)
     {
         $query->where('restricted', '=', true);
     }
 
-    protected function filterViewedByMe(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterViewedByMe(EloquentBuilder $query, Entity $model, $input)
     {
         $query->whereHas('views', function ($query) {
             $query->where('user_id', '=', user()->id);
         });
     }
 
-    protected function filterNotViewedByMe(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterNotViewedByMe(EloquentBuilder $query, Entity $model, $input)
     {
         $query->whereDoesntHave('views', function ($query) {
             $query->where('user_id', '=', user()->id);
         });
     }
 
-    protected function filterSortBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
+    protected function filterSortBy(EloquentBuilder $query, Entity $model, $input)
     {
-        $functionName = camel_case('sort_by_' . $input);
+        $functionName = Str::camel('sort_by_' . $input);
         if (method_exists($this, $functionName)) {
             $this->$functionName($query, $model);
         }
@@ -544,7 +526,7 @@ class SearchService
      * Sorting filter options
      */
 
-    protected function sortByLastCommented(\Illuminate\Database\Eloquent\Builder $query, Entity $model)
+    protected function sortByLastCommented(EloquentBuilder $query, Entity $model)
     {
         $commentsTable = $this->db->getTablePrefix() . 'comments';
         $morphClass = str_replace('\\', '\\\\', $model->getMorphClass());