1<?php 2namespace dokuwiki\plugin\structcombolookup\types; 3 4use dokuwiki\plugin\struct\meta\Column; 5use dokuwiki\plugin\struct\meta\Search; 6use dokuwiki\plugin\struct\meta\Value; 7use dokuwiki\plugin\struct\types\Lookup; 8 9class NarrowingLookup extends Lookup 10{ 11 protected $config = array( 12 'schema' => '', 13 'field' => '', 14 'narrow by' => '', 15 'disable child' => true 16 ); 17 18 /** @var Column caches the referenced column */ 19 protected $narrowByColumn = null; 20 21 /** 22 * Get the configured lookup column 23 * 24 * @return Column|false 25 */ 26 protected function getNarrowByColumn() { 27 if($this->narrowByColumn !== null) return $this->narrowByColumn; 28 $this->narrowByColumn = $this->getColumn($this->config['schema'], $this->config['narrow by']); 29 return $this->narrowByColumn; 30 } 31 32 33 /** 34 * Creates the options array 35 * 36 * @return array 37 */ 38 protected function getNarrowByOptions() { 39 $schema = $this->config['schema']; 40 $column = $this->getNarrowByColumn(); 41 if(!$column) return array(); 42 $field = $column->getLabel(); 43 44 $search = new Search(); 45 $search->addSchema($schema); 46 $search->addColumn($field); 47 $search->addSort($field); 48 49 $options = array('' => ''); 50 $results = $search->execute(); 51 foreach ($results as $result) { 52 $options[$result[0]->getRawValue()] = $result[0]->getDisplayValue(); 53 } 54 return $options; 55 } 56 57 protected function getRawValueNarrowingValue($rawvalue) { 58 $schema = $this->config['schema']; 59 $column = $this->getNarrowByColumn(); 60 if(!$column) return ''; 61 $field = $column->getLabel(); 62 63 $search = new Search(); 64 $search->addSchema($schema); 65 $search->addColumn($field); 66 $search->addFilter($this->config['field'], $rawvalue, '='); 67 $result = $search->execute(); 68 if (!isset($result[0])) return ''; 69 return $result[0][0]->getRawValue(); 70 } 71 72 /** 73 * Creates the options array 74 * 75 * @return array 76 */ 77 protected function getOptions() { 78 $schema = $this->config['schema']; 79 $column = $this->getLookupColumn(); 80 if(!$column) return array(); 81 $field = $column->getLabel(); 82 83 $narrowingColumn = $this->getNarrowByColumn(); 84 if(!$narrowingColumn) return array(); 85 $narrowingField = $narrowingColumn->getLabel(); 86 87 88 89 $search = new Search(); 90 $search->addSchema($schema); 91 $search->addColumn($field); 92 $search->addColumn($narrowingField); 93 94 $search->addSort($field); 95 $result = $search->execute(); 96 $pids = $search->getPids(); 97 $len = count($result); 98 99 /** @var Value[][] $result */ 100 $options = array('' => array('', '')); 101 for($i = 0; $i < $len; $i++) { 102 $options[$pids[$i]] = array($result[$i][0]->getDisplayValue(), $result[$i][1]->getRawValue()); 103 } 104 return $options; 105 } 106 107 108 protected function parentValueEditor($name, $rawvalue, $htmlID) { 109 $params = array( 110 'data-child-id' => $htmlID, 111 'class' => 'struct_'.strtolower($this->getClass()). '_parent', 112 'onchange' => 'structcombolookup_change_narrowby(this, '.(int)$this->config['disable child'].')' 113 ); 114 $attributes = buildAttributes($params, true); 115 $html = "<select $attributes>"; 116 foreach($this->getNarrowByOptions() as $opt => $val) { 117 if($opt == $this->getRawValueNarrowingValue($rawvalue)) { 118 $selected = 'selected="selected"'; 119 } else { 120 $selected = ''; 121 } 122 123 $html .= "<option $selected value=\"" . hsc($opt) . "\">" . hsc($val) . '</option>'; 124 } 125 $html .= '</select>'; 126 127 return $html; 128 } 129 130 /** 131 * A Dropdown with a single value to pick 132 * 133 * @param string $name 134 * @param string $rawvalue 135 * @return string 136 */ 137 public function valueEditor($name, $rawvalue, $htmlID) { 138 $html = $this->parentValueEditor($name, $rawvalue, $htmlID); 139 140 $params = array( 141 'name' => $name, 142 'class' => 'struct_'.strtolower($this->getClass()) . '_child', 143 'id' => $htmlID 144 ); 145 if ($this->config['disable child']) { 146 $params['disabled'] = 'disabled'; 147 } 148 $attributes = buildAttributes($params, true); 149 $html .= "<select $attributes>"; 150 foreach($this->getOptions() as $opt => $option) { 151 list($val, $parent) = $option; 152 if($opt == $rawvalue) { 153 $selected = 'selected="selected"'; 154 } else { 155 $selected = ''; 156 } 157 158 $html .= "<option data-parent=\"" . hsc($parent) . "\" $selected value=\"" . hsc($opt) . "\">" . hsc($val) . '</option>'; 159 } 160 $html .= '</select>'; 161 162 return $html; 163 } 164}