xref: /plugin/dw2pdf/src/AbstractCollector.php (revision 3ddddb3b2485c18a6aa6809af789c7abb6977134)
1<?php
2
3namespace dokuwiki\plugin\dw2pdf\src;
4
5abstract class AbstractCollector
6{
7    /** @var string */
8    protected string $title = '';
9
10    /** @var string[] */
11    protected array $pages = [];
12
13    /** @var string[] Pages removed from the selection because of missing read access */
14    protected array $skipped = [];
15
16    /** @var int|null */
17    protected ?int $rev;
18    /**
19     * @var int|null
20     */
21    protected ?int $at;
22    protected Config $config;
23
24    /**
25     * Collect the pages for this export and partition them by read access
26     *
27     * Pages the current user may not read are skipped but remembered, so callers can tell an
28     * empty selection apart from one where every selected page was forbidden.
29     *
30     * @param Config $config Combined plugin and request configuration
31     * @param int|null $rev Specific revision to export, if any
32     * @param int|null $at Specific dateat timestamp to export, if any
33     */
34    public function __construct(Config $config, ?int $rev = null, ?int $at = null)
35    {
36        $this->config = $config;
37        $this->rev = $rev;
38        $this->at = $at;
39        $this->title = $config->getBookTitle() ?? '';
40
41        // clean and partition collected pages into readable and forbidden ones in a single pass
42        foreach ($this->collect() as $page) {
43            $page = cleanID($page);
44            if (auth_quickaclcheck($page) >= AUTH_READ) {
45                $this->pages[] = $page;
46            } else {
47                $this->skipped[] = $page;
48            }
49        }
50    }
51
52    /**
53     * Get the combined configuration/request context for this export.
54     *
55     * @return Config
56     */
57    protected function getConfig(): Config
58    {
59        return $this->config;
60    }
61
62    /**
63     * Collect the pages to be included in the PDF
64     *
65     * The collected pages will be cleaned and checked for read access automatically.
66     *
67     * This method should check for page existence, though (might depend on $rev/$at).
68     *
69     * @return string[] The list of page ids
70     */
71    abstract protected function collect(): array;
72
73    /**
74     * Get the title to be used for the PDF
75     *
76     * @return string
77     */
78    public function getTitle(): string
79    {
80        if (!$this->title && $this->pages) {
81            $this->title = p_get_first_heading($this->pages[0]) ?: noNS($this->pages[0]);
82        }
83
84        if (!$this->title) {
85            $this->title = 'PDF Export';
86        }
87
88        return $this->title;
89    }
90
91    /**
92     * Get the language to be used for the PDF
93     *
94     * Use the language of the first page if possible, otherwise fall back to the default language
95     *
96     * @return string
97     */
98    public function getLanguage()
99    {
100        global $conf;
101
102        $lang = $conf['lang'];
103        if ($this->pages == []) return $lang;
104
105
106        /** @var helper_plugin_translation $trans */
107        $trans = plugin_load('helper', 'translation');
108        if (!$trans) return $lang;
109        $tr = $trans->getLangPart($this->pages[0]);
110        if ($tr) return $tr;
111
112        return $lang;
113    }
114
115    /**
116     * Get the set revision if any
117     *
118     * @return int|null
119     */
120    public function getRev(): ?int
121    {
122        return $this->rev;
123    }
124
125    /**
126     * Get the set dateat timestamp if any
127     *
128     * @return int|null
129     */
130    public function getAt(): ?int
131    {
132        return $this->at;
133    }
134
135    /**
136     * Get the list of page ids to include in the PDF
137     *
138     * @return string[]
139     */
140    public function getPages(): array
141    {
142        return $this->pages;
143    }
144
145    /**
146     * Get the pages that were removed from the selection because of missing read access
147     *
148     * @return string[]
149     */
150    public function getSkippedPages(): array
151    {
152        return $this->skipped;
153    }
154
155    /**
156     * Get the list of file paths to include in the PDF
157     *
158     * Handles $rev if set
159     *
160     * @return string[]
161     * @todo no handling of $at yet
162     */
163    public function getFiles(): array
164    {
165        return array_map(fn($id) => wikiFN($id, $this->rev), $this->pages);
166    }
167}
168