Passed
Push — master ( 5ce0f4...742c10 )
by Marcel
02:27
created

VariableService   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 91
c 5
b 0
f 0
dl 0
loc 182
rs 9.84
wmc 32

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
B parseFilter() 0 62 9
B replaceTextVariables() 0 31 11
A parseFormat() 0 6 2
A replaceThresholdsVariables() 0 12 5
A replaceFilterVariables() 0 15 4
1
<?php
2
/**
3
 * Analytics
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the LICENSE.md file.
7
 *
8
 * @author Marcel Scherello <[email protected]>
9
 * @copyright 2019-2022 Marcel Scherello
10
 */
11
12
namespace OCA\Analytics\Service;
13
14
use OCA\Analytics\Db\DatasetMapper;
15
use OCP\IDateTimeFormatter;
16
use Psr\Log\LoggerInterface;
17
18
class VariableService
19
{
20
    private $logger;
21
    private $DatasetMapper;
22
    private $IDateTimeFormatter;
23
24
    public function __construct(
25
        LoggerInterface $logger,
26
        DatasetMapper $DatasetMapper,
27
        IDateTimeFormatter $IDateTimeFormatter
28
    )
29
    {
30
        $this->logger = $logger;
31
        $this->DatasetMapper = $DatasetMapper;
32
        $this->IDateTimeFormatter = $IDateTimeFormatter;
33
    }
34
35
    /**
36
     * replace %*% text variables in thresholds
37
     *
38
     * @param array $thresholds
39
     * @return array
40
     */
41
    public function replaceThresholdsVariables($thresholds)
42
    {
43
        foreach ($thresholds as &$threshold) {
44
            $fields = ['dimension1', 'dimension2'];
45
            foreach ($fields as $field) {
46
                isset($threshold[$field]) ? $name = $threshold[$field] : $name = '';
47
                $parsed = $this->parseFilter($name, '');
48
                if (!$parsed) break;
0 ignored issues
show
Bug Best Practice introduced by
The expression $parsed of type array<string,integer|mixed|string> is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
49
                $threshold[$field] = $parsed['6$startDate'];
50
            }
51
        }
52
        return $thresholds;
53
    }
54
55
    /**
56
     * replace %*% text variables in name and subheader
57
     *
58
     * @param array $datasetMetadata
59
     * @return array
60
     */
61
    public function replaceTextVariables($datasetMetadata)
62
    {
63
        $fields = ['name', 'subheader'];
64
        foreach ($fields as $field) {
65
            isset($datasetMetadata[$field]) ? $name = $datasetMetadata[$field] : $name = '';
66
67
            preg_match_all("/%.*?%/", $name, $matches);
68
            if (count($matches[0]) > 0) {
69
                foreach ($matches[0] as $match) {
70
                    $replace = null;
71
                    if ($match === '%currentDate%') {
72
                        $replace = $this->IDateTimeFormatter->formatDate(time(), 'short');
73
                    } elseif ($match === '%currentTime%') {
74
                        $replace = $this->IDateTimeFormatter->formatTime(time(), 'short');
75
                    } elseif ($match === '%lastUpdateDate%') {
76
                        $timestamp = $this->DatasetMapper->getLastUpdate($datasetMetadata['dataset']);
77
                        $replace = $this->IDateTimeFormatter->formatDate($timestamp, 'short');
78
                    } elseif ($match === '%lastUpdateTime%') {
79
                        $timestamp = $this->DatasetMapper->getLastUpdate($datasetMetadata['dataset']);
80
                        $replace = $this->IDateTimeFormatter->formatTime($timestamp, 'short');
81
                    } elseif ($match === '%owner%') {
82
                        $owner = $this->DatasetMapper->getOwner($datasetMetadata['dataset']);
83
                        $replace = $owner;
84
                    }
85
                    if ($replace !== null) {
86
                        $datasetMetadata[$field] = preg_replace('/' . $match . '/', $replace, $datasetMetadata[$field]);
87
                    }
88
                }
89
            }
90
        }
91
        return $datasetMetadata;
92
    }
93
94
    /**
95
     * replace variables in filters and apply format
96
     *
97
     * @param $reportMetadata
98
     * @return array
99
     */
100
    public function replaceFilterVariables($reportMetadata)
101
    {
102
        $filteroptions = json_decode($reportMetadata['filteroptions'], true);
103
        if (isset($filteroptions['filter'])) {
104
            foreach ($filteroptions['filter'] as $key => $value) {
105
                $parsed = $this->parseFilter($value['value'], $value['option']);
106
                $format = $this->parseFormat($value['value']);
107
108
                if (!$parsed) break;
0 ignored issues
show
Bug Best Practice introduced by
The expression $parsed of type array<string,integer|mixed|string> is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
109
                $filteroptions['filter'][$key]['option'] = $parsed['option'];
110
                $filteroptions['filter'][$key]['value'] = date($format, $parsed['value']);
111
            }
112
        }
113
        $reportMetadata['filteroptions'] = json_encode($filteroptions);
114
        return $reportMetadata;
115
    }
116
117
    /**
118
     * parsing of %*% variables
119
     *
120
     * @param $filter
121
     * @param $option
122
     * @return array|bool
123
     */
124
    private function parseFilter($filter, $option) {
0 ignored issues
show
Unused Code introduced by
The parameter $option is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

124
    private function parseFilter($filter, /** @scrutinizer ignore-unused */ $option) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
125
        preg_match_all("/(?<=%).*(?=%)/", $filter, $matches);
126
        if (count($matches[0]) > 0) {
127
            $filter = $matches[0][0];
128
            preg_match('/(last|next|current|to|yester)?/', $filter, $directionMatch);
129
            preg_match('/[0-9]+/', $filter, $offsetMatch);
130
            preg_match('/(day|days|week|weeks|month|months|year|years)$/', $filter, $unitMatch);
131
132
            if (!$directionMatch[0] || !$unitMatch[0]) {
133
                return false;
134
            }
135
136
            !$offsetMatch[0] ? $offset = 1: $offset = $offsetMatch[0];
137
138
            // remove s to unify e.g. weeks => week
139
            $unit = rtrim($unitMatch[0], 's');
140
141
            if ($directionMatch[0] === "last" || $directionMatch[0] === "yester") {
142
                $direction = '-';
143
                //$directionWord = $directionMatch[0];
144
            } elseif ($directionMatch[0] === "next") {
145
                $direction = '+';
146
                //$directionWord = $directionMatch[0];
147
            } else { // current
148
                $direction = '+';
149
                $offset = 0;
150
                //$directionWord = 'this';
151
            }
152
153
            $timestring = $direction . $offset . ' ' . $unit;
154
            $baseDate = strtotime($timestring);
155
156
            if ($unit === 'day') {
157
                $startString = 'today';
158
                //$endString = 'yesterday';
159
            } else {
160
                $startString = 'first day of this ' . $unit;
161
                //$endString = 'last day of ' . $directionWord . ' ' . $unit;
162
            }
163
            $startTS = strtotime($startString, $baseDate);
164
            $start = date("Y-m-d", $startTS);
165
            //$endTS = strtotime($endString);
166
            //$end = date("Y-m-d", $endTS);
167
168
            $return = [
169
                'value' => $startTS,
170
                'option' => 'GT',
171
                '1$filter' => $filter,
172
                '2$timestring' => $timestring,
173
                '3$target' => $baseDate,
174
                '4$target_clean' => date("Y-m-d", $baseDate),
175
                '5$startString' => $startString,
176
                '6$startDate' => $start,
177
                '7$startTS' => $startTS,
178
                //'8$endString' => $endString,
179
                //'9$endDate' => $end,
180
                //'9$endTS' => $endTS,
181
           ];
182
        } else {
183
            $return = false;
184
        }
185
        return $return;
186
    }
187
188
    /**
189
     * parsing of ( ) format instructions
190
     *
191
     * @param $filter
192
     * @return string
193
     */
194
    private function parseFormat($filter) {
195
        preg_match_all("/(?<=\().*(?=\))/", $filter, $matches);
196
        if (count($matches[0]) > 0) {
197
            return $matches[0][0];
198
        } else {
199
            return 'Y-m-d H:m:s';
200
        }
201
    }
202
}