]> BookStack Code Mirror - bookstack/blob - app/Entities/Repos/ChapterRepo.php
2b81891af63ce5fd67410bf62517c728e1e1d3bd
[bookstack] / app / Entities / Repos / ChapterRepo.php
1 <?php
2
3 namespace BookStack\Entities\Repos;
4
5 use BookStack\Actions\ActivityType;
6 use BookStack\Entities\Models\Book;
7 use BookStack\Entities\Models\Chapter;
8 use BookStack\Entities\Models\Entity;
9 use BookStack\Entities\Tools\BookContents;
10 use BookStack\Entities\Tools\TrashCan;
11 use BookStack\Exceptions\MoveOperationException;
12 use BookStack\Exceptions\NotFoundException;
13 use BookStack\Exceptions\PermissionsException;
14 use BookStack\Facades\Activity;
15 use Exception;
16
17 class ChapterRepo
18 {
19     protected $baseRepo;
20
21     /**
22      * ChapterRepo constructor.
23      */
24     public function __construct(BaseRepo $baseRepo)
25     {
26         $this->baseRepo = $baseRepo;
27     }
28
29     /**
30      * Get a chapter via the slug.
31      *
32      * @throws NotFoundException
33      */
34     public function getBySlug(string $bookSlug, string $chapterSlug): Chapter
35     {
36         $chapter = Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->first();
37
38         if ($chapter === null) {
39             throw new NotFoundException(trans('errors.chapter_not_found'));
40         }
41
42         return $chapter;
43     }
44
45     /**
46      * Create a new chapter in the system.
47      */
48     public function create(array $input, Book $parentBook): Chapter
49     {
50         $chapter = new Chapter();
51         $chapter->book_id = $parentBook->id;
52         $chapter->priority = (new BookContents($parentBook))->getLastPriority() + 1;
53         $this->baseRepo->create($chapter, $input);
54         Activity::add(ActivityType::CHAPTER_CREATE, $chapter);
55
56         return $chapter;
57     }
58
59     /**
60      * Update the given chapter.
61      */
62     public function update(Chapter $chapter, array $input): Chapter
63     {
64         $this->baseRepo->update($chapter, $input);
65         Activity::add(ActivityType::CHAPTER_UPDATE, $chapter);
66
67         return $chapter;
68     }
69
70     /**
71      * Remove a chapter from the system.
72      *
73      * @throws Exception
74      */
75     public function destroy(Chapter $chapter)
76     {
77         $trashCan = new TrashCan();
78         $trashCan->softDestroyChapter($chapter);
79         Activity::add(ActivityType::CHAPTER_DELETE, $chapter);
80         $trashCan->autoClearOld();
81     }
82
83     /**
84      * Move the given chapter into a new parent book.
85      * The $parentIdentifier must be a string of the following format:
86      * 'book:<id>' (book:5).
87      *
88      * @throws MoveOperationException
89      * @throws PermissionsException
90      */
91     public function move(Chapter $chapter, string $parentIdentifier): Book
92     {
93         $parent = $this->findParentByIdentifier($parentIdentifier);
94         if (is_null($parent)) {
95             throw new MoveOperationException('Book to move chapter into not found');
96         }
97
98         if (!userCan('chapter-create', $parent)) {
99             throw new PermissionsException('User does not have permission to create a chapter within the chosen book');
100         }
101
102         $chapter->changeBook($parent->id);
103         $chapter->rebuildPermissions();
104         Activity::add(ActivityType::CHAPTER_MOVE, $chapter);
105
106         return $parent;
107     }
108
109     /**
110      * Find a page parent entity via an identifier string in the format:
111      * {type}:{id}
112      * Example: (book:5).
113      *
114      * @throws MoveOperationException
115      */
116     public function findParentByIdentifier(string $identifier): ?Book
117     {
118         $stringExploded = explode(':', $identifier);
119         $entityType = $stringExploded[0];
120         $entityId = intval($stringExploded[1]);
121
122         if ($entityType !== 'book') {
123             throw new MoveOperationException('Chapters can only be in books');
124         }
125
126         return Book::visible()->where('id', '=', $entityId)->first();
127     }
128 }