]> BookStack Code Mirror - bookstack/blobdiff - app/Repos/PageRepo.php
Extracted page form js and added better page content linking
[bookstack] / app / Repos / PageRepo.php
index 441d5980e4cc7ac652850da63572223226884fea..1f0c618191122dd5ca10c1821dfdb358bab5834b 100644 (file)
@@ -1,7 +1,11 @@
 <?php namespace BookStack\Repos;
 
 
+use BookStack\Book;
+use BookStack\Chapter;
+use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Str;
 use BookStack\Page;
 use BookStack\PageRevision;
@@ -42,6 +46,10 @@ class PageRepo
         return $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
     }
 
+    /**
+     * @param $input
+     * @return Page
+     */
     public function newFromInput($input)
     {
         $page = $this->page->fill($input);
@@ -53,6 +61,83 @@ class PageRepo
         return $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId)->count();
     }
 
+    /**
+     * Save a new page into the system.
+     * Input validation must be done beforehand.
+     * @param array $input
+     * @param Book  $book
+     * @param int   $chapterId
+     * @return Page
+     */
+    public function saveNew(array $input, Book $book, $chapterId = null)
+    {
+        $page = $this->newFromInput($input);
+        $page->slug = $this->findSuitableSlug($page->name, $book->id);
+
+        if ($chapterId) $page->chapter_id = $chapterId;
+
+        $page->html = $this->formatHtml($input['html']);
+        $page->text = strip_tags($page->html);
+        $page->created_by = auth()->user()->id;
+        $page->updated_by = auth()->user()->id;
+
+        $book->pages()->save($page);
+        $this->saveRevision($page);
+        return $page;
+    }
+
+    /**
+     * Formats a page's html to be tagged correctly
+     * within the system.
+     * @param string $htmlText
+     * @return string
+     */
+    protected function formatHtml($htmlText)
+    {
+        libxml_use_internal_errors(true);
+        $doc = new \DOMDocument();
+        $doc->loadHTML($htmlText);
+
+        $container = $doc->documentElement;
+        $body = $container->childNodes[0];
+        $childNodes = $body->childNodes;
+
+        // Ensure no duplicate ids are used
+        $lastId = false;
+        $idArray = [];
+
+        foreach ($childNodes as $index => $childNode) {
+            /** @var \DOMElement $childNode */
+            if (get_class($childNode) !== 'DOMElement') continue;
+
+            // Overwrite id if not a bookstack custom id
+            if ($childNode->hasAttribute('id')) {
+                $id = $childNode->getAttribute('id');
+                if (strpos($id, 'bkmrk') === 0 && array_search($id, $idArray) === false) {
+                    $idArray[] = $id;
+                    continue;
+                };
+            }
+
+            // Create an unique id for the element
+            do {
+                $id = 'bkmrk-' . substr(uniqid(), -5);
+            } while ($id == $lastId);
+            $lastId = $id;
+
+            $childNode->setAttribute('id', $id);
+            $idArray[] = $id;
+        }
+
+        // Generate inner html as a string
+        $html = '';
+        foreach ($childNodes as $childNode) {
+            $html .= $doc->saveHTML($childNode);
+        }
+
+        return $html;
+    }
+
     public function destroyById($id)
     {
         $page = $this->getById($id);
@@ -99,8 +184,8 @@ class PageRepo
      */
     public function searchForImage($imageString)
     {
-        $pages = $this->page->where('html', 'like', '%'.$imageString.'%')->get();
-        foreach($pages as $page) {
+        $pages = $this->page->where('html', 'like', '%' . $imageString . '%')->get();
+        foreach ($pages as $page) {
             $page->url = $page->getUrl();
             $page->html = '';
             $page->text = '';
@@ -110,15 +195,16 @@ class PageRepo
 
     /**
      * Updates a page with any fillable data and saves it into the database.
-     * @param Page $page
-     * @param      $book_id
-     * @param      $data
+     * @param Page   $page
+     * @param int    $book_id
+     * @param string $input
      * @return Page
      */
-    public function updatePage(Page $page, $book_id, $data)
+    public function updatePage(Page $page, $book_id, $input)
     {
-        $page->fill($data);
+        $page->fill($input);
         $page->slug = $this->findSuitableSlug($page->name, $book_id, $page->id);
+        $page->html = $this->formatHtml($input['html']);
         $page->text = strip_tags($page->html);
         $page->updated_by = Auth::user()->id;
         $page->save();
@@ -189,7 +275,7 @@ class PageRepo
     public function setBookId($bookId, Page $page)
     {
         $page->book_id = $bookId;
-        foreach($page->activity as $activity) {
+        foreach ($page->activity as $activity) {
             $activity->book_id = $bookId;
             $activity->save();
         }