Completed
Push — 2.1 ( d71b25...b2264f )
by Rafał
08:50
created

isArticleMetadataMatchingCriteria()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.0444
c 0
b 0
f 0
cc 6
nc 5
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Core Bundle.
7
 *
8
 * Copyright 2016 Sourcefabric z.ú. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2016 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\CoreBundle\Matcher;
18
19
use SWP\Bundle\ContentBundle\Model\ArticleInterface;
20
use SWP\Component\Common\Criteria\Criteria;
21
22
final class ArticleCriteriaMatcher implements ArticleCriteriaMatcherInterface
23
{
24
    public function match(ArticleInterface $article, Criteria $criteria)
25
    {
26
        if (0 === $criteria->count()) {
27
            return false;
28
        }
29
30
        if ($criteria->has('route')) {
31
            foreach ($criteria->get('route') as $value) {
32
                if (null !== $article->getRoute() && (int) $value !== $article->getRoute()->getId()) {
33
                    return false;
34
                }
35
            }
36
        }
37
38
        if ($criteria->has('author') && is_array($criteria->get('author'))) {
39
            foreach ($criteria->get('author') as $key => $value) {
40
                if ($value !== $article->getMetadataByKey('byline')) {
41
                    return false;
42
                }
43
            }
44
        }
45
46
        if ($criteria->has('publishedBefore')) {
47
            $publishedBefore = new \DateTime($criteria->get('publishedBefore'));
48
            if ($article->getPublishedAt() > $publishedBefore) {
49
                return false;
50
            }
51
        }
52
53
        if ($criteria->has('publishedAfter')) {
54
            $publishedAfter = new \DateTime($criteria->get('publishedAfter'));
55
            if ($article->getPublishedAt() < $publishedAfter) {
56
                return false;
57
            }
58
        }
59
60
        if ($criteria->has('publishedAt')
61
            && (!$criteria->has('publishedBefore') || !$criteria->has('publishedAfter'))) {
62
            $publishedAt = new \DateTime($criteria->get('publishedAt'));
63
            if ($publishedAt->format('d-m-Y') !== $article->getPublishedAt()->format('d-m-Y')) {
64
                return false;
65
            }
66
        }
67
68
        if ($criteria->has('metadata') && !empty($criteria->get('metadata'))) {
69
            $criteriaMetadata = $criteria->get('metadata');
70
71
            if (!is_array($criteriaMetadata)) {
72
                return false;
73
            }
74
75
            if ($this->isArticleMetadataMatchingCriteria($criteriaMetadata, $article)) {
76
                return true;
77
            }
78
79
            return false;
80
        }
81
82
        return true;
83
    }
84
85
    private function isArticleMetadataMatchingCriteria(array $criteriaMetadata, ArticleInterface $article): bool
86
    {
87
        foreach ($criteriaMetadata as $key => $criteriaMetadataItem) {
88
            $articleMetadataByKey = $article->getMetadataByKey($key);
89
90
            if (is_array($articleMetadataByKey)) {
91
                foreach ($articleMetadataByKey as $articleMetadataItem) {
92
                    if ($this->isMetadataMatching($articleMetadataItem, $criteriaMetadataItem)) {
93
                        return true;
94
                    }
95
                }
96
            } elseif ($criteriaMetadataItem === $articleMetadataByKey) {
97
                return true;
98
            }
99
        }
100
101
        return false;
102
    }
103
104
    private function isMetadataMatching(array $articleMetadataItem, array $criteriaMetadata): bool
105
    {
106
        foreach ($criteriaMetadata as $criteriaMetadataItem) {
107
            if (!isset($articleMetadataItem['code'], $criteriaMetadataItem['code'])) {
108
                continue;
109
            }
110
111
            if ($this->isSubjectMatching($articleMetadataItem, $criteriaMetadataItem)) {
112
                return true;
113
            }
114
115
            if ($articleMetadataItem['code'] === $criteriaMetadataItem['code']) {
116
                return true;
117
            }
118
        }
119
120
        return false;
121
    }
122
123
    private function isSubjectMatching(array $articleMetadataItem, array $criteriaMetadataItem): bool
124
    {
125
        return isset($articleMetadataItem['scheme'], $criteriaMetadataItem['scheme']) &&
126
            $articleMetadataItem['code'] === $criteriaMetadataItem['code'] &&
127
            $articleMetadataItem['scheme'] === $criteriaMetadataItem['scheme']
128
        ;
129
    }
130
}
131