1<?php 2 3namespace dokuwiki\plugin\struct\meta; 4 5/** 6 * Base contract for Aggregations 7 * 8 * @package dokuwiki\plugin\struct\meta 9 */ 10abstract class Aggregation 11{ 12 /** @var string the page id of the page this is rendered to */ 13 protected $id; 14 15 /** @var string the Type of renderer used */ 16 protected $mode; 17 18 /** @var \Doku_Renderer the DokuWiki renderer used to create the output */ 19 protected $renderer; 20 21 /** @var SearchConfig the configured search - gives access to columns etc. */ 22 protected $searchConfig; 23 24 /** @var Column[] the list of columns to be displayed */ 25 protected $columns; 26 27 /** @var Value[][] the search result */ 28 protected $result; 29 30 /** @var int number of all results */ 31 protected $resultCount; 32 33 /** @var string usually a div, but AggregationValue needs to be wrapped in a span */ 34 protected $tagName = 'div'; 35 36 /** 37 * @todo we might be able to get rid of this helper and move this to SearchConfig 38 * @var \helper_plugin_struct_config 39 */ 40 protected $helper; 41 42 /** 43 * @var array the original configuration data 44 */ 45 protected $data; 46 47 /** 48 * Initialize the Aggregation renderer and executes the search 49 * 50 * You need to call startScope(), render() and finishScope() on the resulting object. 51 * 52 * @param string $id The page this is rendered to 53 * @param string $mode The renderer format 54 * @param \Doku_Renderer $renderer The renderer to use for output 55 * @param SearchConfig $searchConfig The configured search object to use for displaying the data 56 */ 57 public function __construct($id, $mode, \Doku_Renderer $renderer, SearchConfig $searchConfig) 58 { 59 $this->id = $id; 60 $this->mode = $mode; 61 $this->renderer = $renderer; 62 $this->searchConfig = $searchConfig; 63 $this->data = $this->searchConfig->getConf(); 64 $this->helper = plugin_load('helper', 'struct_config'); 65 } 66 67 /** 68 * Returns the page id the aggregation is used on 69 */ 70 public function getID() 71 { 72 return $this->id; 73 } 74 75 /** 76 * Return the list of classes that should be added to the scope when rendering XHTML 77 * 78 * @return string[] 79 */ 80 public function getScopeClasses() 81 { 82 // we're all aggregations 83 $classes = ['structaggregation']; 84 85 // which type of aggregation are we? 86 $class = get_class($this); 87 $class = substr($class, strrpos($class, "\\") + 1); 88 $class = strtolower($class); 89 $classes[] = 'struct' . $class; 90 91 // config options 92 if ($this->data['nesting']) { 93 $classes[] = 'is-nested'; 94 } 95 if ($this->data['index']) { 96 $classes[] = 'is-indexed'; 97 } 98 99 // custom classes 100 $classes = array_merge($classes, $this->data['classes']); 101 return $classes; 102 } 103 104 public function executeSearch() 105 { 106 $this->columns = $this->searchConfig->getColumns(); 107 $this->result = $this->searchConfig->execute(); 108 $this->resultCount = $this->searchConfig->getCount(); 109 110 $this->postSearch(); 111 } 112 113 /** 114 * Render the actual output to the renderer 115 * 116 * @param bool $showNotFound show a not found message when no data available? 117 */ 118 abstract public function render($showNotFound = false); 119 120 /** 121 * Adds additional info to document and renderer in XHTML mode 122 * 123 * Called before render() 124 * 125 * @see finishScope() 126 */ 127 public function startScope() 128 { 129 if ($this->mode !== 'metadata') { 130 $this->executeSearch(); 131 } 132 if ($this->mode == 'xhtml') { 133 $classes = $this->getScopeClasses(); 134 135 $hash = $this->renderer->info['struct_table_hash'] ?? ''; 136 $id = $hash ? " id=\"$hash\" " : ''; 137 138 $this->renderer->doc .= '<' . $this->tagName . $id . ' class="' . implode(' ', $classes) . '">'; 139 } 140 } 141 142 /** 143 * Child classes can set their own class properties based on search result 144 * 145 * @return void 146 */ 147 public function postSearch() 148 { 149 return; 150 } 151 152 /** 153 * Closes anything opened in startScope() 154 * 155 * Called after render() 156 * 157 * @see startScope() 158 */ 159 public function finishScope() 160 { 161 if ($this->mode == 'xhtml') { 162 $this->renderer->doc .= '</' . $this->tagName . '>'; 163 } 164 } 165} 166