xref: /plugin/dw2pdf/src/Config.php (revision a9cd524ed3465a8385c4a367213f90bb9717f5b7)
1c5c184fdSAndreas Gohr<?php
2c5c184fdSAndreas Gohr
3c5c184fdSAndreas Gohrnamespace dokuwiki\plugin\dw2pdf\src;
4c5c184fdSAndreas Gohr
501a7083bSAndreas Gohruse dokuwiki\plugin\dw2pdf\src\attributes\FromConfig;
601a7083bSAndreas Gohruse dokuwiki\plugin\dw2pdf\src\attributes\FromInput;
701a7083bSAndreas Gohr
8c5c184fdSAndreas Gohrclass Config
9c5c184fdSAndreas Gohr{
10c5c184fdSAndreas Gohr    protected string $tempDir = '';
1101a7083bSAndreas Gohr
1201a7083bSAndreas Gohr    // General PDF configuration
1301a7083bSAndreas Gohr    #[FromConfig, FromInput]
14c5c184fdSAndreas Gohr    protected string $pagesize = 'A4';
1501a7083bSAndreas Gohr    #[FromConfig('orientation'), FromInput('orientation')]
16c5c184fdSAndreas Gohr    protected bool $isLandscape = false;
1701a7083bSAndreas Gohr    #[FromConfig('font-size'), FromInput('font-size')]
18c5c184fdSAndreas Gohr    protected int $fontSize = 11;
1901a7083bSAndreas Gohr    #[FromConfig('doublesided'), FromInput('doublesided')]
20c5c184fdSAndreas Gohr    protected bool $isDoublesided = false;
21212a1ea5SAndreas Gohr    #[FromConfig('toc'), FromInput('toc')]
22c5c184fdSAndreas Gohr    protected bool $hasToC = false;
2301a7083bSAndreas Gohr    #[FromConfig, FromInput('toclevels')]
24c5c184fdSAndreas Gohr    protected array $tocLevels = [];
2501a7083bSAndreas Gohr    #[FromConfig]
26c5c184fdSAndreas Gohr    protected int $maxBookmarks = 5;
2701a7083bSAndreas Gohr    #[FromConfig('headernumber')]
280eefd8f7SAndreas Gohr    protected bool $numberedHeaders = false;
2901a7083bSAndreas Gohr    #[FromConfig, FromInput]
30c5c184fdSAndreas Gohr    protected string $watermark = '';
31212a1ea5SAndreas Gohr    #[FromConfig, FromInput('tpl')]
32c5c184fdSAndreas Gohr    protected string $template = 'default';
3301a7083bSAndreas Gohr    #[FromConfig('debug'), FromInput('debug')]
341d334a8cSAndreas Gohr    protected bool $isDebug = false;
3501a7083bSAndreas Gohr    #[FromConfig]
36da4f9133SAnna Dabrowska    protected bool $usecache;
37da4f9133SAnna Dabrowska    #[FromConfig]
38081fc334SAndreas Gohr    protected array $useStyles = [];
3901a7083bSAndreas Gohr    #[FromConfig]
40293d84e6SAndreas Gohr    protected float $qrCodeScale = 0.0;
41212a1ea5SAndreas Gohr    #[FromConfig('output'), FromInput('outputTarget')]
4270028127SAndreas Gohr    protected string $outputTarget = 'file';
43c5c184fdSAndreas Gohr
44decfd8d6SAndreas Gohr    // Collector-specific request data
4501a7083bSAndreas Gohr    #[FromConfig, FromInput('book_title')]
46decfd8d6SAndreas Gohr    protected ?string $bookTitle = null;
4701a7083bSAndreas Gohr    #[FromConfig, FromInput('book_ns')]
48decfd8d6SAndreas Gohr    protected string $bookNamespace = '';
4901a7083bSAndreas Gohr    #[FromConfig, FromInput('book_order')]
50decfd8d6SAndreas Gohr    protected string $bookSortOrder = 'natural';
5101a7083bSAndreas Gohr    #[FromConfig, FromInput('book_nsdepth')]
52decfd8d6SAndreas Gohr    protected int $bookNamespaceDepth = 0;
5301a7083bSAndreas Gohr    #[FromConfig, FromInput('excludes')]
54decfd8d6SAndreas Gohr    protected array $bookExcludePages = [];
5501a7083bSAndreas Gohr    #[FromConfig, FromInput('excludesns')]
56decfd8d6SAndreas Gohr    protected array $bookExcludeNamespaces = [];
5701a7083bSAndreas Gohr    #[FromConfig, FromInput('selection')]
58decfd8d6SAndreas Gohr    protected ?string $liveSelection = null;
5901a7083bSAndreas Gohr    #[FromConfig, FromInput('savedselection')]
60decfd8d6SAndreas Gohr    protected ?string $savedSelection = null;
61212a1ea5SAndreas Gohr    #[FromConfig] // also read from global $ID
62b23d7b8aSAndreas Gohr    protected string $exportId = '';
63decfd8d6SAndreas Gohr
64c5c184fdSAndreas Gohr    /**
65c5c184fdSAndreas Gohr     * @param array $pluginConf Plugin configuration
66c5c184fdSAndreas Gohr     */
67293d84e6SAndreas Gohr    public function __construct(array $pluginConf = [])
68c5c184fdSAndreas Gohr    {
69c5c184fdSAndreas Gohr        global $conf;
70c5c184fdSAndreas Gohr        $this->tempDir = $conf['tmpdir'] . '/mpdf';
71c5c184fdSAndreas Gohr        io_mkdir_p($this->tempDir);
72c5c184fdSAndreas Gohr
73c5c184fdSAndreas Gohr        // set default ToC levels from main config
74c5c184fdSAndreas Gohr        $this->tocLevels = $this->parseTocLevels($conf['toptoclevel'] . '-' . $conf['maxtoclevel']);
75c5c184fdSAndreas Gohr
76c5c184fdSAndreas Gohr        $this->loadPluginConfig($pluginConf);
77c5c184fdSAndreas Gohr        $this->loadInputConfig();
78c5c184fdSAndreas Gohr    }
79c5c184fdSAndreas Gohr
80c5c184fdSAndreas Gohr    /**
8101a7083bSAndreas Gohr     * Set a property with type casting and custom parsing
8201a7083bSAndreas Gohr     *
8301a7083bSAndreas Gohr     * @param string $prop The property name to set
8401a7083bSAndreas Gohr     * @param string|null $type The property type
8501a7083bSAndreas Gohr     * @param mixed $value The value to set
8601a7083bSAndreas Gohr     * @return void
8701a7083bSAndreas Gohr     * @see loadPluginConfig
8801a7083bSAndreas Gohr     * @see loadInputConfig
8901a7083bSAndreas Gohr     */
9001a7083bSAndreas Gohr    protected function setProperty(string $prop, ?string $type, $value)
9101a7083bSAndreas Gohr    {
92212a1ea5SAndreas Gohr        // custom value parsing (lowercased property names to avoid mistakes)
93212a1ea5SAndreas Gohr        $value = match (strtolower($prop)) {
94212a1ea5SAndreas Gohr            'islandscape' => ($value === 'landscape'),
95212a1ea5SAndreas Gohr            'toclevels' => is_array($value) ? $value : $this->parseTocLevels((string)$value),
96212a1ea5SAndreas Gohr            'exportid' => cleanID((string)$value),
9701a7083bSAndreas Gohr            default => $value,
9801a7083bSAndreas Gohr        };
9901a7083bSAndreas Gohr
10001a7083bSAndreas Gohr        // standard type casting
10101a7083bSAndreas Gohr        $this->$prop = match ($type) {
10201a7083bSAndreas Gohr            'int' => (int)$value,
10301a7083bSAndreas Gohr            'bool' => (bool)$value,
10401a7083bSAndreas Gohr            'float' => (float)$value,
10501a7083bSAndreas Gohr            'array' => is_array($value)
10601a7083bSAndreas Gohr                ? $value
10701a7083bSAndreas Gohr                : array_filter(array_map('trim', explode(',', (string)$value))),
10801a7083bSAndreas Gohr            default => $value,
10901a7083bSAndreas Gohr        };
11001a7083bSAndreas Gohr    }
11101a7083bSAndreas Gohr
11201a7083bSAndreas Gohr    /**
113c5c184fdSAndreas Gohr     * Apply the given configuration
114c5c184fdSAndreas Gohr     *
11501a7083bSAndreas Gohr     * This will set all properties annotated with FromConfig
11601a7083bSAndreas Gohr     *
11701a7083bSAndreas Gohr     * @param array $conf (Plugin) configuration
118c5c184fdSAndreas Gohr     */
11901a7083bSAndreas Gohr    public function loadPluginConfig(array $conf = [])
120c5c184fdSAndreas Gohr    {
12101a7083bSAndreas Gohr        $reflection = new \ReflectionClass($this);
12201a7083bSAndreas Gohr        foreach ($reflection->getProperties() as $property) {
12301a7083bSAndreas Gohr            $attributes = $property->getAttributes(FromConfig::class);
12401a7083bSAndreas Gohr            if ($attributes === []) continue;
12501a7083bSAndreas Gohr            $attribute = $attributes[0]->newInstance(); // we only expect one
12601a7083bSAndreas Gohr
12701a7083bSAndreas Gohr            $prop = $property->getName();
12801a7083bSAndreas Gohr            $confName = $attribute->name ?? strtolower($prop);
12901a7083bSAndreas Gohr            $type = $property->getType()?->getName();
13001a7083bSAndreas Gohr
13101a7083bSAndreas Gohr            if (!isset($conf[$confName])) continue;
13201a7083bSAndreas Gohr            $this->setProperty($prop, $type, $conf[$confName]);
133081fc334SAndreas Gohr        }
134c5c184fdSAndreas Gohr    }
135c5c184fdSAndreas Gohr
136c5c184fdSAndreas Gohr    /**
137c5c184fdSAndreas Gohr     * Load configuration provided by INPUT parameters
138c5c184fdSAndreas Gohr     *
139c5c184fdSAndreas Gohr     * Not all parameters are overridable here
140c5c184fdSAndreas Gohr     *
141c5c184fdSAndreas Gohr     * @return void
142c5c184fdSAndreas Gohr     */
143c5c184fdSAndreas Gohr    public function loadInputConfig()
144c5c184fdSAndreas Gohr    {
145*a9cd524eSAndreas Gohr        global $INPUT, $ID, $conf;
14601a7083bSAndreas Gohr
14708b6e06bSAndreas Gohr        if (!blank($ID)) $this->exportId = $ID; // default exportId to current page ID
14801a7083bSAndreas Gohr
14901a7083bSAndreas Gohr        $reflection = new \ReflectionClass($this);
15001a7083bSAndreas Gohr        foreach ($reflection->getProperties() as $property) {
15101a7083bSAndreas Gohr            $attributes = $property->getAttributes(FromInput::class);
15201a7083bSAndreas Gohr            if ($attributes === []) continue;
15301a7083bSAndreas Gohr            $attribute = $attributes[0]->newInstance(); // we only expect one
15401a7083bSAndreas Gohr
15501a7083bSAndreas Gohr            $prop = $property->getName();
15601a7083bSAndreas Gohr            $confName = $attribute->name ?? strtolower($prop);
15701a7083bSAndreas Gohr            $type = $property->getType()?->getName();
15801a7083bSAndreas Gohr
15901a7083bSAndreas Gohr            if (!$INPUT->has($confName)) continue;
160*a9cd524eSAndreas Gohr
161*a9cd524eSAndreas Gohr            // debug output exposes the raw mPDF input and bypasses the cache, so it may only be
162*a9cd524eSAndreas Gohr            // requested via URL when core debugging is enabled
163*a9cd524eSAndreas Gohr            if ($prop === 'isDebug' && empty($conf['allowdebug'])) continue;
164*a9cd524eSAndreas Gohr
16501a7083bSAndreas Gohr            $this->setProperty($prop, $type, $INPUT->param($confName));
166c5c184fdSAndreas Gohr        }
167c5c184fdSAndreas Gohr    }
168c5c184fdSAndreas Gohr
169b883aeceSAndreas Gohr    /**
170b883aeceSAndreas Gohr     * Check whether ToC is enabled
171b883aeceSAndreas Gohr     *
172b883aeceSAndreas Gohr     * @return bool
173b883aeceSAndreas Gohr     */
174081fc334SAndreas Gohr    public function hasToc(): bool
175b883aeceSAndreas Gohr    {
176b883aeceSAndreas Gohr        return $this->hasToC;
177b883aeceSAndreas Gohr    }
178c5c184fdSAndreas Gohr
179c5c184fdSAndreas Gohr    /**
1801d334a8cSAndreas Gohr     * Check whether debug mode is enabled
1811d334a8cSAndreas Gohr     *
1821d334a8cSAndreas Gohr     * @return bool
1831d334a8cSAndreas Gohr     */
184081fc334SAndreas Gohr    public function isDebugEnabled(): bool
1851d334a8cSAndreas Gohr    {
1861d334a8cSAndreas Gohr        return $this->isDebug;
1871d334a8cSAndreas Gohr    }
1881d334a8cSAndreas Gohr
1891d334a8cSAndreas Gohr    /**
190da4f9133SAnna Dabrowska     * Check if caching is enabled
191da4f9133SAnna Dabrowska     *
192da4f9133SAnna Dabrowska     * @return bool
193da4f9133SAnna Dabrowska     */
194da4f9133SAnna Dabrowska    public function useCache(): bool
195da4f9133SAnna Dabrowska    {
196da4f9133SAnna Dabrowska        return $this->usecache;
197da4f9133SAnna Dabrowska    }
198da4f9133SAnna Dabrowska
199da4f9133SAnna Dabrowska    /**
200081fc334SAndreas Gohr     * Get a list of extensions whose screen styles should be applied
201081fc334SAndreas Gohr     *
202081fc334SAndreas Gohr     * @return string[]
203081fc334SAndreas Gohr     */
204081fc334SAndreas Gohr    public function getStyledExtensions(): array
205081fc334SAndreas Gohr    {
206081fc334SAndreas Gohr        return $this->useStyles;
207081fc334SAndreas Gohr    }
208081fc334SAndreas Gohr
209081fc334SAndreas Gohr    /**
210081fc334SAndreas Gohr     * Get the name of the selected template
211081fc334SAndreas Gohr     *
212081fc334SAndreas Gohr     * @return string
213081fc334SAndreas Gohr     */
214081fc334SAndreas Gohr    public function getTemplateName(): string
215081fc334SAndreas Gohr    {
216081fc334SAndreas Gohr        return $this->template;
217081fc334SAndreas Gohr    }
218081fc334SAndreas Gohr
219293d84e6SAndreas Gohr    /**
2200eefd8f7SAndreas Gohr     * Get the maximum number of bookmarks to include
2210eefd8f7SAndreas Gohr     *
2220eefd8f7SAndreas Gohr     * @return int
2230eefd8f7SAndreas Gohr     */
2240eefd8f7SAndreas Gohr    public function getMaxBookmarks(): int
2250eefd8f7SAndreas Gohr    {
2260eefd8f7SAndreas Gohr        return $this->maxBookmarks;
2270eefd8f7SAndreas Gohr    }
2280eefd8f7SAndreas Gohr
2290eefd8f7SAndreas Gohr    /**
2300eefd8f7SAndreas Gohr     * Check whether numbered headers are to be used
2310eefd8f7SAndreas Gohr     *
2320eefd8f7SAndreas Gohr     * @return bool
2330eefd8f7SAndreas Gohr     */
2340eefd8f7SAndreas Gohr    public function useNumberedHeaders(): bool
2350eefd8f7SAndreas Gohr    {
2360eefd8f7SAndreas Gohr        return $this->numberedHeaders;
2370eefd8f7SAndreas Gohr    }
2380eefd8f7SAndreas Gohr
2390eefd8f7SAndreas Gohr    /**
240293d84e6SAndreas Gohr     * Get the QR code scale
241293d84e6SAndreas Gohr     *
242293d84e6SAndreas Gohr     * @return float
243293d84e6SAndreas Gohr     */
244293d84e6SAndreas Gohr    public function getQRScale(): float
245293d84e6SAndreas Gohr    {
246293d84e6SAndreas Gohr        return $this->qrCodeScale;
247293d84e6SAndreas Gohr    }
248293d84e6SAndreas Gohr
249293d84e6SAndreas Gohr    /**
25070028127SAndreas Gohr     * Get desired PDF delivery target (inline or file download)
25170028127SAndreas Gohr     *
25270028127SAndreas Gohr     * @return string
25370028127SAndreas Gohr     */
25470028127SAndreas Gohr    public function getOutputTarget(): string
25570028127SAndreas Gohr    {
25670028127SAndreas Gohr        return $this->outputTarget;
25770028127SAndreas Gohr    }
25870028127SAndreas Gohr
25970028127SAndreas Gohr    /**
260293d84e6SAndreas Gohr     * Get a unique cache key for the current configuration
261293d84e6SAndreas Gohr     *
262293d84e6SAndreas Gohr     * @return string
263293d84e6SAndreas Gohr     */
264293d84e6SAndreas Gohr    public function getCacheKey(): string
265293d84e6SAndreas Gohr    {
2665340eaffSAndreas Gohr        return implode(',', [
267293d84e6SAndreas Gohr            $this->template,
268293d84e6SAndreas Gohr            $this->pagesize,
269293d84e6SAndreas Gohr            $this->isLandscape ? 'L' : 'P',
270293d84e6SAndreas Gohr            $this->fontSize,
271293d84e6SAndreas Gohr            $this->isDoublesided ? 'D' : 'S',
272293d84e6SAndreas Gohr            $this->hasToC ? 'T' : 'N',
2730eefd8f7SAndreas Gohr            $this->maxBookmarks,
2740eefd8f7SAndreas Gohr            $this->numberedHeaders ? 'H' : 'N',
275293d84e6SAndreas Gohr            implode('-', $this->tocLevels)
276293d84e6SAndreas Gohr        ]);
277293d84e6SAndreas Gohr    }
278081fc334SAndreas Gohr
279081fc334SAndreas Gohr    /**
280c5c184fdSAndreas Gohr     * Parses the ToC levels configuration into an array
281c5c184fdSAndreas Gohr     *
282c5c184fdSAndreas Gohr     * @param string $toclevels eg. "2-4"
283c5c184fdSAndreas Gohr     * @return array
284c5c184fdSAndreas Gohr     */
285c5c184fdSAndreas Gohr    protected function parseTocLevels(string $toclevels): array
286c5c184fdSAndreas Gohr    {
287c5c184fdSAndreas Gohr        $levels = [];
288c5c184fdSAndreas Gohr        [$top, $max] = sexplode('-', $toclevels, 2);
289c5c184fdSAndreas Gohr        $top = max(1, min(5, (int)$top));
290c5c184fdSAndreas Gohr        $max = max(1, min(5, (int)$max));
291c5c184fdSAndreas Gohr
292c5c184fdSAndreas Gohr        if ($max < $top) {
293c5c184fdSAndreas Gohr            $max = $top;
294c5c184fdSAndreas Gohr        }
295c5c184fdSAndreas Gohr
296c5c184fdSAndreas Gohr        for ($level = $top; $level <= $max; $level++) {
297c5c184fdSAndreas Gohr            $levels["H$level"] = $level - 1;
298c5c184fdSAndreas Gohr        }
299c5c184fdSAndreas Gohr
300c5c184fdSAndreas Gohr        return $levels;
301c5c184fdSAndreas Gohr    }
302c5c184fdSAndreas Gohr
303c5c184fdSAndreas Gohr
304c5c184fdSAndreas Gohr    /**
305c5c184fdSAndreas Gohr     * Return the paper format
306c5c184fdSAndreas Gohr     *
307c5c184fdSAndreas Gohr     * @return string
308c5c184fdSAndreas Gohr     */
309c5c184fdSAndreas Gohr    public function getFormat()
310c5c184fdSAndreas Gohr    {
311c5c184fdSAndreas Gohr        $format = $this->pagesize;
312c5c184fdSAndreas Gohr        if ($this->isLandscape) {
313c5c184fdSAndreas Gohr            $format .= '-L';
314c5c184fdSAndreas Gohr        }
315c5c184fdSAndreas Gohr        return $format;
316c5c184fdSAndreas Gohr    }
317c5c184fdSAndreas Gohr
318c5c184fdSAndreas Gohr    /**
319293d84e6SAndreas Gohr     * Return the watermark text if any
320c5c184fdSAndreas Gohr     *
321c5c184fdSAndreas Gohr     * @return string
322c5c184fdSAndreas Gohr     */
323293d84e6SAndreas Gohr    public function getWatermarkText(): string
324c5c184fdSAndreas Gohr    {
325c5c184fdSAndreas Gohr        return $this->watermark;
326c5c184fdSAndreas Gohr    }
327c5c184fdSAndreas Gohr
328c5c184fdSAndreas Gohr    /**
329c5c184fdSAndreas Gohr     * Get all configuration for mpdf as array
330c5c184fdSAndreas Gohr     *
3317542e5b4SAndreas Gohr     * Note: mode and writing direction are set in DokuPDF based on the language
332c5c184fdSAndreas Gohr     *
333c5c184fdSAndreas Gohr     * @link https://mpdf.github.io/reference/mpdf-variables/overview.html
334c5c184fdSAndreas Gohr     * @return array
335c5c184fdSAndreas Gohr     */
336c5c184fdSAndreas Gohr    public function getMPdfConfig(): array
337c5c184fdSAndreas Gohr    {
338c5c184fdSAndreas Gohr        return [
339c5c184fdSAndreas Gohr            'format' => $this->getFormat(),
340c5c184fdSAndreas Gohr            'default_font_size' => $this->fontSize,
341c5c184fdSAndreas Gohr            'tempDir' => $this->tempDir,
342c5c184fdSAndreas Gohr            'mirrorMargins' => $this->isDoublesided,
343c5c184fdSAndreas Gohr            'h2toc' => $this->hasToC ? $this->tocLevels : [],
344c5c184fdSAndreas Gohr            'showWatermarkText' => $this->watermark !== '',
345c5c184fdSAndreas Gohr
346c5c184fdSAndreas Gohr            'setAutoTopMargin' => 'stretch',
347c5c184fdSAndreas Gohr            'setAutoBottomMargin' => 'stretch',
348c5c184fdSAndreas Gohr            'autoScriptToLang' => true,
349c5c184fdSAndreas Gohr            'baseScript' => 1,
350c5c184fdSAndreas Gohr            'autoVietnamese' => true,
351c5c184fdSAndreas Gohr            'autoArabic' => true,
352c5c184fdSAndreas Gohr            'autoLangToFont' => true,
353c5c184fdSAndreas Gohr            'ignore_invalid_utf8' => true,
354c5c184fdSAndreas Gohr            'tabSpaces' => 4,
355c5c184fdSAndreas Gohr        ];
356c5c184fdSAndreas Gohr    }
357decfd8d6SAndreas Gohr
358decfd8d6SAndreas Gohr    /**
359decfd8d6SAndreas Gohr     * Get the requested book title override if provided.
360decfd8d6SAndreas Gohr     *
361decfd8d6SAndreas Gohr     * @return string|null
362decfd8d6SAndreas Gohr     */
363decfd8d6SAndreas Gohr    public function getBookTitle(): ?string
364decfd8d6SAndreas Gohr    {
365decfd8d6SAndreas Gohr        return $this->bookTitle;
366decfd8d6SAndreas Gohr    }
367decfd8d6SAndreas Gohr
368decfd8d6SAndreas Gohr    /**
369decfd8d6SAndreas Gohr     * Get the namespace to export for namespace/book selections.
370decfd8d6SAndreas Gohr     *
371decfd8d6SAndreas Gohr     * @return string
372decfd8d6SAndreas Gohr     */
373decfd8d6SAndreas Gohr    public function getBookNamespace(): string
374decfd8d6SAndreas Gohr    {
375decfd8d6SAndreas Gohr        return $this->bookNamespace;
376decfd8d6SAndreas Gohr    }
377decfd8d6SAndreas Gohr
378decfd8d6SAndreas Gohr    /**
379decfd8d6SAndreas Gohr     * Get the page sort order selected for namespace exports.
380decfd8d6SAndreas Gohr     *
381decfd8d6SAndreas Gohr     * @return string
382decfd8d6SAndreas Gohr     */
383decfd8d6SAndreas Gohr    public function getBookSortOrder(): string
384decfd8d6SAndreas Gohr    {
385decfd8d6SAndreas Gohr        return $this->bookSortOrder;
386decfd8d6SAndreas Gohr    }
387decfd8d6SAndreas Gohr
388decfd8d6SAndreas Gohr    /**
389decfd8d6SAndreas Gohr     * Get the maximum namespace depth to traverse for namespace exports.
390decfd8d6SAndreas Gohr     *
391decfd8d6SAndreas Gohr     * @return int
392decfd8d6SAndreas Gohr     */
393decfd8d6SAndreas Gohr    public function getBookNamespaceDepth(): int
394decfd8d6SAndreas Gohr    {
395decfd8d6SAndreas Gohr        return $this->bookNamespaceDepth;
396decfd8d6SAndreas Gohr    }
397decfd8d6SAndreas Gohr
398decfd8d6SAndreas Gohr    /**
399decfd8d6SAndreas Gohr     * Get the list of explicitly excluded page IDs.
400decfd8d6SAndreas Gohr     *
401decfd8d6SAndreas Gohr     * @return string[]
402decfd8d6SAndreas Gohr     */
403decfd8d6SAndreas Gohr    public function getBookExcludedPages(): array
404decfd8d6SAndreas Gohr    {
405decfd8d6SAndreas Gohr        return $this->bookExcludePages;
406decfd8d6SAndreas Gohr    }
407decfd8d6SAndreas Gohr
408decfd8d6SAndreas Gohr    /**
409decfd8d6SAndreas Gohr     * Get the list of excluded namespaces.
410decfd8d6SAndreas Gohr     *
411decfd8d6SAndreas Gohr     * @return string[]
412decfd8d6SAndreas Gohr     */
413decfd8d6SAndreas Gohr    public function getBookExcludedNamespaces(): array
414decfd8d6SAndreas Gohr    {
415decfd8d6SAndreas Gohr        return $this->bookExcludeNamespaces;
416decfd8d6SAndreas Gohr    }
417decfd8d6SAndreas Gohr
418decfd8d6SAndreas Gohr    /**
419decfd8d6SAndreas Gohr     * Get the raw JSON payload representing a live book selection.
420decfd8d6SAndreas Gohr     *
421decfd8d6SAndreas Gohr     * @return string|null
422decfd8d6SAndreas Gohr     */
423decfd8d6SAndreas Gohr    public function getLiveSelection(): ?string
424decfd8d6SAndreas Gohr    {
425decfd8d6SAndreas Gohr        return $this->liveSelection;
426decfd8d6SAndreas Gohr    }
427decfd8d6SAndreas Gohr
428decfd8d6SAndreas Gohr    /**
429decfd8d6SAndreas Gohr     * Check whether a live selection payload was supplied.
430decfd8d6SAndreas Gohr     *
431decfd8d6SAndreas Gohr     * @return bool
432decfd8d6SAndreas Gohr     */
433decfd8d6SAndreas Gohr    public function hasLiveSelection(): bool
434decfd8d6SAndreas Gohr    {
435decfd8d6SAndreas Gohr        return $this->liveSelection !== null;
436decfd8d6SAndreas Gohr    }
437decfd8d6SAndreas Gohr
438decfd8d6SAndreas Gohr    /**
439decfd8d6SAndreas Gohr     * Get the identifier of a saved book selection.
440decfd8d6SAndreas Gohr     *
441decfd8d6SAndreas Gohr     * @return string|null
442decfd8d6SAndreas Gohr     */
443decfd8d6SAndreas Gohr    public function getSavedSelection(): ?string
444decfd8d6SAndreas Gohr    {
445decfd8d6SAndreas Gohr        return $this->savedSelection;
446decfd8d6SAndreas Gohr    }
447decfd8d6SAndreas Gohr
448decfd8d6SAndreas Gohr    /**
449decfd8d6SAndreas Gohr     * Check whether a saved selection identifier was supplied.
450decfd8d6SAndreas Gohr     *
451decfd8d6SAndreas Gohr     * @return bool
452decfd8d6SAndreas Gohr     */
453decfd8d6SAndreas Gohr    public function hasSavedSelection(): bool
454decfd8d6SAndreas Gohr    {
455decfd8d6SAndreas Gohr        return $this->savedSelection !== null;
456decfd8d6SAndreas Gohr    }
457b23d7b8aSAndreas Gohr
458b23d7b8aSAndreas Gohr    /**
459b23d7b8aSAndreas Gohr     * Get the requested page ID for single page exports.
460b23d7b8aSAndreas Gohr     *
461b23d7b8aSAndreas Gohr     * @return string
462b23d7b8aSAndreas Gohr     */
463b23d7b8aSAndreas Gohr    public function getExportId(): string
464b23d7b8aSAndreas Gohr    {
465b23d7b8aSAndreas Gohr        return $this->exportId;
466b23d7b8aSAndreas Gohr    }
467c5c184fdSAndreas Gohr}
468