1<?php 2 3namespace dokuwiki\plugin\bez\struct; 4 5use dokuwiki\plugin\struct\meta\ValidationException; 6use dokuwiki\plugin\struct\types\AbstractMultiBaseType; 7 8class BezType extends AbstractMultiBaseType { 9 10 const BEZ_TABLE_CODES = array( 11 '' => 'thread', 12 'k' => 'thread_comment', 13 'z' => 'task', 14 'zk' => 'task_comment' 15 ); 16 17 protected $config = array( 18 'autocomplete' => array( 19 'maxresult' => 10 20 ), 21 ); 22 23 /** 24 * Output the stored data 25 * 26 * @param string $value the value stored in the database 27 * @param \Doku_Renderer $R the renderer currently used to render the data 28 * @param string $mode The mode the output is rendered in (eg. XHTML) 29 * @return bool true if $mode could be satisfied 30 */ 31 public function renderValue($value, \Doku_Renderer $R, $mode) { 32 preg_match('/#([a-z]*)([0-9]+)/', $value, $matches); 33 list(,$code, $id) = $matches; 34 $title = $value; 35 36 $anchor = ''; 37 $id_key = 'id'; 38 switch ($code) { 39 case '': 40 $table = 'thread'; 41 break; 42 case 'k': 43 $table = 'thread'; 44 $anchor = '#k' . $id; 45 46 /** @var helper_plugin_sqlite $sqlite */ 47 $sqlite = plugin_load('helper', 'bez_db')->getDB(); 48 $res = $sqlite->query("SELECT thread_id FROM thread_comment WHERE id=?", $id); 49 $id = $res->fetchColumn(); 50 break; 51 case 'z': 52 $table = 'task'; 53 $id_key = 'tid'; 54 break; 55 case 'zk': 56 $table = 'task'; 57 $id_key = 'tid'; 58 $anchor = '#zk' . $id; 59 60 /** @var helper_plugin_sqlite $sqlite */ 61 $sqlite = plugin_load('helper', 'bez_db')->getDB(); 62 $res = $sqlite->query("SELECT task_id FROM task_comment WHERE id=?", $id); 63 $id = $res->fetchColumn(); 64 break; 65 } 66 67 $wl = wl("bez:$table:$id_key:$id") . $anchor; 68 $R->doc .= '<a href="'.$wl.'">'.$title.'</a>'; 69 70 71 return true; 72 } 73 74 /** 75 * Cleans the link 76 * 77 * @param string $rawvalue 78 * @return string 79 */ 80 public function validate($rawvalue) { 81 preg_match('/#([a-z]*)([0-9]+)/', $rawvalue, $matches); 82 list(,$code, $id) = $matches; 83 84 if (!is_numeric($id)) { 85 throw new ValidationException('Invalid BEZ reference'); 86 } 87 88 if (!in_array($code, array_keys(self::BEZ_TABLE_CODES))) { 89 throw new ValidationException('Invalid BEZ reference'); 90 } 91 92 $table = self::BEZ_TABLE_CODES[$code]; 93 94 /** @var helper_plugin_sqlite $sqlite */ 95 $sqlite = plugin_load('helper', 'bez_db')->getDB(); 96 $res = $sqlite->query("SELECT COUNT(*) FROM $table WHERE id=?", $id); 97 $count = $res->fetchColumn(); 98 if ($count == 0) { 99 throw new ValidationException(ucfirst($table) . " with id: $id doesn't exists."); 100 } 101 102 return $rawvalue; 103 } 104 105 /** 106 * Autocompletion support for pages 107 * 108 * @return array 109 */ 110 public function handleAjax() { 111 global $INPUT; 112 113 // check minimum length 114 $lookup = trim($INPUT->str('search')); 115 if(utf8_strlen($lookup) < 1) return array(); 116 if ($lookup[0] != '#') return array(); 117 118 preg_match('/#([a-z]*)([0-9]+)/', $lookup, $matches); 119 list(,$code, $id) = $matches; 120 121 if (!is_numeric($id)) return array(); 122 if (!in_array($code, array_keys(self::BEZ_TABLE_CODES))) return array(); 123 124 $table = self::BEZ_TABLE_CODES[$code]; 125 126 // results wanted? 127 $max = (int)$this->config['autocomplete']['maxresult']; 128 if($max <= 0) return array(); 129 130 $bez_db_helper = plugin_load('helper', 'bez_db'); 131 132 /** @var helper_plugin_sqlite $sqlite */ 133 $sqlite = $bez_db_helper->getDB(); 134 135 $fields = array('id'); 136 if ($table == 'thread' || $table == 'task') { 137 $fields[] = 'state'; 138 } 139 140 $sql = "SELECT " . implode(',', $fields) . " FROM $table WHERE id LIKE ? LIMIT $max"; 141 $res = $sqlite->query($sql, $id . '%'); 142 143 $result = array(); 144 while ($row = $res->fetch(\PDO::FETCH_ASSOC)) { 145 146 $name = $value = '#' . $code . $row['id']; 147 if ($table == 'thread' || $table == 'task') { 148 $state = $bez_db_helper->getLang('state_' . $row['state']); 149 $name .= ' (' . $state . ')'; 150 } 151 152 $result[] = array( 153 'label' => $name, 154 'value' => $value 155 ); 156 } 157 158 return $result; 159 } 160}