Passed
Push — master ( 8d8aff...14bf48 )
by Aleksei
07:24
created

SimpleConverterMatcher::withRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace roxblnfk\SmartStream\Matching;
6
7
use Generator;
8
use Psr\Container\ContainerInterface;
9
use Psr\Http\Message\RequestInterface;
10
use roxblnfk\SmartStream\ConverterInterface;
11
use roxblnfk\SmartStream\ConverterMatcherInterface;
12
use roxblnfk\SmartStream\Data\DataBucket;
13
use roxblnfk\SmartStream\Exception\ConverterNotFoundException;
14
use Yiisoft\Http\Header;
15
16
final class SimpleConverterMatcher implements ConverterMatcherInterface
17
{
18
    private SimpleMatcherConfig $matcherConfig;
19
    private ContainerInterface $container;
20
    private ?RequestInterface $request = null;
21
22
    public function __construct(ContainerInterface $container)
23
    {
24
        $this->container = $container;
25
        $this->matcherConfig = $container->get(SimpleMatcherConfig::class);
26
    }
27
28
    public function match(DataBucket $bucket): ?MatchingResult
29
    {
30
        if (!$bucket->isFormatable()) {
31
            return null;
32
        }
33
34
        # find by format from bucket
35
        # find by bucket class name
36
        $format = $this->getBucketFormat($bucket) ?? $this->getBucketClassFormat($bucket);
37
        if ($format === null) {
38
            return null;
39
        }
40
41
        # multiple formats
42
        if (is_array($format)) {
43
            if (count($format) > 1) {
44
                # find format by headers
45
                $format = $this->compareWithAcceptTypes($format) ?? current($format);
46
            } else {
47
                $format = current($format);
48
            }
49
        }
50
51
        $converter = $this->container->get($this->matcherConfig->getConverter($format));
52
        return new MatchingResult($format, $converter, $this->matcherConfig->getMimeType($format));
53
    }
54
    public function withRequest(?RequestInterface $request): ConverterMatcherInterface
55
    {
56
        $clone = clone $this;
57
        $clone->request = $request;
58
        return $clone;
59
    }
60
61
    private function getBucketFormat(DataBucket $bucket): ?string
62
    {
63
        if ($bucket->hasFormat()) {
64
            $format = $bucket->getFormat();
65
            if (!$this->matcherConfig->hasFormat($format)) {
66
                throw new ConverterNotFoundException($format);
67
            }
68
            return $format;
69
        }
70
        return null;
71
    }
72
    private function getBucketClassFormat(DataBucket $bucket): ?array
73
    {
74
        $className = static function (DataBucket $bucket): Generator {
75
            yield get_class($bucket);
76
            yield from get_parent_class($bucket);
77
        };
78
        $result = [];
79
        foreach ($className($bucket) as $bucketClass) {
80
            if ($this->matcherConfig->hasBucketFormat($bucketClass)) {
81
                $result = array_merge($result, $this->matcherConfig->getBucketFormats($bucketClass));
82
            }
83
        }
84
        return count($result) > 0 ? array_unique($result) : null;
85
    }
86
    /**
87
     * @param string[] $format
88
     * @return null|string
89
     */
90
    private function compareWithAcceptTypes(array $format): ?string
91
    {
92
        return current($format);
93
        # TODO
94
        // $header = $this->request->getHeaderLine(Header::ACCEPT);
95
        // return null;
96
    }
97
}
98