mustHaveLengthBetween()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 5
1
<?php
2
declare(strict_types = 1);
3
4
namespace AmmitPhp\Ammit\UI\Resolver\Validator;
5
6
use AmmitPhp\Ammit\UI\Resolver\Exception\CommandMappingException;
7
use Psr\Http\Message\ServerRequestInterface;
8
9
/**
10
 * @internal Contains Domain Validation assertions (but class won't be removed in next version)
11
 *   Domain Validation should be done in Domain
12
 *   Should be used for prototyping project knowing you are accumulating technical debt
13
 */
14
class PragmaticRequestQueryStringValueValidator extends RequestQueryStringValueValidator
15
{
16
    /** @var RawValueValidator */
17
    protected $rawValueValidator;
18
19
    public function __construct(PragmaticRawValueValidator $rawValueValidator)
20
    {
21
        $this->rawValueValidator = $rawValueValidator;
22
    }
23
24
    /**
25
     * Domain should be responsible for id format
26
     * Exceptions are caught in order to be processed later
27
     *
28
     * @throws CommandMappingException If any mapping validation failed
29
     */
30
    public function mustBeUuid(ServerRequestInterface $request, string $queryStringKey, string $exceptionMessage = null): string
31
    {
32
        $value = $this->extractValueFromRequestQueryString($request, $queryStringKey);
33
34
        return $this->rawValueValidator->mustBeUuid(
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator as the method mustBeUuid() does only exist in the following sub-classes of AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator: AmmitPhp\Ammit\UI\Resolv...gmaticRawValueValidator. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
35
            $value,
36
            $queryStringKey,
37
            $this,
38
            $exceptionMessage
39
        );
40
    }
41
42
    /**
43
     * Domain should be responsible for legit values
44
     * Exceptions are caught in order to be processed later
45
     *
46
     * @throws CommandMappingException If any mapping validation failed
47
     * @return mixed Untouched value
48
     */
49
    public function mustBeInArray(ServerRequestInterface $request, array $availableValues, string $queryStringKey, string $exceptionMessage = null)
50
    {
51
        $value = $this->extractValueFromRequestQueryString($request, $queryStringKey);
52
53
        return $this->rawValueValidator->mustBeInArray(
0 ignored issues
show
Bug introduced by
The method mustBeInArray() does not exist on AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator. Did you maybe mean mustBeArray()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
54
            $value,
55
            $availableValues,
56
            $queryStringKey,
57
            $this,
58
            $exceptionMessage
59
        );
60
    }
61
62
    /**
63
     * Domain should be responsible for string emptiness
64
     * Exceptions are caught in order to be processed later
65
     *
66
     * @throws CommandMappingException If any mapping validation failed
67
     * @return mixed Untouched value
68
     */
69
    public function mustBeStringNotEmpty(ServerRequestInterface $request, string $queryStringKey, string $exceptionMessage = null)
70
    {
71
        $value = $this->extractValueFromRequestQueryString($request, $queryStringKey);
72
73
        return $this->rawValueValidator->mustBeStringNotEmpty(
0 ignored issues
show
Bug introduced by
The method mustBeStringNotEmpty() does not exist on AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator. Did you maybe mean mustBeString()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
74
            $value,
75
            $queryStringKey,
76
            $this,
77
            $exceptionMessage
78
        );
79
    }
80
81
    /**
82
     * Domain should be responsible for id format
83
     * Exceptions are caught in order to be processed later
84
     *
85
     * @throws CommandMappingException If any mapping validation failed
86
     * @return mixed Untouched value
87
     */
88
    public function mustHaveLengthBetween(ServerRequestInterface $request, string $queryStringKey, int $min, int $max, string $exceptionMessage = null)
89
    {
90
        $value = $this->extractValueFromRequestQueryString($request, $queryStringKey);
91
92
        return $this->rawValueValidator->mustHaveLengthBetween(
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator as the method mustHaveLengthBetween() does only exist in the following sub-classes of AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator: AmmitPhp\Ammit\UI\Resolv...gmaticRawValueValidator. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
93
            $value,
94
            $min,
95
            $max,
96
            $queryStringKey,
97
            $this,
98
            $exceptionMessage
99
        );
100
    }
101
102
    /**
103
     * Domain should be responsible for email format
104
     * Exceptions are caught in order to be processed later
105
     *
106
     * @throws CommandMappingException If any mapping validation failed
107
     * @return mixed Untouched value
108
     */
109
    public function mustBeEmailAddress(ServerRequestInterface $request, string $queryStringKey, string $exceptionMessage = null)
110
    {
111
        $value = $this->extractValueFromRequestQueryString($request, $queryStringKey);
112
113
        return $this->rawValueValidator->mustBeEmailAddress(
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator as the method mustBeEmailAddress() does only exist in the following sub-classes of AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator: AmmitPhp\Ammit\UI\Resolv...gmaticRawValueValidator. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
114
            $value,
115
            $queryStringKey,
116
            $this,
117
            $exceptionMessage
118
        );
119
    }
120
121
    /**
122
     * Domain should be responsible for regex validation
123
     * Exceptions are caught in order to be processed later
124
     *
125
     * @throws CommandMappingException If any mapping validation failed
126
     * @return mixed Untouched value
127
     */
128
    public function mustBeValidAgainstRegex(ServerRequestInterface $request, string $pattern, string $queryStringKey, string $exceptionMessage = null)
129
    {
130
        $value = $this->extractValueFromRequestQueryString($request, $queryStringKey);
131
132
        return $this->rawValueValidator->mustBeValidAgainstRegex(
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator as the method mustBeValidAgainstRegex() does only exist in the following sub-classes of AmmitPhp\Ammit\UI\Resolv...dator\RawValueValidator: AmmitPhp\Ammit\UI\Resolv...gmaticRawValueValidator. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
133
            $value,
134
            $pattern,
135
            $queryStringKey,
136
            $this,
137
            $exceptionMessage
138
        );
139
    }
140
141
    /**
142
     * Exceptions are caught in order to be processed later
143
     *
144
     * @throws CommandMappingException If any mapping validation failed
145
     * @return int|null
146
     */
147 View Code Duplication
    public function mustBeIntegerOrEmpty(ServerRequestInterface $request, string $attributeKey, string $exceptionMessage = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
148
    {
149
        $value = $this->extractValueFromRequestQueryString($request, $attributeKey);
150
151
        return $this->rawValueValidator->mustBeIntegerOrEmpty(
152
            $value,
153
            $attributeKey,
154
            $this,
155
            $exceptionMessage
156
        );
157
    }
158
}
159