Completed
Pull Request — master (#126)
by
unknown
03:19
created

NestedInnerHit::getPathType()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 3
eloc 11
nc 3
nop 0
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\ElasticsearchDSL\InnerHit;
13
14
use ONGR\ElasticsearchDSL\BuilderBag;
15
use ONGR\ElasticsearchDSL\BuilderInterface;
16
use ONGR\ElasticsearchDSL\NameAwareTrait;
17
use ONGR\ElasticsearchDSL\ParametersTrait;
18
19
/**
20
 * Represents Elasticsearch top level nested inner hits.
21
 *
22
 * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-inner-hits.html
23
 */
24
class NestedInnerHit implements BuilderInterface
25
{
26
    use ParametersTrait;
27
    use NameAwareTrait;
28
29
    /**
30
     * @var string
31
     */
32
    private $path;
33
34
    /**
35
     * @var BuilderInterface
36
     */
37
    private $query;
38
39
    /**
40
     * @var BuilderBag
41
     */
42
    private $innerHits;
43
44
    /**
45
     * Inner hits container init.
46
     *
47
     * @param string           $name
48
     * @param string           $path
49
     * @param BuilderInterface $query
50
     */
51
    public function __construct($name, $path, BuilderInterface $query)
52
    {
53
        $this->setName($name);
54
        $this->setPath($path);
55
        $this->setQuery($query);
56
    }
57
58
    /**
59
     * @return string
60
     */
61
    public function getPath()
62
    {
63
        return $this->path;
64
    }
65
66
    /**
67
     * @param string $path
68
     */
69
    public function setPath($path)
70
    {
71
        $this->path = $path;
72
    }
73
74
    /**
75
     * @return BuilderInterface
76
     */
77
    public function getQuery()
78
    {
79
        return $this->query;
80
    }
81
82
    /**
83
     * @param BuilderInterface $query
84
     */
85
    public function setQuery(BuilderInterface $query)
86
    {
87
        $this->query = $query;
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function getType()
94
    {
95
        return 'nested';
96
    }
97
98
    /**
99
     * Adds a sub-innerHit.
100
     *
101
     * @param NestedInnerHit $innerHit
102
     */
103
    public function addInnerHit(NestedInnerHit $innerHit)
104
    {
105
        if (!$this->innerHits) {
106
            $this->innerHits = new BuilderBag();
107
        }
108
109
        $this->innerHits->add($innerHit);
110
    }
111
112
    /**
113
     * Returns all sub inner hits.
114
     *
115
     * @return BuilderInterface[]
116
     */
117
    public function getInnerHits()
118
    {
119
        if ($this->innerHits) {
120
            return $this->innerHits->all();
121
        } else {
122
            return [];
123
        }
124
    }
125
126
    /**
127
     * Returns sub inner hit.
128
     * @param string $name inner hit name to return.
129
     *
130
     * @return NestedInnerHit|null
131
     */
132
    public function getInnerHit($name)
133
    {
134
        if ($this->innerHits && $this->innerHits->has($name)) {
135
            return $this->innerHits->get($name);
136
        } else {
137
            return null;
138
        }
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144
    public function toArray()
145
    {
146
        $out = array_filter(
147
            [
148
                'query' => $this->getQuery()->toArray(),
149
                'inner_hits' => $this->collectNestedInnerHits(),
150
            ]
151
        );
152
153
        $out = [
154
            $this->getPathType() => [
155
                $this->getPath() => $this->processArray($out),
156
            ],
157
        ];
158
159
        return $out;
160
    }
161
162
    /**
163
     * Returns 'path' for neted and 'type' for parent inner hits
164
     *
165
     * @return null|string
166
     */
167
    private function getPathType()
168
    {
169
        switch ($this->getType()) {
170
            case 'nested':
171
                $type = 'path';
172
                break;
173
            case 'parent':
174
                $type = 'type';
175
                break;
176
            default:
177
                $type = null;
178
        }
179
        return $type;
180
    }
181
182
    /**
183
     * Process all nested inner hits.
184
     *
185
     * @return array
186
     */
187
    private function collectNestedInnerHits()
188
    {
189
        $result = [];
190
        /** @var NestedInnerHit $innerHit */
191
        foreach ($this->getInnerHits() as $innerHit) {
192
            $result[$innerHit->getName()] = $innerHit->toArray();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ONGR\ElasticsearchDSL\BuilderInterface as the method getName() does only exist in the following implementations of said interface: ONGR\ElasticsearchDSL\Ag...ion\AbstractAggregation, ONGR\ElasticsearchDSL\Aggregation\AvgAggregation, ONGR\ElasticsearchDSL\Ag...\CardinalityAggregation, ONGR\ElasticsearchDSL\Ag...ion\ChildrenAggregation, ONGR\ElasticsearchDSL\Ag...ateHistogramAggregation, ONGR\ElasticsearchDSL\Ag...on\DateRangeAggregation, ONGR\ElasticsearchDSL\Ag...xtendedStatsAggregation, ONGR\ElasticsearchDSL\Ag...ation\FilterAggregation, ONGR\ElasticsearchDSL\Ag...tion\FiltersAggregation, ONGR\ElasticsearchDSL\Ag...on\GeoBoundsAggregation, ONGR\ElasticsearchDSL\Ag...\GeoDistanceAggregation, ONGR\ElasticsearchDSL\Ag...\GeoHashGridAggregation, ONGR\ElasticsearchDSL\Ag...ation\GlobalAggregation, ONGR\ElasticsearchDSL\Ag...on\HistogramAggregation, ONGR\ElasticsearchDSL\Ag...on\Ipv4RangeAggregation, ONGR\ElasticsearchDSL\Aggregation\MaxAggregation, ONGR\ElasticsearchDSL\Aggregation\MinAggregation, ONGR\ElasticsearchDSL\Ag...tion\MissingAggregation, ONGR\ElasticsearchDSL\Ag...ation\NestedAggregation, ONGR\ElasticsearchDSL\Ag...centileRanksAggregation, ONGR\ElasticsearchDSL\Ag...\PercentilesAggregation, ONGR\ElasticsearchDSL\Ag...ractPipelineAggregation, ONGR\ElasticsearchDSL\Ag...ne\AvgBucketAggregation, ONGR\ElasticsearchDSL\Aggregation\RangeAggregation, ONGR\ElasticsearchDSL\Ag...everseNestedAggregation, ONGR\ElasticsearchDSL\Ag...ificantTermsAggregation, ONGR\ElasticsearchDSL\Aggregation\StatsAggregation, ONGR\ElasticsearchDSL\Aggregation\SumAggregation, ONGR\ElasticsearchDSL\Aggregation\TermsAggregation, ONGR\ElasticsearchDSL\Ag...tion\TopHitsAggregation, ONGR\ElasticsearchDSL\Ag...n\ValueCountAggregation, ONGR\ElasticsearchDSL\InnerHit\NestedInnerHit, ONGR\ElasticsearchDSL\Suggest\CompletionSuggest, ONGR\ElasticsearchDSL\Suggest\Suggest, ONGR\ElasticsearchDSL\Suggest\TermSuggest.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
193
        }
194
195
        return $result;
196
    }
197
}
198