]> BookStack Code Mirror - bookstack/blob - app/Exports/ZipExports/Models/ZipExportBook.php
ZIP Exports: Prevent book child page drafts from being included
[bookstack] / app / Exports / ZipExports / Models / ZipExportBook.php
1 <?php
2
3 namespace BookStack\Exports\ZipExports\Models;
4
5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\Chapter;
7 use BookStack\Entities\Models\Page;
8 use BookStack\Exports\ZipExports\ZipExportFiles;
9 use BookStack\Exports\ZipExports\ZipValidationHelper;
10
11 class ZipExportBook extends ZipExportModel
12 {
13     public ?int $id = null;
14     public string $name;
15     public ?string $description_html = null;
16     public ?string $cover = null;
17     /** @var ZipExportChapter[] */
18     public array $chapters = [];
19     /** @var ZipExportPage[] */
20     public array $pages = [];
21     /** @var ZipExportTag[] */
22     public array $tags = [];
23
24     public function metadataOnly(): void
25     {
26         $this->description_html = $this->cover = null;
27
28         foreach ($this->chapters as $chapter) {
29             $chapter->metadataOnly();
30         }
31         foreach ($this->pages as $page) {
32             $page->metadataOnly();
33         }
34         foreach ($this->tags as $tag) {
35             $tag->metadataOnly();
36         }
37     }
38
39     public function children(): array
40     {
41         $children = [
42             ...$this->pages,
43             ...$this->chapters,
44         ];
45
46         usort($children, function ($a, $b) {
47             return ($a->priority ?? 0) - ($b->priority ?? 0);
48         });
49
50         return $children;
51     }
52
53     public static function fromModel(Book $model, ZipExportFiles $files): self
54     {
55         $instance = new self();
56         $instance->id = $model->id;
57         $instance->name = $model->name;
58         $instance->description_html = $model->descriptionHtml();
59
60         if ($model->cover) {
61             $instance->cover = $files->referenceForImage($model->cover);
62         }
63
64         $instance->tags = ZipExportTag::fromModelArray($model->tags()->get()->all());
65
66         $chapters = [];
67         $pages = [];
68
69         $children = $model->getDirectVisibleChildren()->all();
70         foreach ($children as $child) {
71             if ($child instanceof Chapter) {
72                 $chapters[] = $child;
73             } else if ($child instanceof Page && !$child->draft) {
74                 $pages[] = $child;
75             }
76         }
77
78         $instance->pages = ZipExportPage::fromModelArray($pages, $files);
79         $instance->chapters = ZipExportChapter::fromModelArray($chapters, $files);
80
81         return $instance;
82     }
83
84     public static function validate(ZipValidationHelper $context, array $data): array
85     {
86         $rules = [
87             'id'    => ['nullable', 'int', $context->uniqueIdRule('book')],
88             'name'  => ['required', 'string', 'min:1'],
89             'description_html' => ['nullable', 'string'],
90             'cover' => ['nullable', 'string', $context->fileReferenceRule()],
91             'tags' => ['array'],
92             'pages' => ['array'],
93             'chapters' => ['array'],
94         ];
95
96         $errors = $context->validateData($data, $rules);
97         $errors['tags'] = $context->validateRelations($data['tags'] ?? [], ZipExportTag::class);
98         $errors['pages'] = $context->validateRelations($data['pages'] ?? [], ZipExportPage::class);
99         $errors['chapters'] = $context->validateRelations($data['chapters'] ?? [], ZipExportChapter::class);
100
101         return $errors;
102     }
103
104     public static function fromArray(array $data): self
105     {
106         $model = new self();
107
108         $model->id = $data['id'] ?? null;
109         $model->name = $data['name'];
110         $model->description_html = $data['description_html'] ?? null;
111         $model->cover = $data['cover'] ?? null;
112         $model->tags = ZipExportTag::fromManyArray($data['tags'] ?? []);
113         $model->pages = ZipExportPage::fromManyArray($data['pages'] ?? []);
114         $model->chapters = ZipExportChapter::fromManyArray($data['chapters'] ?? []);
115
116         return $model;
117     }
118 }