GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#56)
by Marc
02:53
created

JobComparisonBusinessCase::isEqualInterval()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
crap 1
1
<?php
2
/**
3
 * @package: chapi
4
 *
5
 * @author:  msiebeneicher
6
 * @since:   2015-07-29
7
 *
8
 */
9
10
namespace Chapi\BusinessCase\Comparison;
11
12
use Chapi\Component\Comparison\DiffCompareInterface;
13
use Chapi\Component\DatePeriod\DatePeriodFactoryInterface;
14
use Chapi\Entity\Chronos\JobCollection;
15
use Chapi\Entity\Chronos\JobEntity;
16
use Chapi\Service\JobRepository\JobRepositoryInterface;
17
use Psr\Log\LoggerInterface;
18
19
class JobComparisonBusinessCase implements JobComparisonInterface
20
{
21
    /**
22
     * @var JobRepositoryInterface
23
     */
24
    private $oJobRepositoryLocal;
25
26
    /**
27
     * @var JobRepositoryInterface
28
     */
29
    private $oJobRepositoryChronos;
30
31
    /**
32
     * @var DiffCompareInterface
33
     */
34
    private $oDiffCompare;
35
36
    /**
37
     * @var DatePeriodFactoryInterface
38
     */
39
    private $oDatePeriodFactory;
40
41
    /**
42
     * @var LoggerInterface
43
     */
44
    private $oLogger;
45
46
47
    /**
48
     * @param JobRepositoryInterface $oJobRepositoryLocal
49
     * @param JobRepositoryInterface $oJobRepositoryChronos
50
     * @param DiffCompareInterface $oDiffCompare
51
     * @param DatePeriodFactoryInterface $oDatePeriodFactory
52
     * @param LoggerInterface $oLogger
53
     */
54 5
    public function __construct(
55
        JobRepositoryInterface $oJobRepositoryLocal,
56
        JobRepositoryInterface $oJobRepositoryChronos,
57
        DiffCompareInterface $oDiffCompare,
58
        DatePeriodFactoryInterface $oDatePeriodFactory,
59
        LoggerInterface $oLogger
60
    )
61
    {
62 5
        $this->oJobRepositoryLocal = $oJobRepositoryLocal;
63 5
        $this->oJobRepositoryChronos = $oJobRepositoryChronos;
64 5
        $this->oDiffCompare = $oDiffCompare;
65 5
        $this->oDatePeriodFactory = $oDatePeriodFactory;
66 5
        $this->oLogger = $oLogger;
67 5
    }
68
69
    /**
70
     * @return string[]
0 ignored issues
show
Documentation introduced by
Should the return type not be array<integer|string>?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
71
     */
72
    public function getLocalMissingJobs()
73
    {
74
        return $this->getMissingJobsInCollectionA(
75
            $this->oJobRepositoryLocal->getJobs(),
76
            $this->oJobRepositoryChronos->getJobs()
77
        );
78
    }
79
80
    /**
81
     * @return string[]
0 ignored issues
show
Documentation introduced by
Should the return type not be array<integer|string>?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
82
     */
83
    public function getChronosMissingJobs()
84
    {
85
        return $this->getMissingJobsInCollectionA(
86
            $this->oJobRepositoryChronos->getJobs(),
87
            $this->oJobRepositoryLocal->getJobs()
88
        );
89
    }
90
91
    /**
92
     * @return string[]
93
     */
94 3
    public function getLocalJobUpdates()
95
    {
96 3
        $_aJobsLocal = $this->oJobRepositoryLocal->getJobs();
97 3
        $_aLocalJobUpdates = [];
98
99
        /** @var JobEntity $_oJobEntity */
100 3
        foreach ($_aJobsLocal as $_oJobEntityLocal)
101
        {
102 3
            $_oJobEntityChronos = $this->oJobRepositoryChronos->getJob($_oJobEntityLocal->name);
103
104
            // if job already exist in chronos (not new or deleted in chronos)
105 3
            if (!empty($_oJobEntityChronos->name))
106 3
            {
107 3
                $_aNonidenticalProperties = $this->compareJobEntities($_oJobEntityLocal, $_oJobEntityChronos);
108 3
                if (!empty($_aNonidenticalProperties))
109 3
                {
110 3
                    $_aLocalJobUpdates[] = $_oJobEntityLocal->name;
111 3
                }
112 3
            }
113 3
        }
114
115 3
        return $_aLocalJobUpdates;
116
    }
117
118
    /**
119
     * @param string $sJobName
120
     * @return string[]
121
     */
122
    public function getJobDiff($sJobName)
123
    {
124
        $_aReturn = [];
125
126
        $_oJobEntityLocal = $this->oJobRepositoryLocal->getJob($sJobName);
127
        $_oJobEntityChronos = $this->oJobRepositoryChronos->getJob($sJobName);
128
129
        $_aNonidenticalProperties = $this->compareJobEntities(
130
            $_oJobEntityLocal,
131
            $_oJobEntityChronos
132
        );
133
134
        foreach ($_aNonidenticalProperties as $_sProperty)
135
        {
136
            $_aReturn[$_sProperty] = $this->oDiffCompare->compare(
137
                $_oJobEntityChronos->{$_sProperty},
138
                $_oJobEntityLocal->{$_sProperty}
139
            );
140
        }
141
142
        return $_aReturn;
143
    }
144
145
    /**
146
     * @param JobEntity $oJobEntityA
147
     * @param JobEntity $oJobEntityB
148
     * @return bool
149
     */
150 2
    public function hasSameJobType(JobEntity $oJobEntityA, JobEntity $oJobEntityB)
151
    {
152
        return (
153 2
            ($oJobEntityA->isSchedulingJob() && $oJobEntityB->isSchedulingJob())
154 2
            || ($oJobEntityA->isDependencyJob() && $oJobEntityB->isDependencyJob())
155 2
        );
156
    }
157
158
    /**
159
     * @param JobEntity $oJobEntityA
160
     * @param JobEntity $oJobEntityB
161
     * @return array
162
     */
163 3
    private function compareJobEntities(JobEntity $oJobEntityA, JobEntity $oJobEntityB)
164
    {
165 3
        $_aNonidenticalProperties = [];
166
167 3
        $_aDiff = array_merge(
168 3
            array_diff_assoc(
169 3
                $oJobEntityA->getSimpleArrayCopy(),
170 3
                $oJobEntityB->getSimpleArrayCopy()
171 3
            ),
172 3
            array_diff_assoc(
173 3
                $oJobEntityB->getSimpleArrayCopy(),
174 3
                $oJobEntityA->getSimpleArrayCopy()
175 3
            )
176 3
        );
177
178 3
        if (count($_aDiff) > 0)
179 3
        {
180 3
            $_aDiffKeys = array_keys($_aDiff);
181 3
            foreach ($_aDiffKeys as $_sDiffKey)
182
            {
183 3
                if (!$this->isJobEntityValueIdentical($_sDiffKey, $oJobEntityA, $oJobEntityB))
184 3
                {
185 3
                    $_aNonidenticalProperties[] = $_sDiffKey;
186 3
                }
187 3
            }
188 3
        }
189
190 3
        return $_aNonidenticalProperties;
191
    }
192
193
    /**
194
     * @param string $sProperty
195
     * @param JobEntity $oJobEntityA
196
     * @param JobEntity $oJobEntityB
197
     * @return bool
198
     */
199 3
    private function isJobEntityValueIdentical($sProperty, JobEntity $oJobEntityA, JobEntity $oJobEntityB)
200
    {
201 3
        $mValueA = $oJobEntityA->{$sProperty};
202 3
        $mValueB = $oJobEntityB->{$sProperty};
203
204
        switch ($sProperty)
205
        {
206 3
            case 'schedule':
207 1
                return $this->isSchedulePropertyIdentical($oJobEntityA, $oJobEntityB);
208
209 3
            case 'scheduleTimeZone':
210 1
                return $this->isScheduleTimeZonePropertyIdentical($oJobEntityA, $oJobEntityB);
211
212 2
            case 'parents':
213
                return (
214
                    is_array($mValueA)
215
                    && is_array($mValueB)
216
                    && count(array_diff($mValueA, $mValueB)) == 0
217
                    && count(array_diff($mValueB, $mValueA)) == 0
218
                );
219
220 2
            case 'successCount':
221 2
            case 'lastSuccess':
222 2
            case 'errorCount':
223 2
            case 'errorsSinceLastSuccess':
224 2
            case 'lastError':
225
                return true;
226
227 2
            default:
228 2
                return ($mValueA == $mValueB);
229 2
        }
230
    }
231
232
    /**
233
     * @param JobEntity $oJobEntityA
234
     * @param JobEntity $oJobEntityB
235
     * @return bool
236
     */
237 1
    private function isScheduleTimeZonePropertyIdentical(JobEntity $oJobEntityA, JobEntity $oJobEntityB)
238
    {
239 1
        if ($oJobEntityA->scheduleTimeZone == $oJobEntityB->scheduleTimeZone)
240 1
        {
241
            return true;
242
        }
243
244 1
        if (!empty($oJobEntityA->schedule) && !empty($oJobEntityB->schedule))
245 1
        {
246 1
            $_oDateA = $this->createDateTimeObj($oJobEntityA->schedule, $oJobEntityA->scheduleTimeZone);
247 1
            $_oDateB = $this->createDateTimeObj($oJobEntityB->schedule, $oJobEntityB->scheduleTimeZone);
248
249 1
            return ($_oDateA->getOffset() == $_oDateB->getOffset());
250
        }
251
252
        return false;
253
    }
254
255
    /**
256
     * @param JobEntity $oJobEntityA
257
     * @param JobEntity $oJobEntityB
258
     * @return bool
259
     */
260 1
    private function isSchedulePropertyIdentical(JobEntity $oJobEntityA, JobEntity $oJobEntityB)
261
    {
262
        // if values are exact the same
263 1
        if ($oJobEntityA->schedule === $oJobEntityB->schedule)
264 1
        {
265
            $this->oLogger->debug(sprintf('%s::EXCACT INTERVAL FOR "%s"', 'ScheduleComparison', $oJobEntityA->name));
266
            return true;
267
        }
268
269
        // if one value is empty and not both, compare the time periods
270 1
        if (!empty($oJobEntityA->schedule) && !empty($oJobEntityB->schedule))
271 1
        {
272 1
            $_oIso8601EntityA = $this->oDatePeriodFactory->createIso8601Entity($oJobEntityA->schedule);
273 1
            $_oIso8601EntityB = $this->oDatePeriodFactory->createIso8601Entity($oJobEntityB->schedule);
274
275
            // if the clean interval is different return directly false (P1D != P1M)
276 1
            if ($_oIso8601EntityA->sInterval != $_oIso8601EntityB->sInterval)
277 1
            {
278 1
                $this->oLogger->debug(sprintf('%s::DIFFERENT INTERVAL FOR "%s"', 'ScheduleComparison', $oJobEntityA->name));
279 1
                return false;
280
            }
281
282
            // else if the interval is <= 1Min return directly true (performance)
283 1
            if ($_oIso8601EntityA->sInterval == 'PT1M' || $_oIso8601EntityA->sInterval == 'PT1S')
284 1
            {
285 1
                $this->oLogger->debug(sprintf('%s::PT1M|PT1S INTERVAL FOR "%s" - Job execution should be equal', 'ScheduleComparison', $oJobEntityA->name));
286 1
                return true;
287
            }
288
289
            // start to check by DatePeriods
290 1
            $_oLastDateTimeA = null;
291 1
            $_oLastDateTimeB = null;
292
293
            /** @var \DatePeriod $_oPeriodB */
294 1
            $_oPeriodA = $this->oDatePeriodFactory->createDatePeriod($oJobEntityA->schedule, $oJobEntityA->scheduleTimeZone);
295
296
            /** @var \DateTime $_oDateTime */
297 1
            foreach ($_oPeriodA as $_oDateTime) {
298 1
                $_oLastDateTimeA = $_oDateTime;
299 1
            }
300
301
            /** @var \DatePeriod $_oPeriodB */
302 1
            $_oPeriodB = $this->oDatePeriodFactory->createDatePeriod($oJobEntityB->schedule, $oJobEntityB->scheduleTimeZone);
303
304
            /** @var \DateTime $_oDateTime */
305 1
            foreach ($_oPeriodB as $_oDateTime) {
306 1
                $_oLastDateTimeB = $_oDateTime;
307 1
            }
308
309
            // $_oLastDateTimeA !== false happen if no dates are in the period
310 1
            if ($_oLastDateTimeA !== null && $_oLastDateTimeB !== null)
311 1
            {
312 1
                $_oDiffInterval = $_oLastDateTimeA->diff($_oLastDateTimeB);
313 1
                $_iDiffInterval = (int) $_oDiffInterval->format('%Y%M%D%H%I');
314
315 1
                $this->oLogger->debug(sprintf('%s::INTERVAL DIFF OF "%d" FOR "%s"', 'ScheduleComparison', $_iDiffInterval, $oJobEntityA->name));
316
317 1
                return ($_iDiffInterval == 0);
318
            }
319
        }
320
321
        $this->oLogger->warning(sprintf('%s::CAN\'T COMPARE INTERVAL FOR "%s"', 'ScheduleComparison', $oJobEntityA->name));
322
        return false;
323
    }
324
325
    /**
326
     * @param string $sIso8601String
327
     * @param string $sTimeZone
328
     * @return \DateTime
329
     */
330 1
    private function createDateTimeObj($sIso8601String, $sTimeZone = '')
331
    {
332 1
        $_oIso8601Entity = $this->oDatePeriodFactory->createIso8601Entity($sIso8601String);
333
334 1 View Code Duplication
        if (!empty($sTimeZone))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
335 1
        {
336 1
            $_oDateTime = new \DateTime(str_replace('Z', '', $_oIso8601Entity->sStartTime));
337 1
            $_oDateTime->setTimezone(new \DateTimeZone($sTimeZone));
338 1
        }
339
        else
340
        {
341 1
            $_oDateTime = new \DateTime($_oIso8601Entity->sStartTime);
342
        }
343
344 1
        return $_oDateTime;
345
    }
346
347
    /**
348
     * @param JobCollection $oJobCollectionA
349
     * @param JobCollection $oJobCollectionB
350
     * @return string[]
0 ignored issues
show
Documentation introduced by
Should the return type not be array<integer|string>?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
351
     */
352
    private function getMissingJobsInCollectionA(JobCollection $oJobCollectionA, JobCollection $oJobCollectionB)
353
    {
354
        return array_diff(
355
            array_keys($oJobCollectionB->getArrayCopy()),
356
            array_keys($oJobCollectionA->getArrayCopy())
357
        );
358
    }
359
}