BookStack/app/Exports/ZipExports/ZipReferenceParser.php
Dan Brown d1f69feb4a
Some checks failed
test-migrations / build (8.1) (push) Has been cancelled
test-migrations / build (8.2) (push) Has been cancelled
analyse-php / build (push) Has been cancelled
lint-php / build (push) Has been cancelled
test-migrations / build (8.3) (push) Has been cancelled
test-php / build (8.1) (push) Has been cancelled
test-php / build (8.2) (push) Has been cancelled
test-php / build (8.3) (push) Has been cancelled
ZIP Exports: Tested each type and model of export
2024-10-27 14:33:43 +00:00

78 lines
2.3 KiB
PHP

<?php
namespace BookStack\Exports\ZipExports;
use BookStack\App\Model;
use BookStack\Entities\Queries\EntityQueries;
use BookStack\References\ModelResolvers\AttachmentModelResolver;
use BookStack\References\ModelResolvers\BookLinkModelResolver;
use BookStack\References\ModelResolvers\ChapterLinkModelResolver;
use BookStack\References\ModelResolvers\CrossLinkModelResolver;
use BookStack\References\ModelResolvers\ImageModelResolver;
use BookStack\References\ModelResolvers\PageLinkModelResolver;
use BookStack\References\ModelResolvers\PagePermalinkModelResolver;
class ZipReferenceParser
{
/**
* @var CrossLinkModelResolver[]
*/
protected array $modelResolvers;
public function __construct(EntityQueries $queries)
{
$this->modelResolvers = [
new PagePermalinkModelResolver($queries->pages),
new PageLinkModelResolver($queries->pages),
new ChapterLinkModelResolver($queries->chapters),
new BookLinkModelResolver($queries->books),
new ImageModelResolver(),
new AttachmentModelResolver(),
];
}
/**
* Parse and replace references in the given content.
* @param callable(Model):(string|null) $handler
*/
public function parse(string $content, callable $handler): string
{
$escapedBase = preg_quote(url('/'), '/');
$linkRegex = "/({$escapedBase}.*?)[\\t\\n\\f>\"'=?#()]/";
$matches = [];
preg_match_all($linkRegex, $content, $matches);
if (count($matches) < 2) {
return $content;
}
foreach ($matches[1] as $link) {
$model = $this->linkToModel($link);
if ($model) {
$result = $handler($model);
if ($result !== null) {
$content = str_replace($link, $result, $content);
}
}
}
return $content;
}
/**
* Attempt to resolve the given link to a model using the instance model resolvers.
*/
protected function linkToModel(string $link): ?Model
{
foreach ($this->modelResolvers as $resolver) {
$model = $resolver->resolve($link);
if (!is_null($model)) {
return $model;
}
}
return null;
}
}