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