Completed
Branch master (fea354)
by
unknown
03:14
created

Factory::createQueryParametersParser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
crap 1
1
<?php namespace Neomerx\JsonApi\Factories;
2
3
/**
4
 * Copyright 2015 [email protected] (www.neomerx.com)
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use \Closure;
20
use \Psr\Log\LoggerInterface;
21
use \Neomerx\JsonApi\Document\Link;
22
use \Neomerx\JsonApi\Document\Error;
23
use \Neomerx\JsonApi\Encoder\Encoder;
24
use \Neomerx\JsonApi\Schema\Container;
25
use \Neomerx\JsonApi\Document\Document;
26
use \Neomerx\JsonApi\Codec\CodecMatcher;
27
use \Neomerx\JsonApi\Encoder\Stack\Stack;
28
use \Neomerx\JsonApi\Encoder\Parser\Parser;
29
use \Neomerx\JsonApi\Schema\IdentitySchema;
30
use \Neomerx\JsonApi\Schema\ResourceObject;
31
use \Neomerx\JsonApi\Encoder\EncoderOptions;
32
use \Neomerx\JsonApi\Http\Headers\MediaType;
33
use \Neomerx\JsonApi\Encoder\Stack\StackFrame;
34
use \Neomerx\JsonApi\Http\Headers\AcceptHeader;
35
use \Neomerx\JsonApi\Schema\RelationshipObject;
36
use \Neomerx\JsonApi\Encoder\Parser\ParserReply;
37
use \Neomerx\JsonApi\Encoder\Parser\ParserManager;
38
use \Neomerx\JsonApi\Http\Headers\AcceptMediaType;
39
use \Neomerx\JsonApi\Http\Headers\HeaderParameters;
40
use \Neomerx\JsonApi\Encoder\Parser\ParserEmptyReply;
41
use \Neomerx\JsonApi\Contracts\Document\LinkInterface;
42
use \Neomerx\JsonApi\Encoder\Parameters\SortParameter;
43
use \Neomerx\JsonApi\Http\Headers\SupportedExtensions;
44
use \Neomerx\JsonApi\Http\Query\QueryParametersParser;
45
use \Neomerx\JsonApi\Encoder\Handlers\ReplyInterpreter;
46
use \Neomerx\JsonApi\Http\Query\RestrictiveQueryChecker;
47
use \Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
48
use \Neomerx\JsonApi\Http\Headers\HeaderParametersParser;
49
use \Neomerx\JsonApi\Contracts\Document\DocumentInterface;
50
use \Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
51
use \Neomerx\JsonApi\Contracts\Codec\CodecMatcherInterface;
52
use \Neomerx\JsonApi\Encoder\Parameters\EncodingParameters;
53
use \Neomerx\JsonApi\Encoder\Parameters\ParametersAnalyzer;
54
use \Neomerx\JsonApi\Http\Headers\RestrictiveHeadersChecker;
55
use \Neomerx\JsonApi\Schema\ResourceIdentifierSchemaAdapter;
56
use \Neomerx\JsonApi\Contracts\Http\Headers\HeaderInterface;
57
use \Neomerx\JsonApi\Contracts\Schema\SchemaProviderInterface;
58
use \Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
59
use \Neomerx\JsonApi\Schema\ResourceIdentifierContainerAdapter;
60
use \Neomerx\JsonApi\Contracts\Http\Headers\AcceptHeaderInterface;
61
use \Neomerx\JsonApi\Contracts\Encoder\Stack\StackReadOnlyInterface;
62
use \Neomerx\JsonApi\Contracts\Encoder\Parser\ParserManagerInterface;
63
use \Neomerx\JsonApi\Contracts\Encoder\Stack\StackFrameReadOnlyInterface;
64
use \Neomerx\JsonApi\Contracts\Encoder\Parameters\EncodingParametersInterface;
65
use \Neomerx\JsonApi\Contracts\Encoder\Parameters\ParametersAnalyzerInterface;
66
67
/**
68
 * @package Neomerx\JsonApi
69
 */
