| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace BookStack\Entities\Tools; | 
					
						
							| 
									
										
										
										
											2021-05-29 19:39:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | use BookStack\Entities\Models\BookChild; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Entity; | 
					
						
							|  |  |  | use Illuminate\Support\Collection; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Finds the next or previous content of a book element (page or chapter). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class NextPreviousContentLocator | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     protected $relativeBookItem; | 
					
						
							|  |  |  |     protected $flatTree; | 
					
						
							|  |  |  |     protected $currentIndex = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * NextPreviousContentLocator constructor. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function __construct(BookChild $relativeBookItem, Collection $bookTree) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->relativeBookItem = $relativeBookItem; | 
					
						
							|  |  |  |         $this->flatTree = $this->treeToFlatOrderedCollection($bookTree); | 
					
						
							|  |  |  |         $this->currentIndex = $this->getCurrentIndex(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the next logical entity within the book hierarchy. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getNext(): ?Entity | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->flatTree->get($this->currentIndex + 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the next logical entity within the book hierarchy. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getPrevious(): ?Entity | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->flatTree->get($this->currentIndex - 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the index of the current relative item. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getCurrentIndex(): ?int | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $index = $this->flatTree->search(function (Entity $entity) { | 
					
						
							|  |  |  |             return get_class($entity) === get_class($this->relativeBookItem) | 
					
						
							|  |  |  |                 && $entity->id === $this->relativeBookItem->id; | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 19:39:41 +08:00
										 |  |  |         return $index === false ? null : $index; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Convert a book tree collection to a flattened version | 
					
						
							|  |  |  |      * where all items follow the expected order of user flow. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function treeToFlatOrderedCollection(Collection $bookTree): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $flatOrdered = collect(); | 
					
						
							|  |  |  |         /** @var Entity $item */ | 
					
						
							|  |  |  |         foreach ($bookTree->all() as $item) { | 
					
						
							|  |  |  |             $flatOrdered->push($item); | 
					
						
							| 
									
										
										
										
											2021-11-20 22:03:56 +08:00
										 |  |  |             $childPages = $item->getAttribute('visible_pages') ?? []; | 
					
						
							| 
									
										
										
										
											2021-05-29 19:39:41 +08:00
										 |  |  |             $flatOrdered = $flatOrdered->concat($childPages); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 19:39:41 +08:00
										 |  |  |         return $flatOrdered; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |