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