1<?php 2 3// must be run within DokuWiki 4if(!defined('DOKU_INC')) die(); 5 6 7class syntax_plugin_ireadit_list extends DokuWiki_Syntax_Plugin { 8 9 function getType() { 10 return 'substition'; 11 } 12 13 function getSort() { 14 return 20; 15 } 16 17 function PType() { 18 return 'block'; 19 } 20 21 function connectTo($mode) { 22 $this->Lexer->addSpecialPattern('----+ *ireadit list *-+\n.*?----+', $mode,'plugin_ireadit_list'); 23 } 24 25 function handle($match, $state, $pos, Doku_Handler $handler){ 26 $lines = explode("\n", $match); 27 array_shift($lines); 28 array_pop($lines); 29 30 $statemap = [ 31 'read' => ['read'], 32 'outdated' => ['outdated'], 33 'unread' => ['unread'], 34 'not read' => ['outdated', 'unread'], 35 'all' => ['read', 'outdated', 'unread'], 36 ]; 37 38 $params = [ 39 'user' => '$USER$', 40 'state' => $statemap['all'], 41 'lastread' => '0', 42 'overview' => '0', 43 'namespace' => '', 44 'filter' => false 45 ]; 46 47 foreach ($lines as $line) { 48 $pair = explode(':', $line, 2); 49 if (count($pair) < 2) { 50 continue; 51 } 52 $key = trim($pair[0]); 53 $value = trim($pair[1]); 54 if ($key == 'state') { 55 $states = array_map('trim', explode(',', strtolower($value))); 56 $value = []; 57 foreach ($states as $state) { 58 if (isset($statemap[$state])) { 59 $value = array_merge($value, $statemap[$state]); 60 } else { 61 msg('ireadit plugin: unknown state "'.$state.'" should be: ' . 62 implode(', ', array_keys($statemap)), -1); 63 return false; 64 } 65 } 66 } elseif ($key == 'namespace') { 67 $value = trim(cleanID($value), ':'); 68 } elseif($key == 'filter') { 69 $value = trim($value, '/'); 70 if (preg_match('/' . $value . '/', null) === false) { 71 msg('ireadit plugin: invalid filter regex', -1); 72 return false; 73 } 74 } elseif ($key == 'lastread') { 75 if ($value != '0' && $value != '1') { 76 msg('ireadit plugin: lastread should be 0 or 1', -1); 77 return false; 78 } 79 } elseif ($key == 'overview') { 80 if ($value != '0' && $value != '1') { 81 msg('ireadit plugin: overview should be 0 or 1', -1); 82 return false; 83 } 84 } 85 $params[$key] = $value; 86 } 87 return $params; 88 } 89 90 /** 91 * Render xhtml output or metadata 92 * 93 * @param string $mode Renderer mode (supported modes: xhtml) 94 * @param Doku_Renderer $renderer The renderer 95 * @param array $data The data from the handler() function 96 * 97 * @return bool If rendering was successful. 98 */ 99 100 public function render($mode, Doku_Renderer $renderer, $data) 101 { 102 $method = 'render' . ucfirst($mode); 103 if (method_exists($this, $method)) { 104 call_user_func([$this, $method], $renderer, $data); 105 return true; 106 } 107 return false; 108 } 109 110 /** 111 * Render metadata 112 * 113 * @param Doku_Renderer $renderer The renderer 114 * @param array $params The data from the handler() function 115 */ 116 public function renderMetadata(Doku_Renderer $renderer, $params) 117 { 118 $renderer->meta['plugin']['ireadit_list'] = []; 119 120 if ($params['user'] == '$USER$') { 121 $renderer->meta['plugin']['ireadit_list']['dynamic_user'] = true; 122 } 123 } 124 125 public function renderXhtml(Doku_Renderer $renderer, $params) 126 { 127 global $INFO; 128 129 try { 130 /** @var \helper_plugin_ireadit_db $db_helper */ 131 $db_helper = plugin_load('helper', 'ireadit_db'); 132 $sqlite = $db_helper->getDB(); 133 } catch (Exception $e) { 134 msg($e->getMessage(), -1); 135 return false; 136 } 137 138 if ($params['user'] == '$USER$') { 139 $params['user'] = $INFO['client']; 140 } 141 142 $query_args = [$params['namespace'].'%']; 143 $filter_q = ''; 144 145 if ($params['filter']) { 146 $query_args[] = $params['filter']; 147 $filter_q .= " AND I.page REGEXP ?"; 148 } 149 150 if ($params['overview'] == '1') { 151 $q = "SELECT I.page, I.timestamp, 152 (SELECT T.rev FROM ireadit T 153 WHERE T.page=I.page AND T.timestamp IS NOT NULL 154 ORDER BY rev DESC LIMIT 1) lastread 155 FROM ireadit I INNER JOIN meta M ON I.page = M.page AND I.rev = M.last_change_date 156 WHERE I.page LIKE ? ESCAPE '_' 157 $filter_q"; 158 $res = $sqlite->query($q, $query_args); 159 } else { 160 array_unshift($query_args, $params['user'], $params['user']); 161 $q = "SELECT I.page, I.timestamp, 162 (SELECT T.rev FROM ireadit T 163 WHERE T.page=I.page AND T.user=? AND T.timestamp IS NOT NULL 164 ORDER BY rev DESC LIMIT 1) lastread 165 FROM ireadit I INNER JOIN meta M ON I.page = M.page AND I.rev = M.last_change_date 166 WHERE I.user=? 167 AND I.page LIKE ? ESCAPE '_' 168 $filter_q"; 169 $res = $sqlite->query($q, $query_args); 170 } 171 172 // Output List 173 $renderer->doc .= '<ul>'; 174 while ($row = $sqlite->res_fetch_assoc($res)) { 175 $page = $row['page']; 176 $timestamp = $row['timestamp']; 177 $lastread = $row['lastread']; 178 179 if (!$timestamp && $lastread) { 180 $state = 'outdated'; 181 } elseif (!$timestamp && !$lastread) { 182 $state = 'unread'; 183 } else { 184 $state = 'read'; 185 } 186 187 if (!in_array($state, $params['state'])) { 188 continue; 189 } 190 191 $urlParameters = []; 192 if ($params['lastread'] && $state == 'outdated') { 193 $urlParameters['rev'] = $lastread; 194 } 195 $url = wl($page, $urlParameters); 196 $link = '<a class="wikilink1" href="' . $url . '">'; 197 if (useHeading('content')) { 198 $heading = p_get_first_heading($page); 199 if (!blank($heading)) { 200 $link .= $heading; 201 } else { 202 $link .= noNSorNS($page); 203 } 204 } else { 205 $link .= noNSorNS($page); 206 } 207 $link .= '</a>'; 208 $renderer->doc .= '<li class="li">' . $link . '</li>'; 209 } 210 $renderer->doc .= '</ul>'; 211 } 212} 213