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 = $searchConfig->getConf(); 64 $this->columns = $searchConfig->getColumns(); 65 $this->result = $this->searchConfig->execute(); 66 $this->resultCount = $this->searchConfig->getCount(); 67 $this->helper = plugin_load('helper', 'struct_config'); 68 } 69 70 /** 71 * Returns the page id the aggregation is used on 72 */ 73 public function getID() 74 { 75 return $this->id; 76 } 77 78 /** 79 * Return the list of classes that should be added to the scope when rendering XHTML 80 * 81 * @return string[] 82 */ 83 public function getScopeClasses() 84 { 85 // we're all aggregations 86 $classes = ['structaggregation']; 87 88 // which type of aggregation are we? 89 $class = get_class($this); 90 $class = substr($class, strrpos($class, "\\") + 1); 91 $class = strtolower($class); 92 $classes[] = 'struct' . $class; 93 94 // config options 95 if ($this->data['nesting']) { 96 $classes[] = 'is-nested'; 97 } 98 if ($this->data['index']) { 99 $classes[] = 'is-indexed'; 100 } 101 102 // custom classes 103 $classes = array_merge($classes, $this->data['classes']); 104 return $classes; 105 } 106 107 /** 108 * Render the actual output to the renderer 109 * 110 * @param bool $showNotFound show a not found message when no data available? 111 */ 112 abstract public function render($showNotFound = false); 113 114 /** 115 * Adds additional info to document and renderer in XHTML mode 116 * 117 * Called before render() 118 * 119 * @see finishScope() 120 */ 121 public function startScope() 122 { 123 if ($this->mode == 'xhtml') { 124 $classes = $this->getScopeClasses(); 125 126 $hash = $this->renderer->info['struct_table_hash'] ?? ''; 127 $id = $hash ? " id=\"$hash\" " : ''; 128 129 $this->renderer->doc .= '<' . $this->tagName . $id . ' class="' . implode(' ', $classes) . '">'; 130 } 131 } 132 133 /** 134 * Closes anything opened in startScope() 135 * 136 * Called after render() 137 * 138 * @see startScope() 139 */ 140 public function finishScope() 141 { 142 if ($this->mode == 'xhtml') { 143 $this->renderer->doc .= '</' . $this->tagName . '>'; 144 } 145 } 146} 147