Passed
Pull Request — master (#12)
by Ivo
02:52
created

JSONScalarTypeMapper   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 24
c 1
b 0
f 1
dl 0
loc 78
rs 10
wmc 14

6 Methods

Rating   Name   Duplication   Size   Complexity  
A toGraphQLInputType() 0 11 2
A matchReturnType() 0 6 2
A mapNameToType() 0 6 2
A matchInputType() 0 13 5
A toGraphQLOutputType() 0 10 2
A __construct() 0 3 1
1
<?php
2
3
namespace TheCodingMachine\GraphQLite\Types\JSONScalar;
4
5
use GraphQL\Type\Definition\InputType;
6
use GraphQL\Type\Definition\NamedType;
7
use GraphQL\Type\Definition\OutputType;
8
use phpDocumentor\Reflection\DocBlock;
9
use phpDocumentor\Reflection\Type;
10
use ReflectionMethod;
11
use ReflectionProperty;
12
use TheCodingMachine\GraphQLite\Mappers\Root\RootTypeMapperInterface;
13
14
class JSONScalarTypeMapper implements RootTypeMapperInterface
15
{
16
    /** @var RootTypeMapperInterface */
17
    private $next;
18
19
    public function __construct(RootTypeMapperInterface $next)
20
    {
21
        $this->next = $next;
22
    }
23
24
    public function toGraphQLOutputType(
25
        Type $type,
26
        ?OutputType $subType,
27
        $reflector,
28
        DocBlock $docBlockObj
29
    ): OutputType {
30
        if ($this->matchReturnType($docBlockObj)) {
31
            return JSONScalarType::getInstance();
32
        }
33
        return  $this->next->toGraphQLOutputType($type, $subType, $reflector, $docBlockObj);
34
    }
35
36
    public function toGraphQLInputType(
37
        Type $type,
38
        ?InputType $subType,
39
        string $argumentName,
40
        $reflector,
41
        DocBlock $docBlockObj
42
    ): InputType {
43
        if ($this->matchInputType($argumentName, $reflector, $docBlockObj)) {
44
            return JSONScalarType::getInstance();
45
        }
46
        return $this->next->toGraphQLInputType($type, $subType, $argumentName, $reflector, $docBlockObj);
47
    }
48
49
    /**
50
     * @param string $typeName The name of the GraphQL type
51
     * @return NamedType
52
     */
53
    public function mapNameToType(string $typeName): NamedType
54
    {
55
        if ($typeName === JSONScalarType::NAME) {
56
            return JSONScalarType::getInstance();
57
        }
58
        return $this->next->mapNameToType($typeName);
59
    }
60
61
    /**
62
     * @param DocBlock $docBlockObj
63
     * @return bool
64
     */
65
    private function matchReturnType(DocBlock $docBlockObj): bool
66
    {
67
        $paramText = $docBlockObj->hasTag('return') ?
68
            $docBlockObj->getTagsByName('return')[0]->__toString() :
69
            null;
70
        return strpos($paramText, JSONScalarType::NAME) > 0;
0 ignored issues
show
Bug introduced by
It seems like $paramText can also be of type null; however, parameter $haystack of strpos() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
        return strpos(/** @scrutinizer ignore-type */ $paramText, JSONScalarType::NAME) > 0;
Loading history...
71
    }
72
73
    /**
74
     * @param string $argumentName
75
     * @param ReflectionMethod|ReflectionProperty $reflector
76
     * @param DocBlock $docBlockObj
77
     * @return bool
78
     */
79
    private function matchInputType(string $argumentName, $reflector, DocBlock $docBlockObj): bool
80
    {
81
        $params = $docBlockObj->getTagsByName('param');
82
        for ($i = 0; $i < count($params); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
83
            $paramText = $params[$i]->__toString();
84
            if ($reflector instanceof ReflectionMethod) {
85
                $refParams = $reflector->getParameters();
86
                if (strpos($paramText, JSONScalarType::NAME) > 0 && $refParams[$i]->getName() === $argumentName) {
87
                    return true;
88
                }
89
            }
90
        }
91
        return false;
92
    }
93
}
94