namespace BookStack\Activity\Tools;
use BookStack\Activity\Models\Tag;
+use BookStack\Entities\Models\BookChild;
+use BookStack\Entities\Models\Entity;
+use BookStack\Entities\Models\Page;
class TagClassGenerator
{
- protected array $tags;
-
- /**
- * @param Tag[] $tags
- */
- public function __construct(array $tags)
- {
- $this->tags = $tags;
+ public function __construct(
+ protected Entity $entity
+ ) {
}
/**
public function generate(): array
{
$classes = [];
+ $tags = $this->entity->tags->all();
+
+ foreach ($tags as $tag) {
+ array_push($classes, ...$this->generateClassesForTag($tag));
+ }
+
+ if ($this->entity instanceof BookChild && userCan('view', $this->entity->book)) {
+ $bookTags = $this->entity->book->tags;
+ foreach ($bookTags as $bookTag) {
+ array_push($classes, ...$this->generateClassesForTag($bookTag, 'book-'));
+ }
+ }
- foreach ($this->tags as $tag) {
- $name = $this->normalizeTagClassString($tag->name);
- $value = $this->normalizeTagClassString($tag->value);
- $classes[] = 'tag-name-' . $name;
- if ($value) {
- $classes[] = 'tag-value-' . $value;
- $classes[] = 'tag-pair-' . $name . '-' . $value;
+ if ($this->entity instanceof Page && $this->entity->chapter && userCan('view', $this->entity->chapter)) {
+ $chapterTags = $this->entity->chapter->tags;
+ foreach ($chapterTags as $chapterTag) {
+ array_push($classes, ...$this->generateClassesForTag($chapterTag, 'chapter-'));
}
}
return implode(' ', $this->generate());
}
+ /**
+ * @return string[]
+ */
+ protected function generateClassesForTag(Tag $tag, string $prefix = ''): array
+ {
+ $classes = [];
+ $name = $this->normalizeTagClassString($tag->name);
+ $value = $this->normalizeTagClassString($tag->value);
+ $classes[] = "{$prefix}tag-name-{$name}";
+ if ($value) {
+ $classes[] = "{$prefix}tag-value-{$value}";
+ $classes[] = "{$prefix}tag-pair-{$name}-{$value}";
+ }
+ return $classes;
+ }
+
protected function normalizeTagClassString(string $value): string
{
$value = str_replace(' ', '', strtolower($value));
$resp->assertDontSee('tag-name-<>', false);
$resp->assertSee('tag-name-<>', false);
}
+
+ public function test_parent_tag_classes_visible()
+ {
+ $page = $this->entities->pageWithinChapter();
+ $page->chapter->tags()->create(['name' => 'My Chapter Tag', 'value' => 'abc123']);
+ $page->book->tags()->create(['name' => 'My Book Tag', 'value' => 'def456']);
+ $this->asEditor();
+
+ $html = $this->withHtml($this->get($page->getUrl()));
+ $html->assertElementExists('body.chapter-tag-pair-mychaptertag-abc123');
+ $html->assertElementExists('body.book-tag-pair-mybooktag-def456');
+
+ $html = $this->withHtml($this->get($page->chapter->getUrl()));
+ $html->assertElementExists('body.book-tag-pair-mybooktag-def456');
+ }
+
+ public function test_parent_tag_classes_not_visible_if_cannot_see_parent()
+ {
+ $page = $this->entities->pageWithinChapter();
+ $page->chapter->tags()->create(['name' => 'My Chapter Tag', 'value' => 'abc123']);
+ $page->book->tags()->create(['name' => 'My Book Tag', 'value' => 'def456']);
+ $editor = $this->users->editor();
+ $this->actingAs($editor);
+
+ $this->permissions->setEntityPermissions($page, ['view'], [$editor->roles()->first()]);
+ $this->permissions->disableEntityInheritedPermissions($page->chapter);
+
+ $html = $this->withHtml($this->get($page->getUrl()));
+ $html->assertElementNotExists('body.chapter-tag-pair-mychaptertag-abc123');
+ $html->assertElementExists('body.book-tag-pair-mybooktag-def456');
+
+ $this->permissions->disableEntityInheritedPermissions($page->book);
+ $html = $this->withHtml($this->get($page->getUrl()));
+ $html->assertElementNotExists('body.book-tag-pair-mybooktag-def456');
+ }
}