1<?php
2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
3//
4// All Rights Reserved. See copyright.txt for details and a complete list of authors.
5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
6// $Id$
7
8class Search_Query_FacetWikiBuilder
9{
10	private $facets = [];
11
12	function apply(WikiParser_PluginMatcher $matches)
13	{
14		$argumentParser = new WikiParser_PluginArgumentParser;
15
16		foreach ($matches as $match) {
17			if ($match->getName() === 'facet') {
18				$arguments = $argumentParser->parse($match->getArguments());
19				if (isset($arguments['name'])) {
20					$facet = [
21						'name'     => $arguments['name'],
22						'type'     => isset($arguments['type']) ? $arguments['type'] : 'terms',
23					];
24
25					if ($facet['type'] === 'terms') {
26						$facet['operator'] = isset($arguments['operator']) ? $arguments['operator'] : 'or';
27						$facet['count'] = isset($arguments['count']) ? $arguments['count'] : null;
28						$facet['order'] = isset($arguments['order']) ? $arguments['order'] : null;
29						$facet['min'] = isset($arguments['min']) ? $arguments['min'] : null;
30					} elseif ($facet['type'] === 'date_range') {
31						$facet['ranges'] = isset($arguments['ranges']) ? $arguments['ranges'] : null;
32					} elseif ($facet['type'] === 'date_histogram') {
33						$facet['interval'] = isset($arguments['interval']) ? $arguments['interval'] : null;
34						$facet['format'] = isset($arguments['format']) ? $arguments['format'] : null;
35					}
36
37					if (isset($arguments['id'])) {
38						$facet['id'] = $arguments['id'];
39					} else {
40						$facet['id'] = $arguments['name'];
41					}
42
43					$this->facets[] = $facet;
44				}
45			}
46		}
47	}
48
49	function build(Search_Query $query, Search_FacetProvider $provider)
50	{
51		foreach ($this->facets as $facet) {
52			if (isset($facet['id'])) {
53				$real = $provider->getFacet($facet['id']);
54			} else {
55				$real = null;
56			}
57			if (! $real) {
58				$real = $provider->getFacet($facet['name']);	// name is actually field, id allows multiple aggs per field
59			}
60			if ($real) {
61
62				if ($facet['type'] === 'date_histogram' && ! is_a($real, '\Search_Query_Facet_DateHistogram')) {
63					// tracker date fields return a generic "Term" facet but the plugin should choose range of histogram
64					$real = Search_Query_Facet_DateHistogram::fromField($real->getField())->setLabel($real->getLabel());
65
66				} else if ($facet['type'] === 'date_range' && ! is_a($real, '\Search_Query_Facet_DateRange')) {
67					// same for date range
68					$real = Search_Query_Facet_DateRange::fromField($real->getField())->setLabel($real->getLabel());
69				}
70
71				if (isset($facet['operator']) && $facet['operator']) {
72					$real->setOperator($facet['operator']);
73				}
74
75				if (isset($facet['count']) && $facet['count']) {
76					$real->setCount($facet['count']);
77				}
78
79				if (isset($facet['order']) && $facet['order']) {
80					$real->setOrder($facet['order']);
81				}
82
83				if (isset($facet['min']) && $facet['min'] !== null) {
84					$real->setMinDocCount($facet['min']);
85				}
86
87				if (is_a($real, '\Search_Query_Facet_DateRange')) {
88					if (! empty($facet['ranges'])) {
89						$ranges = explode('|', $facet['ranges']);
90						$real->clearRanges();
91						foreach (array_filter($ranges) as & $range) {
92							$range = explode(',', $range);
93							if (count($range) > 2) {
94								$real->addRange($range[1], $range[0], $range[2]);
95							} else if (count($range) > 1) {
96								$real->addRange($range[1], $range[0]);
97							}
98						}
99					}
100				} elseif (is_a($real, '\Search_Query_Facet_DateHistogram')) {
101
102					if (! empty($facet['interval'])) {
103						$real->setInterval($facet['interval']);
104					}
105
106					if (! empty($facet['format'])) {
107						$format = $facet['format'];
108
109						$real->setRenderCallback(
110							function ($date) use ($format) {
111								if ($date === 0) {
112									$date = 1000;	// tikilib makes zero date now FIXME (it)
113								}
114								return TikiLib::lib('tiki')->date_format($format, $date / 1000);
115							}
116						);
117					}
118				}
119
120				$query->requestFacet($real);
121			}
122		}
123	}
124
125	/**
126	 * @return array
127	 */
128	public function getFacets(): array
129	{
130		return $this->facets;
131	}
132
133}
134