xref: /plugin/dw2pdf/src/AbstractCollector.php (revision 40a07da2a0a1fe205d2fb62c8cd8b8968e580efa)
12bef96e6SAndreas Gohr<?php
22bef96e6SAndreas Gohr
32bef96e6SAndreas Gohrnamespace dokuwiki\plugin\dw2pdf\src;
42bef96e6SAndreas Gohr
52bef96e6SAndreas Gohrabstract class AbstractCollector
62bef96e6SAndreas Gohr{
72bef96e6SAndreas Gohr    /** @var string */
82bef96e6SAndreas Gohr    protected string $title = '';
92bef96e6SAndreas Gohr
102bef96e6SAndreas Gohr    /** @var string[] */
112bef96e6SAndreas Gohr    protected array $pages = [];
122bef96e6SAndreas Gohr
13*40a07da2SAndreas Gohr    /** @var string[] Pages removed from the selection because of missing read access */
14*40a07da2SAndreas Gohr    protected array $skipped = [];
15*40a07da2SAndreas Gohr
162bef96e6SAndreas Gohr    /** @var int|null */
172bef96e6SAndreas Gohr    protected ?int $rev;
182bef96e6SAndreas Gohr    /**
192bef96e6SAndreas Gohr     * @var int|null
202bef96e6SAndreas Gohr     */
212bef96e6SAndreas Gohr    protected ?int $at;
22decfd8d6SAndreas Gohr    protected Config $config;
232bef96e6SAndreas Gohr
242bef96e6SAndreas Gohr    /**
25*40a07da2SAndreas Gohr     * Collect the pages for this export and partition them by read access
26*40a07da2SAndreas Gohr     *
27*40a07da2SAndreas Gohr     * Pages the current user may not read are skipped but remembered, so callers can tell an
28*40a07da2SAndreas Gohr     * empty selection apart from one where every selected page was forbidden.
29*40a07da2SAndreas Gohr     *
30*40a07da2SAndreas Gohr     * @param Config $config Combined plugin and request configuration
31*40a07da2SAndreas Gohr     * @param int|null $rev Specific revision to export, if any
32*40a07da2SAndreas Gohr     * @param int|null $at Specific dateat timestamp to export, if any
332bef96e6SAndreas Gohr     */
34decfd8d6SAndreas Gohr    public function __construct(Config $config, ?int $rev = null, ?int $at = null)
352bef96e6SAndreas Gohr    {
36decfd8d6SAndreas Gohr        $this->config = $config;
372bef96e6SAndreas Gohr        $this->rev = $rev;
382bef96e6SAndreas Gohr        $this->at = $at;
39decfd8d6SAndreas Gohr        $this->title = $config->getBookTitle() ?? '';
40293d84e6SAndreas Gohr
41*40a07da2SAndreas Gohr        // clean and partition collected pages into readable and forbidden ones in a single pass
42*40a07da2SAndreas Gohr        foreach ($this->collect() as $page) {
43*40a07da2SAndreas Gohr            $page = cleanID($page);
44*40a07da2SAndreas Gohr            if (auth_quickaclcheck($page) >= AUTH_READ) {
45*40a07da2SAndreas Gohr                $this->pages[] = $page;
46*40a07da2SAndreas Gohr            } else {
47*40a07da2SAndreas Gohr                $this->skipped[] = $page;
48*40a07da2SAndreas Gohr            }
49*40a07da2SAndreas Gohr        }
502bef96e6SAndreas Gohr    }
512bef96e6SAndreas Gohr
522bef96e6SAndreas Gohr    /**
53decfd8d6SAndreas Gohr     * Get the combined configuration/request context for this export.
54decfd8d6SAndreas Gohr     *
55decfd8d6SAndreas Gohr     * @return Config
56decfd8d6SAndreas Gohr     */
57decfd8d6SAndreas Gohr    protected function getConfig(): Config
58decfd8d6SAndreas Gohr    {
59decfd8d6SAndreas Gohr        return $this->config;
60decfd8d6SAndreas Gohr    }
61decfd8d6SAndreas Gohr
62decfd8d6SAndreas Gohr    /**
632bef96e6SAndreas Gohr     * Collect the pages to be included in the PDF
642bef96e6SAndreas Gohr     *
6532d393aeSAndreas Gohr     * The collected pages will be cleaned and checked for read access automatically.
6632d393aeSAndreas Gohr     *
6732d393aeSAndreas Gohr     * This method should check for page existence, though (might depend on $rev/$at).
6832d393aeSAndreas Gohr     *
692bef96e6SAndreas Gohr     * @return string[] The list of page ids
702bef96e6SAndreas Gohr     */
712bef96e6SAndreas Gohr    abstract protected function collect(): array;
722bef96e6SAndreas Gohr
732bef96e6SAndreas Gohr    /**
742bef96e6SAndreas Gohr     * Get the title to be used for the PDF
752bef96e6SAndreas Gohr     *
762bef96e6SAndreas Gohr     * @return string
772bef96e6SAndreas Gohr     */
782bef96e6SAndreas Gohr    public function getTitle(): string
792bef96e6SAndreas Gohr    {
802bef96e6SAndreas Gohr        if (!$this->title && $this->pages) {
812bef96e6SAndreas Gohr            $this->title = p_get_first_heading($this->pages[0]) ?: noNS($this->pages[0]);
822bef96e6SAndreas Gohr        }
832bef96e6SAndreas Gohr
842bef96e6SAndreas Gohr        if (!$this->title) {
852bef96e6SAndreas Gohr            $this->title = 'PDF Export';
862bef96e6SAndreas Gohr        }
872bef96e6SAndreas Gohr
882bef96e6SAndreas Gohr        return $this->title;
892bef96e6SAndreas Gohr    }
902bef96e6SAndreas Gohr
912bef96e6SAndreas Gohr    /**
92293d84e6SAndreas Gohr     * Get the language to be used for the PDF
93293d84e6SAndreas Gohr     *
94293d84e6SAndreas Gohr     * Use the language of the first page if possible, otherwise fall back to the default language
95293d84e6SAndreas Gohr     *
96293d84e6SAndreas Gohr     * @return string
97293d84e6SAndreas Gohr     */
98293d84e6SAndreas Gohr    public function getLanguage()
99293d84e6SAndreas Gohr    {
100293d84e6SAndreas Gohr        global $conf;
101293d84e6SAndreas Gohr
102293d84e6SAndreas Gohr        $lang = $conf['lang'];
103293d84e6SAndreas Gohr        if ($this->pages == []) return $lang;
104293d84e6SAndreas Gohr
105293d84e6SAndreas Gohr
106293d84e6SAndreas Gohr        /** @var helper_plugin_translation $trans */
107293d84e6SAndreas Gohr        $trans = plugin_load('helper', 'translation');
108293d84e6SAndreas Gohr        if (!$trans) return $lang;
109293d84e6SAndreas Gohr        $tr = $trans->getLangPart($this->pages[0]);
110293d84e6SAndreas Gohr        if ($tr) return $tr;
111293d84e6SAndreas Gohr
112293d84e6SAndreas Gohr        return $lang;
113293d84e6SAndreas Gohr    }
114293d84e6SAndreas Gohr
115293d84e6SAndreas Gohr    /**
116293d84e6SAndreas Gohr     * Get the set revision if any
117293d84e6SAndreas Gohr     *
118293d84e6SAndreas Gohr     * @return int|null
119293d84e6SAndreas Gohr     */
120293d84e6SAndreas Gohr    public function getRev(): ?int
121293d84e6SAndreas Gohr    {
122293d84e6SAndreas Gohr        return $this->rev;
123293d84e6SAndreas Gohr    }
124293d84e6SAndreas Gohr
125293d84e6SAndreas Gohr    /**
126293d84e6SAndreas Gohr     * Get the set dateat timestamp if any
127293d84e6SAndreas Gohr     *
128293d84e6SAndreas Gohr     * @return int|null
129293d84e6SAndreas Gohr     */
130293d84e6SAndreas Gohr    public function getAt(): ?int
131293d84e6SAndreas Gohr    {
132293d84e6SAndreas Gohr        return $this->at;
133293d84e6SAndreas Gohr    }
134293d84e6SAndreas Gohr
135293d84e6SAndreas Gohr    /**
1362bef96e6SAndreas Gohr     * Get the list of page ids to include in the PDF
1372bef96e6SAndreas Gohr     *
1382bef96e6SAndreas Gohr     * @return string[]
1392bef96e6SAndreas Gohr     */
1402bef96e6SAndreas Gohr    public function getPages(): array
1412bef96e6SAndreas Gohr    {
1422bef96e6SAndreas Gohr        return $this->pages;
1432bef96e6SAndreas Gohr    }
144293d84e6SAndreas Gohr
145293d84e6SAndreas Gohr    /**
146*40a07da2SAndreas Gohr     * Get the pages that were removed from the selection because of missing read access
147*40a07da2SAndreas Gohr     *
148*40a07da2SAndreas Gohr     * @return string[]
149*40a07da2SAndreas Gohr     */
150*40a07da2SAndreas Gohr    public function getSkippedPages(): array
151*40a07da2SAndreas Gohr    {
152*40a07da2SAndreas Gohr        return $this->skipped;
153*40a07da2SAndreas Gohr    }
154*40a07da2SAndreas Gohr
155*40a07da2SAndreas Gohr    /**
156293d84e6SAndreas Gohr     * Get the list of file paths to include in the PDF
157293d84e6SAndreas Gohr     *
158293d84e6SAndreas Gohr     * Handles $rev if set
159293d84e6SAndreas Gohr     *
160293d84e6SAndreas Gohr     * @return string[]
161293d84e6SAndreas Gohr     * @todo no handling of $at yet
162293d84e6SAndreas Gohr     */
163293d84e6SAndreas Gohr    public function getFiles(): array
164293d84e6SAndreas Gohr    {
165293d84e6SAndreas Gohr        return array_map(fn($id) => wikiFN($id, $this->rev), $this->pages);
166293d84e6SAndreas Gohr    }
1672bef96e6SAndreas Gohr}
168