3 namespace BookStack\References;
5 use BookStack\App\Model;
6 use BookStack\Entities\Queries\EntityQueries;
7 use BookStack\References\ModelResolvers\BookLinkModelResolver;
8 use BookStack\References\ModelResolvers\BookshelfLinkModelResolver;
9 use BookStack\References\ModelResolvers\ChapterLinkModelResolver;
10 use BookStack\References\ModelResolvers\CrossLinkModelResolver;
11 use BookStack\References\ModelResolvers\PageLinkModelResolver;
12 use BookStack\References\ModelResolvers\PagePermalinkModelResolver;
13 use BookStack\Util\HtmlDocument;
18 * @var CrossLinkModelResolver[]
20 protected array $modelResolvers;
22 public function __construct(array $modelResolvers)
24 $this->modelResolvers = $modelResolvers;
28 * Extract any found models within the given HTML content.
32 public function extractLinkedModels(string $html): array
36 $links = $this->getLinksFromContent($html);
38 foreach ($links as $link) {
39 $model = $this->linkToModel($link);
40 if (!is_null($model)) {
41 $models[get_class($model) . ':' . $model->id] = $model;
45 return array_values($models);
49 * Get a list of href values from the given document.
53 protected function getLinksFromContent(string $html): array
57 $doc = new HtmlDocument($html);
58 $anchors = $doc->queryXPath('//a[@href]');
60 /** @var \DOMElement $anchor */
61 foreach ($anchors as $anchor) {
62 $links[] = $anchor->getAttribute('href');
69 * Attempt to resolve the given link to a model using the instance model resolvers.
71 protected function linkToModel(string $link): ?Model
73 foreach ($this->modelResolvers as $resolver) {
74 $model = $resolver->resolve($link);
75 if (!is_null($model)) {
84 * Create a new instance with a pre-defined set of model resolvers, specifically for the
85 * default set of entities within BookStack.
87 public static function createWithEntityResolvers(): self
89 $queries = app()->make(EntityQueries::class);
92 new PagePermalinkModelResolver($queries->pages),
93 new PageLinkModelResolver($queries->pages),
94 new ChapterLinkModelResolver($queries->chapters),
95 new BookLinkModelResolver($queries->books),
96 new BookshelfLinkModelResolver($queries->shelves),