1*fe9d054bSAndreas Gohr<?php 2*fe9d054bSAndreas Gohr 3*fe9d054bSAndreas Gohrnamespace dokuwiki\Feed; 4*fe9d054bSAndreas Gohr 5*fe9d054bSAndreas Gohruse dokuwiki\Extension\AuthPlugin; 6*fe9d054bSAndreas Gohruse RuntimeException; 7*fe9d054bSAndreas Gohr 8*fe9d054bSAndreas Gohr/** 9*fe9d054bSAndreas Gohr * Accept more or less arbitrary data to represent data to later construct a feed item from. 10*fe9d054bSAndreas Gohr * Provide lazy loading accessors to all the data we need for feed generation. 11*fe9d054bSAndreas Gohr */ 12*fe9d054bSAndreas Gohrabstract class FeedItemProcessor 13*fe9d054bSAndreas Gohr{ 14*fe9d054bSAndreas Gohr /** @var string This page's ID */ 15*fe9d054bSAndreas Gohr protected $id; 16*fe9d054bSAndreas Gohr 17*fe9d054bSAndreas Gohr /** @var array bag of holding */ 18*fe9d054bSAndreas Gohr protected $data; 19*fe9d054bSAndreas Gohr 20*fe9d054bSAndreas Gohr 21*fe9d054bSAndreas Gohr /** 22*fe9d054bSAndreas Gohr * Constructor 23*fe9d054bSAndreas Gohr * 24*fe9d054bSAndreas Gohr * @param array $data Needs to have at least an 'id' key 25*fe9d054bSAndreas Gohr */ 26*fe9d054bSAndreas Gohr public function __construct($data) 27*fe9d054bSAndreas Gohr { 28*fe9d054bSAndreas Gohr if (!isset($data['id'])) throw new RuntimeException('Missing ID'); 29*fe9d054bSAndreas Gohr $this->id = cleanID($data['id']); 30*fe9d054bSAndreas Gohr $this->data = $data; 31*fe9d054bSAndreas Gohr } 32*fe9d054bSAndreas Gohr 33*fe9d054bSAndreas Gohr /** 34*fe9d054bSAndreas Gohr * Get the page ID 35*fe9d054bSAndreas Gohr * 36*fe9d054bSAndreas Gohr * @return string 37*fe9d054bSAndreas Gohr */ 38*fe9d054bSAndreas Gohr public function getId() 39*fe9d054bSAndreas Gohr { 40*fe9d054bSAndreas Gohr return $this->id; 41*fe9d054bSAndreas Gohr } 42*fe9d054bSAndreas Gohr 43*fe9d054bSAndreas Gohr /** 44*fe9d054bSAndreas Gohr * Get the revision timestamp of this page 45*fe9d054bSAndreas Gohr * 46*fe9d054bSAndreas Gohr * If the input gave us a revision, date or lastmodified already, we trust that it is correct. 47*fe9d054bSAndreas Gohr * 48*fe9d054bSAndreas Gohr * Note: we only handle most current revisions in feeds, so the revision is usually just the 49*fe9d054bSAndreas Gohr * lastmodifed timestamp of the page file. However, if the item does not exist, we need to 50*fe9d054bSAndreas Gohr * determine the revision from the changelog. 51*fe9d054bSAndreas Gohr * 52*fe9d054bSAndreas Gohr * @return int 53*fe9d054bSAndreas Gohr */ 54*fe9d054bSAndreas Gohr public function getRev() 55*fe9d054bSAndreas Gohr { 56*fe9d054bSAndreas Gohr if ($this->data['rev'] ?? 0) return $this->data['rev']; 57*fe9d054bSAndreas Gohr 58*fe9d054bSAndreas Gohr if (isset($this->data['date'])) { 59*fe9d054bSAndreas Gohr $this->data['rev'] = (int)$this->data['date']; 60*fe9d054bSAndreas Gohr } 61*fe9d054bSAndreas Gohr 62*fe9d054bSAndreas Gohr if (isset($this->data['lastmodified'])) { 63*fe9d054bSAndreas Gohr $this->data['rev'] = (int)$this->data['lastmodified']; 64*fe9d054bSAndreas Gohr } 65*fe9d054bSAndreas Gohr 66*fe9d054bSAndreas Gohr return $this->data['rev'] ?? 0; 67*fe9d054bSAndreas Gohr } 68*fe9d054bSAndreas Gohr 69*fe9d054bSAndreas Gohr /** 70*fe9d054bSAndreas Gohr * Construct the URL for the feed item based on the link_to option 71*fe9d054bSAndreas Gohr * 72*fe9d054bSAndreas Gohr * @param string $linkto The link_to option 73*fe9d054bSAndreas Gohr * @return string URL 74*fe9d054bSAndreas Gohr */ 75*fe9d054bSAndreas Gohr abstract public function getURL($linkto); 76*fe9d054bSAndreas Gohr 77*fe9d054bSAndreas Gohr /** 78*fe9d054bSAndreas Gohr * @return string 79*fe9d054bSAndreas Gohr */ 80*fe9d054bSAndreas Gohr public function getTitle() 81*fe9d054bSAndreas Gohr { 82*fe9d054bSAndreas Gohr return $this->data['title'] ?? noNS($this->getId()); 83*fe9d054bSAndreas Gohr } 84*fe9d054bSAndreas Gohr 85*fe9d054bSAndreas Gohr /** 86*fe9d054bSAndreas Gohr * Construct the body of the feed item based on the item_content option 87*fe9d054bSAndreas Gohr * 88*fe9d054bSAndreas Gohr * @param string $content The item_content option 89*fe9d054bSAndreas Gohr * @return string 90*fe9d054bSAndreas Gohr */ 91*fe9d054bSAndreas Gohr abstract public function getBody($content); 92*fe9d054bSAndreas Gohr 93*fe9d054bSAndreas Gohr /** 94*fe9d054bSAndreas Gohr * Get the change summary for this item if any 95*fe9d054bSAndreas Gohr * 96*fe9d054bSAndreas Gohr * @return string 97*fe9d054bSAndreas Gohr */ 98*fe9d054bSAndreas Gohr public function getSummary() 99*fe9d054bSAndreas Gohr { 100*fe9d054bSAndreas Gohr return (string)($this->data['sum'] ?? ''); 101*fe9d054bSAndreas Gohr } 102*fe9d054bSAndreas Gohr 103*fe9d054bSAndreas Gohr /** 104*fe9d054bSAndreas Gohr * Get the author info for this item 105*fe9d054bSAndreas Gohr * 106*fe9d054bSAndreas Gohr * @return string[] [email, author] 107*fe9d054bSAndreas Gohr */ 108*fe9d054bSAndreas Gohr public function getAuthor() 109*fe9d054bSAndreas Gohr { 110*fe9d054bSAndreas Gohr global $conf; 111*fe9d054bSAndreas Gohr global $auth; 112*fe9d054bSAndreas Gohr 113*fe9d054bSAndreas Gohr $user = $this->data['user'] ?? ''; 114*fe9d054bSAndreas Gohr $author = 'Anonymous'; 115*fe9d054bSAndreas Gohr $email = 'anonymous@undisclosed.example.com'; 116*fe9d054bSAndreas Gohr 117*fe9d054bSAndreas Gohr if (!$user) return [$email, $author]; 118*fe9d054bSAndreas Gohr $author = $user; 119*fe9d054bSAndreas Gohr $email = $user . '@undisclosed.example.com'; 120*fe9d054bSAndreas Gohr 121*fe9d054bSAndreas Gohr if ($conf['useacl'] && $auth instanceof AuthPlugin) { 122*fe9d054bSAndreas Gohr $userInfo = $auth->getUserData($user); 123*fe9d054bSAndreas Gohr if ($userInfo) { 124*fe9d054bSAndreas Gohr switch ($conf['showuseras']) { 125*fe9d054bSAndreas Gohr case 'username': 126*fe9d054bSAndreas Gohr case 'username_link': 127*fe9d054bSAndreas Gohr $author = $userInfo['name']; 128*fe9d054bSAndreas Gohr break; 129*fe9d054bSAndreas Gohr } 130*fe9d054bSAndreas Gohr } 131*fe9d054bSAndreas Gohr } 132*fe9d054bSAndreas Gohr return [$email, $author]; 133*fe9d054bSAndreas Gohr } 134*fe9d054bSAndreas Gohr 135*fe9d054bSAndreas Gohr /** 136*fe9d054bSAndreas Gohr * Get the categories for this item 137*fe9d054bSAndreas Gohr * 138*fe9d054bSAndreas Gohr * @return string[] 139*fe9d054bSAndreas Gohr */ 140*fe9d054bSAndreas Gohr abstract public function getCategory(); 141*fe9d054bSAndreas Gohr 142*fe9d054bSAndreas Gohr 143*fe9d054bSAndreas Gohr /** 144*fe9d054bSAndreas Gohr * Clean HTML for the use in feeds 145*fe9d054bSAndreas Gohr * 146*fe9d054bSAndreas Gohr * @param string $html 147*fe9d054bSAndreas Gohr * @return string 148*fe9d054bSAndreas Gohr */ 149*fe9d054bSAndreas Gohr protected function cleanHTML($html) 150*fe9d054bSAndreas Gohr { 151*fe9d054bSAndreas Gohr global $conf; 152*fe9d054bSAndreas Gohr 153*fe9d054bSAndreas Gohr // no TOC in feeds 154*fe9d054bSAndreas Gohr $html = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s', '', $html); 155*fe9d054bSAndreas Gohr 156*fe9d054bSAndreas Gohr // add alignment for images 157*fe9d054bSAndreas Gohr $html = preg_replace('/(<img .*?class="medialeft")/s', '\\1 align="left"', $html); 158*fe9d054bSAndreas Gohr $html = preg_replace('/(<img .*?class="mediaright")/s', '\\1 align="right"', $html); 159*fe9d054bSAndreas Gohr 160*fe9d054bSAndreas Gohr // make URLs work when canonical is not set, regexp instead of rerendering! 161*fe9d054bSAndreas Gohr if (!$conf['canonical']) { 162*fe9d054bSAndreas Gohr $base = preg_quote(DOKU_REL, '/'); 163*fe9d054bSAndreas Gohr $html = preg_replace( 164*fe9d054bSAndreas Gohr '/(<a href|<img src)="(' . $base . ')/s', 165*fe9d054bSAndreas Gohr '$1="' . DOKU_URL, 166*fe9d054bSAndreas Gohr $html 167*fe9d054bSAndreas Gohr ); 168*fe9d054bSAndreas Gohr } 169*fe9d054bSAndreas Gohr 170*fe9d054bSAndreas Gohr return $html; 171*fe9d054bSAndreas Gohr } 172*fe9d054bSAndreas Gohr} 173