1<?php
2
3namespace Elastica\Aggregation;
4
5/**
6 * Class DateHistogram.
7 *
8 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html
9 */
10class DateHistogram extends Histogram
11{
12    public const DEFAULT_TIMEZONE_VALUE = 'UTC';
13
14    private const CALENDAR_INTERVAL_VALUES = [
15        '1m',
16        'minute',
17        '1h',
18        'hour',
19        '1d',
20        'day',
21        '1w',
22        'week',
23        '1M',
24        'month',
25        '1q',
26        'quarter',
27        '1y',
28        'year',
29    ];
30
31    /**
32     * Set the interval by which documents will be bucketed.
33     *
34     * @param int|string $interval
35     *
36     * @return $this
37     */
38    public function setInterval($interval)
39    {
40        $interval = (string) $interval;
41
42        if (\in_array($interval, self::CALENDAR_INTERVAL_VALUES, true)) {
43            return $this->setCalendarInterval($interval);
44        }
45
46        return $this->setFixedInterval($interval);
47    }
48
49    /**
50     * @return $this
51     */
52    public function setCalendarInterval(string $interval): self
53    {
54        return $this->setParam('calendar_interval', $interval);
55    }
56
57    /**
58     * @return $this
59     */
60    public function setFixedInterval(string $interval): self
61    {
62        return $this->setParam('fixed_interval', $interval);
63    }
64
65    /**
66     * Set time_zone option.
67     *
68     * @return $this
69     */
70    public function setTimezone(string $timezone): self
71    {
72        return $this->setParam('time_zone', $timezone);
73    }
74
75    /**
76     * Adjust for granularity of date data.
77     *
78     * @param int $factor set to 1000 if date is stored in seconds rather than milliseconds
79     *
80     * @return $this
81     */
82    public function setFactor(int $factor): self
83    {
84        return $this->setParam('factor', $factor);
85    }
86
87    /**
88     * Set offset option.
89     *
90     * @return $this
91     */
92    public function setOffset(string $offset): self
93    {
94        return $this->setParam('offset', $offset);
95    }
96
97    /**
98     * Set the format for returned bucket key_as_string values.
99     *
100     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-daterange-aggregation.html#date-format-pattern
101     *
102     * @param string $format see link for formatting options
103     *
104     * @return $this
105     */
106    public function setFormat(string $format): self
107    {
108        return $this->setParam('format', $format);
109    }
110
111    /**
112     * Set extended bounds option.
113     *
114     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-histogram-aggregation.html#search-aggregations-bucket-histogram-aggregation-extended-bounds
115     *
116     * @param string $min see link for formatting options
117     * @param string $max see link for formatting options
118     *
119     * @return $this
120     */
121    public function setExtendedBounds(string $min = '', string $max = ''): self
122    {
123        $bounds = [];
124        $bounds['min'] = $min;
125        $bounds['max'] = $max;
126        // switch if min is higher then max
127        if (\strtotime($min) > \strtotime($max)) {
128            $bounds['min'] = $max;
129            $bounds['max'] = $min;
130        }
131
132        return $this->setParam('extended_bounds', $bounds);
133    }
134}
135