70
class Factory implements FactoryInterface
71
{
72
    /**
73
     * @var LoggerInterface
74
     */
75
    protected $logger;
76
77
    /**
78
     * Constructor.
79
     */
80 173
    public function __construct()
81
    {
82 173
        $this->logger = new ProxyLogger();
83 173
    }
84
85
    /**
86
     * @inheritdoc
87
     */
88 2
    public function setLogger(LoggerInterface $logger)
89
    {
90 2
        $this->logger->setLogger($logger);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Psr\Log\LoggerInterface as the method setLogger() does only exist in the following implementations of said interface: Neomerx\JsonApi\Factories\ProxyLogger.

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...
91 2
    }
92
93
    /**
94
     * @inheritdoc
95
     */
96 64
    public function createEncoder(ContainerInterface $container, EncoderOptions $encoderOptions = null)
97
    {
98 64
        $encoder = new Encoder($this, $container, $encoderOptions);
99
100 64
        $encoder->setLogger($this->logger);
101
102 64
        return $encoder;
103
    }
104
105
    /**
106
     * @inheritdoc
107
     */
108 92
    public function createDocument()
109
    {
110 92
        $document = new Document();
111
112 92
        $document->setLogger($this->logger);
113
114 92
        return $document;
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120 3
    public function createError(
121
        $idx = null,
122
        LinkInterface $aboutLink = null,
123
        $status = null,
124
        $code = null,
125
        $title = null,
126
        $detail = null,
127
        $source = null,
128
        array $meta = null
129
    ) {
130 3
        return new Error($idx, $aboutLink, $status, $code, $title, $detail, $source, $meta);
131
    }
132
    /**
133
     * @inheritdoc
134
     */
135 54
    public function createReply($replyType, StackReadOnlyInterface $stack)
136
    {
137 54
        return new ParserReply($replyType, $stack);
138
    }
139
140
    /**
141
     * @inheritdoc
142
     */
143 21
    public function createEmptyReply(
144
        $replyType,
145
        StackReadOnlyInterface $stack
146
    ) {
147 21
        return new ParserEmptyReply($replyType, $stack);
148
    }
149
150
    /**
151
     * @inheritdoc
152
     */
153 60
    public function createParser(ContainerInterface $container, ParserManagerInterface $manager)
154
    {
155 60
        $parser = new Parser($this, $this, $this, $container, $manager);
156
157 60
        $parser->setLogger($this->logger);
158
159 60
        return $parser;
160
    }
161
162
    /**
163
     * @inheritdoc
164
     */
165 58
    public function createManager(ParametersAnalyzerInterface $parameterAnalyzer)
166
    {
167 58
        $manager = new ParserManager($parameterAnalyzer);
168
169 58
        $manager->setLogger($this->logger);
170
171 58
        return $manager;
172
    }
173
174
    /**
175
     * @inheritdoc
176
     */
177 63
    public function createFrame(StackFrameReadOnlyInterface $previous = null)
178
    {
179 63
        return new StackFrame($previous);
180
    }
181
182
    /**
183
     * @inheritdoc
184
     */
185 64
    public function createStack()
186
    {
187 64
        return new Stack($this);
188
    }
189
190
    /**
191
     * @inheritdoc
192
     */
193 58
    public function createReplyInterpreter(DocumentInterface $document, ParametersAnalyzerInterface $parameterAnalyzer)
194
    {
195 58
        $interpreter = new ReplyInterpreter($document, $parameterAnalyzer);
196
197 58
        $interpreter->setLogger($this->logger);
198
199 58
        return $interpreter;
200
    }
201
202
    /**
203
     * @inheritdoc
204
     */
205 61
    public function createParametersAnalyzer(EncodingParametersInterface $parameters, ContainerInterface $container)
206
    {
207 61
        $analyzer = new ParametersAnalyzer($parameters, $container);
208
209 61
        $analyzer->setLogger($this->logger);
210
211 61
        return $analyzer;
212
    }
213
214
    /**
215
     * @inheritdoc
216
     */
217 1
    public function createMediaType($type, $subType, $parameters = null)
218
    {
219 1
        return new MediaType($type, $subType, $parameters);
220
    }
221
222
    /**
223
     * @inheritdoc
224
     */
225 60
    public function createQueryParameters(
226
        $includePaths = null,
227
        array $fieldSets = null,
228
        $sortParameters = null,
229
        array $pagingParameters = null,
230
        array $filteringParameters = null,
231
        array $unrecognizedParams = null
232
    ) {
233 60
        return new EncodingParameters(
234 60
            $includePaths,
235 60
            $fieldSets,
236 60
            $sortParameters,
237 60
            $pagingParameters,
238 60
            $filteringParameters,
239
            $unrecognizedParams
240 60
        );
241
    }
242
243
    /**
244
     * @inheritdoc
245
     */
246 10
    public function createHeaderParameters($method, AcceptHeaderInterface $accept, HeaderInterface $contentType)
247
    {
248 10
        return new HeaderParameters($method, $accept, $contentType);
249
    }
250
251
    /**
252
     * @inheritdoc
253
     */
254 23
    public function createQueryParametersParser()
255
    {
256 23
        $parser = new QueryParametersParser($this);
257
258 23
        $parser->setLogger($this->logger);
259
260 23
        return $parser;
261
    }
262
263
    /**
264
     * @inheritdoc
265
     */
266 12
    public function createHeaderParametersParser()
267
    {
268 12
        $parser = new HeaderParametersParser($this);
269
270 12
        $parser->setLogger($this->logger);
271
272 12
        return $parser;
273
    }
274
275
    /**
276
     * @inheritdoc
277
     */
278 14
    public function createSortParam($sortField, $isAscending)
279
    {
280 14
        return new SortParameter($sortField, $isAscending);
281
    }
282
283
    /**
284
     * @inheritdoc
285
     */
286 1
    public function createSupportedExtensions($extensions = MediaTypeInterface::NO_EXT)
287
    {
288 1
        return new SupportedExtensions($extensions);
289
    }
290
291
    /**
292
     * @inheritdoc
293
     */
294 2
    public function createAcceptMediaType(
295
        $position,
296
        $type,
297
        $subType,
298
        $parameters = null,
299
        $quality = 1.0,
300
        $extensions = null
301
    ) {
302 2
        return new AcceptMediaType($position, $type, $subType, $parameters, $quality, $extensions);
303
    }
304
305
    /**
306
     * @inheritdoc
307
     */
308 2
    public function createAcceptHeader($unsortedMediaTypes)
309
    {
310 2
        return new AcceptHeader($unsortedMediaTypes);
311
    }
312
313
    /**
314
     * @inheritdoc
315
     */
316 6
    public function createHeadersChecker(CodecMatcherInterface $codecMatcher)
317
    {
318 6
        return new RestrictiveHeadersChecker($codecMatcher);
319
    }
320
321
    /**
322
     * @inheritdoc
323
     */
324 12
    public function createQueryChecker(
325
        $allowUnrecognized = true,
326
        array $includePaths = null,
327
        array $fieldSetTypes = null,
328
        array $sortParameters = null,
329
        array $pagingParameters = null,
330
        array $filteringParameters = null
331
    ) {
332 12
        return new RestrictiveQueryChecker(
333 12
            $allowUnrecognized,
334 12
            $includePaths,
335 12
            $fieldSetTypes,
336 12
            $sortParameters,
337 12
            $pagingParameters,
338
            $filteringParameters
339 12
        );
340
    }
341
342
    /**
343
     * @inheritdoc
344
     */
345 77
    public function createContainer(array $providers = [])
346
    {
347 77
        $container = new Container($this, $providers);
348
349 75
        $container->setLogger($this->logger);
350
351 75
        return $container;
352
    }
353
354
    /**
355
     * @inheritdoc
356
     */
357 75
    public function createResourceObject(
358
        SchemaProviderInterface $schema,
359
        $resource,
360
        $isInArray,
361
        $attributeKeysFilter = null
362
    ) {
363 75
        return new ResourceObject($schema, $resource, $isInArray, $attributeKeysFilter);
364
    }
365
366
    /**
367
     * @inheritdoc
368
     */
369 75
    public function createRelationshipObject($name, $data, $links, $meta, $isShowData, $isRoot)
370
    {
371 75
        return new RelationshipObject($name, $data, $links, $meta, $isShowData, $isRoot);
372
    }
373
374
    /**
375
     * @inheritdoc
376
     */
377 52
    public function createLink($subHref, $meta = null, $treatAsHref = false)
378
    {
379 52
        return new Link($subHref, $meta, $treatAsHref);
380
    }
381
382
    /**
383
     * @inheritdoc
384
     */
385 2
    public function createResourceIdentifierSchemaAdapter(SchemaProviderInterface $schema)
386
    {
387 2
        return new ResourceIdentifierSchemaAdapter($this, $schema);
388
    }
389
390
    /**
391
     * @inheritdoc
392
     */
393 2
    public function createResourceIdentifierContainerAdapter(ContainerInterface $container)
394
    {
395 2
        return new ResourceIdentifierContainerAdapter($this, $container);
396
    }
397
398
    /**
399
     * @inheritdoc
400
     */
401 1
    public function createIdentitySchema(ContainerInterface $container, $classType, Closure $identityClosure)
402
    {
403 1
        return new IdentitySchema($this, $container, $classType, $identityClosure);
404
    }
405
406
    /**
407
     * @inheritdoc
408
     */
409 18
    public function createCodecMatcher()
410
    {
411 18
        return new CodecMatcher();
412
    }
413
}
414