]> BookStack Code Mirror - bookstack/blobdiff - app/Repos/EntityRepo.php
Added initial translation into German (formal)
[bookstack] / app / Repos / EntityRepo.php
index 46e1d98a5ced5d3864c41041aec924bf7e066b90..42b0b6b7bef89aecfbecc0f914fde8266ec7eb5e 100644 (file)
@@ -1,43 +1,69 @@
 <?php namespace BookStack\Repos;
 
-
 use BookStack\Book;
 use BookStack\Chapter;
+use BookStack\Entity;
 use BookStack\Page;
-use BookStack\Services\RestrictionService;
+use BookStack\Services\PermissionService;
+use BookStack\User;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Log;
 
 class EntityRepo
 {
 
+    /**
+     * @var Book $book
+     */
     public $book;
+
+    /**
+     * @var Chapter
+     */
     public $chapter;
+
+    /**
+     * @var Page
+     */
     public $page;
-    private $restrictionService;
+
+    /**
+     * @var PermissionService
+     */
+    protected $permissionService;
+
+    /**
+     * Acceptable operators to be used in a query
+     * @var array
+     */
+    protected $queryOperators = ['<=', '>=', '=', '<', '>', 'like', '!='];
 
     /**
      * EntityService constructor.
-     * @param Book $book
-     * @param Chapter $chapter
-     * @param Page $page
-     * @param RestrictionService $restrictionService
      */
-    public function __construct(Book $book, Chapter $chapter, Page $page, RestrictionService $restrictionService)
+    public function __construct()
     {
-        $this->book = $book;
-        $this->chapter = $chapter;
-        $this->page = $page;
-        $this->restrictionService = $restrictionService;
+        $this->book = app(Book::class);
+        $this->chapter = app(Chapter::class);
+        $this->page = app(Page::class);
+        $this->permissionService = app(PermissionService::class);
     }
 
     /**
      * Get the latest books added to the system.
-     * @param $count
-     * @param $page
+     * @param int $count
+     * @param int $page
+     * @param bool $additionalQuery
+     * @return
      */
-    public function getRecentlyCreatedBooks($count = 20, $page = 0)
+    public function getRecentlyCreatedBooks($count = 20, $page = 0, $additionalQuery = false)
     {
-        return $this->restrictionService->enforceBookRestrictions($this->book)
-            ->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
+        $query = $this->permissionService->enforceBookRestrictions($this->book)
+            ->orderBy('created_at', 'desc');
+        if ($additionalQuery !== false && is_callable($additionalQuery)) {
+            $additionalQuery($query);
+        }
+        return $query->skip($page * $count)->take($count)->get();
     }
 
     /**
@@ -48,19 +74,42 @@ class EntityRepo
      */
     public function getRecentlyUpdatedBooks($count = 20, $page = 0)
     {
-        return $this->restrictionService->enforceBookRestrictions($this->book)
-            ->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
+        return $this->permissionService->enforceBookRestrictions($this->book)
+            ->orderBy('updated_at', 'desc')->skip($page * $count)->take($count)->get();
     }
 
     /**
      * Get the latest pages added to the system.
-     * @param $count
-     * @param $page
+     * @param int $count
+     * @param int $page
+     * @param bool $additionalQuery
+     * @return
      */
-    public function getRecentlyCreatedPages($count = 20, $page = 0)
+    public function getRecentlyCreatedPages($count = 20, $page = 0, $additionalQuery = false)
     {
-        return $this->restrictionService->enforcePageRestrictions($this->page)
-            ->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
+        $query = $this->permissionService->enforcePageRestrictions($this->page)
+            ->orderBy('created_at', 'desc')->where('draft', '=', false);
+        if ($additionalQuery !== false && is_callable($additionalQuery)) {
+            $additionalQuery($query);
+        }
+        return $query->with('book')->skip($page * $count)->take($count)->get();
+    }
+
+    /**
+     * Get the latest chapters added to the system.
+     * @param int $count
+     * @param int $page
+     * @param bool $additionalQuery
+     * @return
+     */
+    public function getRecentlyCreatedChapters($count = 20, $page = 0, $additionalQuery = false)
+    {
+        $query = $this->permissionService->enforceChapterRestrictions($this->chapter)
+            ->orderBy('created_at', 'desc');
+        if ($additionalQuery !== false && is_callable($additionalQuery)) {
+            $additionalQuery($query);
+        }
+        return $query->skip($page * $count)->take($count)->get();
     }
 
     /**
@@ -71,9 +120,165 @@ class EntityRepo
      */
     public function getRecentlyUpdatedPages($count = 20, $page = 0)
     {
-        return $this->restrictionService->enforcePageRestrictions($this->page)
-            ->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
+        return $this->permissionService->enforcePageRestrictions($this->page)
+            ->where('draft', '=', false)
+            ->orderBy('updated_at', 'desc')->with('book')->skip($page * $count)->take($count)->get();
+    }
+
+    /**
+     * Get draft pages owned by the current user.
+     * @param int $count
+     * @param int $page
+     */
+    public function getUserDraftPages($count = 20, $page = 0)
+    {
+        return $this->page->where('draft', '=', true)
+            ->where('created_by', '=', user()->id)
+            ->orderBy('updated_at', 'desc')
+            ->skip($count * $page)->take($count)->get();
+    }
+
+    /**
+     * Updates entity restrictions from a request
+     * @param $request
+     * @param Entity $entity
+     */
+    public function updateEntityPermissionsFromRequest($request, Entity $entity)
+    {
+        $entity->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
+        $entity->permissions()->delete();
+        if ($request->has('restrictions')) {
+            foreach ($request->get('restrictions') as $roleId => $restrictions) {
+                foreach ($restrictions as $action => $value) {
+                    $entity->permissions()->create([
+                        'role_id' => $roleId,
+                        'action'  => strtolower($action)
+                    ]);
+                }
+            }
+        }
+        $entity->save();
+        $this->permissionService->buildJointPermissionsForEntity($entity);
+    }
+
+    /**
+     * Prepare a string of search terms by turning
+     * it into an array of terms.
+     * Keeps quoted terms together.
+     * @param $termString
+     * @return array
+     */
+    public function prepareSearchTerms($termString)
+    {
+        $termString = $this->cleanSearchTermString($termString);
+        preg_match_all('/(".*?")/', $termString, $matches);
+        $terms = [];
+        if (count($matches[1]) > 0) {
+            foreach ($matches[1] as $match) {
+                $terms[] = $match;
+            }
+            $termString = trim(preg_replace('/"(.*?)"/', '', $termString));
+        }
+        if (!empty($termString)) $terms = array_merge($terms, explode(' ', $termString));
+        return $terms;
     }
 
+    /**
+     * Removes any special search notation that should not
+     * be used in a full-text search.
+     * @param $termString
+     * @return mixed
+     */
+    protected function cleanSearchTermString($termString)
+    {
+        // Strip tag searches
+        $termString = preg_replace('/\[.*?\]/', '', $termString);
+        // Reduced multiple spacing into single spacing
+        $termString = preg_replace("/\s{2,}/", " ", $termString);
+        return $termString;
+    }
+
+    /**
+     * Get the available query operators as a regex escaped list.
+     * @return mixed
+     */
+    protected function getRegexEscapedOperators()
+    {
+        $escapedOperators = [];
+        foreach ($this->queryOperators as $operator) {
+            $escapedOperators[] = preg_quote($operator);
+        }
+        return join('|', $escapedOperators);
+    }
+
+    /**
+     * Parses advanced search notations and adds them to the db query.
+     * @param $query
+     * @param $termString
+     * @return mixed
+     */
+    protected function addAdvancedSearchQueries($query, $termString)
+    {
+        $escapedOperators = $this->getRegexEscapedOperators();
+        // Look for tag searches
+        preg_match_all("/\[(.*?)((${escapedOperators})(.*?))?\]/", $termString, $tags);
+        if (count($tags[0]) > 0) {
+            $this->applyTagSearches($query, $tags);
+        }
+
+        return $query;
+    }
+
+    /**
+     * Apply extracted tag search terms onto a entity query.
+     * @param $query
+     * @param $tags
+     * @return mixed
+     */
+    protected function applyTagSearches($query, $tags) {
+        $query->where(function($query) use ($tags) {
+            foreach ($tags[1] as $index => $tagName) {
+                $query->whereHas('tags', function($query) use ($tags, $index, $tagName) {
+                    $tagOperator = $tags[3][$index];
+                    $tagValue = $tags[4][$index];
+                    if (!empty($tagOperator) && !empty($tagValue) && in_array($tagOperator, $this->queryOperators)) {
+                        if (is_numeric($tagValue) && $tagOperator !== 'like') {
+                            // We have to do a raw sql query for this since otherwise PDO will quote the value and MySQL will
+                            // search the value as a string which prevents being able to do number-based operations
+                            // on the tag values. We ensure it has a numeric value and then cast it just to be sure.
+                            $tagValue = (float) trim($query->getConnection()->getPdo()->quote($tagValue), "'");
+                            $query->where('name', '=', $tagName)->whereRaw("value ${tagOperator} ${tagValue}");
+                        } else {
+                            $query->where('name', '=', $tagName)->where('value', $tagOperator, $tagValue);
+                        }
+                    } else {
+                        $query->where('name', '=', $tagName);
+                    }
+                });
+            }
+        });
+        return $query;
+    }
+
+    /**
+     * Alias method to update the book jointPermissions in the PermissionService.
+     * @param Collection $collection collection on entities
+     */
+    public function buildJointPermissions(Collection $collection)
+    {
+        $this->permissionService->buildJointPermissionsForEntities($collection);
+    }
+
+}
+
+
+
+
+
+
+
+
+
+
+
 
-}
\ No newline at end of file