Completed
Branch master (c2a41b)
by
unknown
06:28
created

Factory::createQueryParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

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