| 
									
										
										
										
											2024-10-21 19:13:41 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace BookStack\References\ModelResolvers; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use BookStack\Uploads\Image; | 
					
						
							| 
									
										
										
										
											2024-11-26 23:59:39 +08:00
										 |  |  | use BookStack\Uploads\ImageStorage; | 
					
						
							| 
									
										
										
										
											2024-10-21 19:13:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class ImageModelResolver implements CrossLinkModelResolver | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-11-26 23:59:39 +08:00
										 |  |  |     protected ?string $pattern = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-21 19:13:41 +08:00
										 |  |  |     public function resolve(string $link): ?Image | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-11-26 23:59:39 +08:00
										 |  |  |         $pattern = $this->getUrlPattern(); | 
					
						
							| 
									
										
										
										
											2024-10-21 19:13:41 +08:00
										 |  |  |         $matches = []; | 
					
						
							|  |  |  |         $match = preg_match($pattern, $link, $matches); | 
					
						
							|  |  |  |         if (!$match) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-26 23:59:39 +08:00
										 |  |  |         $path = $matches[2]; | 
					
						
							| 
									
										
										
										
											2024-10-21 19:13:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Strip thumbnail element from path if existing
 | 
					
						
							|  |  |  |         $originalPathSplit = array_filter(explode('/', $path), function (string $part) { | 
					
						
							|  |  |  |             $resizedDir = (str_starts_with($part, 'thumbs-') || str_starts_with($part, 'scaled-')); | 
					
						
							|  |  |  |             $missingExtension = !str_contains($part, '.'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return !($resizedDir && $missingExtension); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Build a database-format image path and search for the image entry
 | 
					
						
							|  |  |  |         $fullPath = '/uploads/images/' . ltrim(implode('/', $originalPathSplit), '/'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return Image::query()->where('path', '=', $fullPath)->first(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-26 23:59:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the regex pattern to identify image URLs. | 
					
						
							|  |  |  |      * Caches the pattern since it requires looking up to settings/config. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getUrlPattern(): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($this->pattern) { | 
					
						
							|  |  |  |             return $this->pattern; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $urls = [url('/uploads/images')]; | 
					
						
							|  |  |  |         $baseImageUrl = ImageStorage::getPublicUrl('/uploads/images'); | 
					
						
							|  |  |  |         if ($baseImageUrl !== $urls[0]) { | 
					
						
							|  |  |  |             $urls[] = $baseImageUrl; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $imageUrlRegex = implode('|', array_map(fn ($url) => preg_quote($url, '/'), $urls)); | 
					
						
							|  |  |  |         $this->pattern = '/^(' . $imageUrlRegex . ')\/(.+)/'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->pattern; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-21 19:13:41 +08:00
										 |  |  | } |