xref: /plugin/struct/meta/AggregationCloud.php (revision fa04b28c8e5db215f2d38751b0b1b540f2561b9a)
1*fa04b28cSMichael Grosse<?php
2*fa04b28cSMichael Grossenamespace dokuwiki\plugin\struct\meta;
3*fa04b28cSMichael Grosseclass AggregationCloud {
4*fa04b28cSMichael Grosse    /**
5*fa04b28cSMichael Grosse     * @var string the page id of the page this is rendered to
6*fa04b28cSMichael Grosse     */
7*fa04b28cSMichael Grosse    protected $id;
8*fa04b28cSMichael Grosse    /**
9*fa04b28cSMichael Grosse     * @var string the Type of renderer used
10*fa04b28cSMichael Grosse     */
11*fa04b28cSMichael Grosse    protected $mode;
12*fa04b28cSMichael Grosse    /**
13*fa04b28cSMichael Grosse     * @var \Doku_Renderer the DokuWiki renderer used to create the output
14*fa04b28cSMichael Grosse     */
15*fa04b28cSMichael Grosse    protected $renderer;
16*fa04b28cSMichael Grosse    /**
17*fa04b28cSMichael Grosse     * @var SearchConfig the configured search - gives access to columns etc.
18*fa04b28cSMichael Grosse     */
19*fa04b28cSMichael Grosse    protected $searchConfig;
20*fa04b28cSMichael Grosse    /**
21*fa04b28cSMichael Grosse     * @var Column[] the list of columns to be displayed
22*fa04b28cSMichael Grosse     */
23*fa04b28cSMichael Grosse    protected $columns;
24*fa04b28cSMichael Grosse    /**
25*fa04b28cSMichael Grosse     * @var  Value[][] the search result
26*fa04b28cSMichael Grosse     */
27*fa04b28cSMichael Grosse    protected $result;
28*fa04b28cSMichael Grosse    /**
29*fa04b28cSMichael Grosse     * @var int number of all results
30*fa04b28cSMichael Grosse     */
31*fa04b28cSMichael Grosse    protected $resultCount;
32*fa04b28cSMichael Grosse    /**
33*fa04b28cSMichael Grosse     * @var string[] the result PIDs for each row
34*fa04b28cSMichael Grosse     */
35*fa04b28cSMichael Grosse    protected $resultPIDs;
36*fa04b28cSMichael Grosse    /**
37*fa04b28cSMichael Grosse     * @var array for summing up columns
38*fa04b28cSMichael Grosse     */
39*fa04b28cSMichael Grosse    protected $sums;
40*fa04b28cSMichael Grosse    /**
41*fa04b28cSMichael Grosse     * @var bool skip full table when no results found
42*fa04b28cSMichael Grosse     */
43*fa04b28cSMichael Grosse    protected $simplenone = true;
44*fa04b28cSMichael Grosse    /**
45*fa04b28cSMichael Grosse     * @todo we might be able to get rid of this helper and move this to SearchConfig
46*fa04b28cSMichael Grosse     * @var \helper_plugin_struct_config
47*fa04b28cSMichael Grosse     */
48*fa04b28cSMichael Grosse    protected $helper;
49*fa04b28cSMichael Grosse    /**
50*fa04b28cSMichael Grosse     * Initialize the Aggregation renderer and executes the search
51*fa04b28cSMichael Grosse     *
52*fa04b28cSMichael Grosse     * You need to call @see render() on the resulting object.
53*fa04b28cSMichael Grosse     *
54*fa04b28cSMichael Grosse     * @param string $id
55*fa04b28cSMichael Grosse     * @param string $mode
56*fa04b28cSMichael Grosse     * @param \Doku_Renderer $renderer
57*fa04b28cSMichael Grosse     * @param SearchConfig $searchConfig
58*fa04b28cSMichael Grosse     */
59*fa04b28cSMichael Grosse    public function __construct($id, $mode, \Doku_Renderer $renderer, SearchConfig $searchConfig) {
60*fa04b28cSMichael Grosse        $this->id = $id;
61*fa04b28cSMichael Grosse        $this->mode = $mode;
62*fa04b28cSMichael Grosse        $this->renderer = $renderer;
63*fa04b28cSMichael Grosse        $this->searchConfig = $searchConfig;
64*fa04b28cSMichael Grosse        $this->data = $searchConfig->getConf();
65*fa04b28cSMichael Grosse        $this->columns = $searchConfig->getColumns();
66*fa04b28cSMichael Grosse        $this->result = $this->search(); //$this->searchConfig->execute();
67*fa04b28cSMichael Grosse        //$this->resultCount = $this->searchConfig->getCount();
68*fa04b28cSMichael Grosse        //$this->resultPIDs = $this->searchConfig->getPids();
69*fa04b28cSMichael Grosse        $this->helper = plugin_load('helper', 'struct_config');
70*fa04b28cSMichael Grosse    }
71*fa04b28cSMichael Grosse
72*fa04b28cSMichael Grosse    public function search() {
73*fa04b28cSMichael Grosse        $QB = new QueryBuilder;
74*fa04b28cSMichael Grosse        $schema = $this->data['schemas'][0][0];
75*fa04b28cSMichael Grosse        $colref = $this->columns[0]->getColref();
76*fa04b28cSMichael Grosse        if ($this->columns[0]->getType()->isMulti()) {
77*fa04b28cSMichael Grosse            $table = 'multi_' . $schema;
78*fa04b28cSMichael Grosse            $col = 'value';
79*fa04b28cSMichael Grosse            $QB->filters()->whereAnd('T1.colref='.$colref);
80*fa04b28cSMichael Grosse        } else {
81*fa04b28cSMichael Grosse            $table = 'data_' . $schema;
82*fa04b28cSMichael Grosse            $col = 'col' . $colref;
83*fa04b28cSMichael Grosse        }
84*fa04b28cSMichael Grosse        $QB->addTable($table, 'T1');
85*fa04b28cSMichael Grosse        $QB->addSelectColumn('T1', $col, 'tag');
86*fa04b28cSMichael Grosse        $QB->addSelectStatement("COUNT(T1.$col)", 'count');
87*fa04b28cSMichael Grosse        $QB->filters()->whereAnd('T1.latest=1');
88*fa04b28cSMichael Grosse        $QB->addGroupByStatement('tag');
89*fa04b28cSMichael Grosse        $QB->addOrderBy('tag');
90*fa04b28cSMichael Grosse        /*
91*fa04b28cSMichael Grosse          if ($min=$this->data['min']) {
92*fa04b28cSMichael Grosse          $QB->filters()->whereAnd("count > $min");
93*fa04b28cSMichael Grosse          }
94*fa04b28cSMichael Grosse        */
95*fa04b28cSMichael Grosse        $sql = $QB->getSQL();
96*fa04b28cSMichael Grosse        $db = plugin_load('helper', 'struct_db')->getDB();
97*fa04b28cSMichael Grosse        $res=$db->query($sql[0], $sql[1]);
98*fa04b28cSMichael Grosse        $results = $db->res2arr($res);
99*fa04b28cSMichael Grosse        $db->res_close($res);
100*fa04b28cSMichael Grosse        foreach ($results as &$result) {
101*fa04b28cSMichael Grosse            $result['tag'] = new Value($this->columns[0], $result['tag']);
102*fa04b28cSMichael Grosse        }
103*fa04b28cSMichael Grosse        return $results;
104*fa04b28cSMichael Grosse    }
105*fa04b28cSMichael Grosse
106*fa04b28cSMichael Grosse    /**
107*fa04b28cSMichael Grosse     * Create the table on the renderer
108*fa04b28cSMichael Grosse     */
109*fa04b28cSMichael Grosse    public function render() {
110*fa04b28cSMichael Grosse        $this->startScope();
111*fa04b28cSMichael Grosse        $this->renderer->doc .= '<ul>';
112*fa04b28cSMichael Grosse        foreach ($this->result as $result) {
113*fa04b28cSMichael Grosse            $this->renderResult($result);
114*fa04b28cSMichael Grosse        }
115*fa04b28cSMichael Grosse        $this->renderer->doc .= '</ul>';
116*fa04b28cSMichael Grosse        $this->finishScope();
117*fa04b28cSMichael Grosse        return;
118*fa04b28cSMichael Grosse    }
119*fa04b28cSMichael Grosse    /**
120*fa04b28cSMichael Grosse     * Adds additional info to document and renderer in XHTML mode
121*fa04b28cSMichael Grosse     *
122*fa04b28cSMichael Grosse     * @see finishScope()
123*fa04b28cSMichael Grosse     */
124*fa04b28cSMichael Grosse    protected function startScope() {
125*fa04b28cSMichael Grosse        // unique identifier for this aggregation
126*fa04b28cSMichael Grosse        $this->renderer->info['struct_cloud_hash'] = md5(var_export($this->data, true));
127*fa04b28cSMichael Grosse        // wrapping div
128*fa04b28cSMichael Grosse        if($this->mode != 'xhtml') return;
129*fa04b28cSMichael Grosse        $this->renderer->doc .= "<div class=\"structaggregation cloudaggregation\">";
130*fa04b28cSMichael Grosse    }
131*fa04b28cSMichael Grosse    /**
132*fa04b28cSMichael Grosse     * Closes the table and anything opened in startScope()
133*fa04b28cSMichael Grosse     *
134*fa04b28cSMichael Grosse     * @see startScope()
135*fa04b28cSMichael Grosse     */
136*fa04b28cSMichael Grosse    protected function finishScope() {
137*fa04b28cSMichael Grosse        // remove identifier from renderer again
138*fa04b28cSMichael Grosse        if(isset($this->renderer->info['struct_cloud_hash'])) {
139*fa04b28cSMichael Grosse            unset($this->renderer->info['struct_cloud_hash']);
140*fa04b28cSMichael Grosse        }
141*fa04b28cSMichael Grosse        // wrapping div
142*fa04b28cSMichael Grosse        if($this->mode != 'xhtml') return;
143*fa04b28cSMichael Grosse        $this->renderer->doc .= '</div>';
144*fa04b28cSMichael Grosse    }
145*fa04b28cSMichael Grosse    protected function renderResult($result) {
146*fa04b28cSMichael Grosse        /**
147*fa04b28cSMichael Grosse         * @var Value $value
148*fa04b28cSMichael Grosse         */
149*fa04b28cSMichael Grosse        $value = $result['tag'];
150*fa04b28cSMichael Grosse        $count = $result['count'];
151*fa04b28cSMichael Grosse        if ($value->isEmpty()) {
152*fa04b28cSMichael Grosse            return;
153*fa04b28cSMichael Grosse        }
154*fa04b28cSMichael Grosse
155*fa04b28cSMichael Grosse        $raw = $value->getRawValue();
156*fa04b28cSMichael Grosse        if (is_array($raw)) {
157*fa04b28cSMichael Grosse            $raw = $raw[0];
158*fa04b28cSMichael Grosse        }
159*fa04b28cSMichael Grosse        $schema = $this->data['schemas'][0][0];
160*fa04b28cSMichael Grosse        $col = $value->getColumn()->getLabel();
161*fa04b28cSMichael Grosse        $this->renderer->doc .= '<li><div class="li">';
162*fa04b28cSMichael Grosse        $this->renderer->doc .= '<div data-count="'. $count.'" class="' . $value->getColumn()->getLabel() . '">';
163*fa04b28cSMichael Grosse        //$value->render($this->renderer, $this->mode);
164*fa04b28cSMichael Grosse        $this->renderer->internallink("?flt[$schema.$col*~]=$raw",$raw);
165*fa04b28cSMichael Grosse        if ($column < $this->resultCount) {
166*fa04b28cSMichael Grosse            $this->renderer->doc .= ' ';
167*fa04b28cSMichael Grosse        }
168*fa04b28cSMichael Grosse        $this->renderer->doc .= '</div>';
169*fa04b28cSMichael Grosse        $this->renderer->doc .= '</div></li>';
170*fa04b28cSMichael Grosse    }
171*fa04b28cSMichael Grosse}