1<?php 2 3namespace dokuwiki\plugin\structstatus; 4 5use dokuwiki\plugin\struct\meta\Column; 6use dokuwiki\plugin\struct\meta\QueryBuilder; 7use dokuwiki\plugin\struct\meta\Search; 8use dokuwiki\plugin\struct\types\AbstractBaseType; 9use dokuwiki\plugin\struct\types\Lookup; 10 11class Status extends Lookup { 12 13 protected $config = array( 14 'schema' => '' 15 ); 16 17 /** 18 * @inheritDoc 19 */ 20 protected function getLookupColumn() { 21 if($this->column !== null) return $this->column; 22 $this->column = $this->getColumn($this->config['schema'], 'name_$LANG'); 23 return $this->column; 24 } 25 26 /** 27 * @inheritDoc 28 */ 29 public function renderValue($value, \Doku_Renderer $R, $mode) { 30 list(, $value, $color, $icon) = json_decode($value); 31 32 if($mode == 'xhtml') { 33 $R->doc .= $this->xhtmlStatus($value, $color, $icon); 34 } else { 35 $R->cdata($value); 36 } 37 38 return true; 39 } 40 41 /** 42 * Creates a single status entry 43 * 44 * @param string $label 45 * @param string $color 46 * @param string $icon 47 * @param string $rid the identifier in the linked status lookup table 48 * @param array $classes 49 * @param bool $button 50 * @return string 51 */ 52 public function xhtmlStatus($label, $color, $icon='', $rid = 0, $classes=array(), $button=false) { 53 $html = ''; 54 $classes[] = 'struct_status'; 55 if($icon) $classes[] = 'struct_status_icon_'.$icon; 56 $class = hsc(join(' ', $classes)); 57 58 $tag = $button ? 'button' : 'div'; 59 60 $html .= "<$tag class=\"" . $class . '" style="border-color:' . hsc($color) . '; fill: ' . hsc($color) . ';" data-rid="'.hsc($rid).'">'; 61 $html .= $this->inlineSVG($icon); 62 $html .= hsc($label); 63 $html .= "</$tag>"; 64 65 return $html; 66 } 67 68 /** 69 * Returns the svg code of the given icon 70 * 71 * @param string $icon The icon identifier (no .svg extension) 72 * @return string 73 */ 74 protected function inlineSVG($icon) { 75 $icon = preg_replace('@[\.\\\\/]+@', '', $icon); 76 $file = __DIR__ . '/svg/' . $icon . '.svg'; 77 if(!file_exists($file)) return ''; 78 79 $data = file_get_contents($file); 80 $data = preg_replace('/<\?xml .*?\?>/', '', $data); 81 $data = preg_replace('/<!DOCTYPE .*?>/', '', $data); 82 83 return $data; 84 } 85 86 /** 87 * @inheritDoc 88 */ 89 public function renderMultiValue($values, \Doku_Renderer $R, $mode) { 90 foreach($values as $value) { 91 $this->renderValue($value, $R, $mode); 92 } 93 return true; 94 } 95 96 /** 97 * Merge with lookup table 98 * 99 * @param QueryBuilder $QB 100 * @param string $tablealias 101 * @param string $colname 102 * @param string $alias 103 */ 104 public function select(QueryBuilder $QB, $tablealias, $colname, $alias) { 105 $schema = 'data_' . $this->config['schema']; 106 107 $rightalias = $QB->generateTableAlias(); 108 109 // main status 110 $col_status = $this->getLookupColumn(); 111 if(!$col_status) { 112 AbstractBaseType::select($QB, $tablealias, $colname, $alias); 113 return; 114 } 115 $field_status = $rightalias . '.' . $col_status->getColName(); 116 117 // color 118 $col_color = $this->getColumn($this->config['schema'], 'color'); 119 if(!$col_color) { 120 $field_color = "'#ffffff'"; // static fallback 121 } else { 122 $field_color = $rightalias . '.' . $col_color->getColName(true); 123 } 124 125 // icon 126 $col_icon = $this->getColumn($this->config['schema'], 'icon'); 127 if(!$col_icon) { 128 $field_icon = "''"; // static fallback 129 } else { 130 $field_icon = $rightalias . '.' . $col_icon->getColName(true); 131 } 132 133 // join the lookup 134 $QB->addLeftJoin( 135 $tablealias, $schema, $rightalias, 136 "$tablealias.$colname = STRUCT_JSON($rightalias.pid, CAST($rightalias.rid AS DECIMAL)) AND $rightalias.latest = 1" 137 ); 138 139 // get the values (pid, status, color) 140 $QB->addSelectStatement("STRUCT_JSON($tablealias.$colname, $field_status, $field_color, $field_icon)", $alias); 141 } 142 143 /** 144 * Returns a list of available statuses for this type 145 * 146 * This is similar to getOptions but returns some more info about each status 147 * 148 * @return array 149 */ 150 public function getAllStatuses() { 151 $col = $this->getLookupColumn(); 152 $colname = $col->getLabel(); 153 154 $search = new Search(); 155 $search->addSchema($col->getTable()); 156 $search->addColumn($colname); 157 $search->addColumn('color'); 158 $search->addColumn('icon'); 159 $search->addSort($colname); 160 $values = $search->execute(); 161 $rids = $search->getRids(); 162 163 $statuses = array(); 164 foreach($values as $status) { 165 $rid = json_encode(["", (int)array_shift($rids)]); 166 $label = $status[0]->getValue(); 167 $color = $status[1]->getValue(); 168 $icon = $status[2]->getValue(); 169 170 $statuses[] = compact('rid', 'label', 'color', 'icon'); 171 } 172 173 return $statuses; 174 } 175} 176