Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Completed
Push — 2.0 ( e6a123 )
by Henrique
05:00
created

Domain::collectAssertException()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 5
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 3
crap 6
1
<?php
2
3
/*
4
 * This file is part of Respect/Validation.
5
 *
6
 * (c) Alexandre Gomes Gaigalas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the "LICENSE.md"
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Respect\Validation\Rules;
13
14
use Respect\Validation\Exceptions\ValidationException;
15
16
class Domain extends AbstractComposite
17
{
18
    protected $tld;
19
    protected $checks = [];
20
    protected $otherParts;
21
22
    public function __construct($tldCheck = true)
23
    {
24
        $this->checks[] = new NoWhitespace();
25
        $this->checks[] = new Contains('.');
26
        $this->checks[] = new Length(3, null);
27
        $this->tldCheck($tldCheck);
28
        $this->otherParts = new AllOf(
29
            new Alnum('-'),
30
            new Not(new StartsWith('-')),
31
            new OneOf(
32
                new Not(
33
                    new Contains('--')
34
                ),
35
                new AllOf(
36
                    new StartsWith('xn--'),
37
                    new Callback(function ($str) {
38
                        return mb_substr_count($str, '--') == 1;
39
                    })
40
                )
41
            )
42
        );
43
    }
44
45
    public function tldCheck($do = true)
46
    {
47
        if ($do === true) {
48
            $this->tld = new Tld();
49
        } else {
50
            $this->tld = new AllOf(
51
                new Not(
52
                    new StartsWith('-')
53
                ),
54
                new NoWhitespace(),
55
                new Length(2, null)
56
            );
57
        }
58
59
        return true;
60
    }
61
62
    public function validate($input)
63
    {
64
        foreach ($this->checks as $chk) {
65
            if (!$chk->validate($input)) {
66
                return false;
67
            }
68
        }
69
70
        if (count($parts = explode('.', $input)) < 2
71
            || !$this->tld->validate(array_pop($parts))) {
72
            return false;
73
        }
74
75
        foreach ($parts as $p) {
76
            if (!$this->otherParts->validate($p)) {
77
                return false;
78
            }
79
        }
80
81
        return true;
82
    }
83
84
    public function assert($input)
85
    {
86
        $e = [];
87
        foreach ($this->checks as $chk) {
88
            $this->collectAssertException($e, $chk, $input);
89
        }
90
91
        if (count($parts = explode('.', $input)) >= 2) {
92
            $this->collectAssertException($e, $this->tld, array_pop($parts));
93
        }
94
95
        foreach ($parts as $p) {
96
            $this->collectAssertException($e, $this->otherParts, $p);
97
        }
98
99
        if (count($e)) {
100
            throw $this->reportError($input)->setRelated($e);
101
        }
102
103
        return true;
104
    }
105
106
    protected function collectAssertException(&$exceptions, $validator, $input)
107
    {
108
        try {
109
            $validator->assert($input);
110
        } catch (ValidationException $e) {
111
            $exceptions[] = $e;
112
        }
113
    }
114
115
    public function check($input)
116
    {
117
        foreach ($this->checks as $chk) {
118
            $chk->check($input);
119
        }
120
121
        if (count($parts = explode('.', $input)) >= 2) {
122
            $this->tld->check(array_pop($parts));
0 ignored issues
show
Bug introduced by
The method check does only exist in Respect\Validation\Rules\Tld, but not in Respect\Validation\Rules\AllOf.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
123
        }
124
125
        foreach ($parts as $p) {
126
            $this->otherParts->check($p);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Respect\Validation\Rules\AllOf as the method check() does only exist in the following sub-classes of Respect\Validation\Rules\AllOf: Respect\Validation\Validator. 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...
127
        }
128
129
        return true;
130
    }
131
}
132