Url::getFragmentIdentifier()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace ValueObjects\Web;
4
5
use ValueObjects\StringLiteral\StringLiteral;
6
use ValueObjects\Util\Util;
7
use ValueObjects\ValueObjectInterface;
8
9
class Url implements ValueObjectInterface
10
{
11
    /** @var SchemeName */
12
    protected $scheme;
13
14
    /** @var StringLiteral */
15
    protected $user;
16
17
    /** @var StringLiteral */
18
    protected $password;
19
20
    /** @var Domain */
21
    protected $domain;
22
23
    /** @var Path */
24
    protected $path;
25
26
    /** @var PortNumberInterface */
27
    protected $port;
28
29
    /** @var QueryString */
30
    protected $queryString;
31
32
    /** @var FragmentIdentifier */
33
    protected $fragmentIdentifier;
34
35
    /**
36
     * Returns a new Url object from a native url string
37
     *
38
     * @param $url_string
39
     * @return Url
40
     */
41 2
    public static function fromNative()
42
    {
43 2
        $urlString = \func_get_arg(0);
44
45 2
        $user        = \parse_url($urlString, PHP_URL_USER);
46 2
        $pass        = \parse_url($urlString, PHP_URL_PASS);
47 2
        $host        = \parse_url($urlString, PHP_URL_HOST);
48 2
        $queryString = \parse_url($urlString, PHP_URL_QUERY);
49 2
        $fragmentId  = \parse_url($urlString, PHP_URL_FRAGMENT);
50 2
        $port        = \parse_url($urlString, PHP_URL_PORT);
51
52 2
        $scheme     = new SchemeName(\parse_url($urlString, PHP_URL_SCHEME));
0 ignored issues
show
Security Bug introduced by
It seems like \parse_url($urlString, PHP_URL_SCHEME) targeting parse_url() can also be of type false; however, ValueObjects\Web\SchemeName::__construct() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
53 2
        $user       = $user ? new StringLiteral($user) : new StringLiteral('');
54 2
        $pass       = $pass ? new StringLiteral($pass) : new StringLiteral('');
55 2
        $domain     = Domain::specifyType($host);
56 2
        $path       = new Path(\parse_url($urlString, PHP_URL_PATH));
57 2
        $portNumber = $port ? new PortNumber($port) : new NullPortNumber();
58 2
        $query      = $queryString ? new QueryString(\sprintf('?%s', $queryString)) : new NullQueryString();
59 2
        $fragment   = $fragmentId ? new FragmentIdentifier(\sprintf('#%s', $fragmentId)) : new NullFragmentIdentifier();
60
61 2
        return new static($scheme, $user, $pass, $domain, $portNumber, $path, $query, $fragment);
62
    }
63
64
    /**
65
     * Returns a new Url object
66
     *
67
     * @param SchemeName          $scheme
68
     * @param StringLiteral       $user
69
     * @param StringLiteral       $password
70
     * @param Domain              $domain
71
     * @param Path                $path
72
     * @param PortNumberInterface $port
73
     * @param QueryString         $query
74
     * @param FragmentIdentifier  $fragment
75
     */
76 13
    public function __construct(SchemeName $scheme, StringLiteral $user, StringLiteral $password, Domain $domain, PortNumberInterface $port, Path $path, QueryString $query, FragmentIdentifier $fragment)
77
    {
78 13
        $this->scheme             = $scheme;
79 13
        $this->user               = $user;
80 13
        $this->password           = $password;
81 13
        $this->domain             = $domain;
82 13
        $this->path               = $path;
83 13
        $this->port               = $port;
84 13
        $this->queryString        = $query;
85 13
        $this->fragmentIdentifier = $fragment;
86 13
    }
87
88
    /**
89
     * Tells whether two Url are sameValueAs by comparing their components
90
     *
91
     * @param  ValueObjectInterface $url
92
     * @return bool
93
     */
94 2
    public function sameValueAs(ValueObjectInterface $url)
95
    {
96 2
        if (false === Util::classEquals($this, $url)) {
97 1
            return false;
98
        }
99
100 2
        return $this->getScheme()->sameValueAs($url->getScheme()) &&
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\ValueObjectInterface as the method getScheme() does only exist in the following implementations of said interface: ValueObjects\Web\Url.

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...
101 2
               $this->getUser()->sameValueAs($url->getUser()) &&
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\ValueObjectInterface as the method getUser() does only exist in the following implementations of said interface: ValueObjects\Web\Url.

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...
102 2
               $this->getPassword()->sameValueAs($url->getPassword()) &&
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\ValueObjectInterface as the method getPassword() does only exist in the following implementations of said interface: ValueObjects\Web\Url.

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...
103 2
               $this->getDomain()->sameValueAs($url->getDomain()) &&
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\ValueObjectInterface as the method getDomain() does only exist in the following implementations of said interface: ValueObjects\Web\Url.

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...
104 2
               $this->getPath()->sameValueAs($url->getPath()) &&
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\ValueObjectInterface as the method getPath() does only exist in the following implementations of said interface: ValueObjects\Web\Url.

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...
105 2
               $this->getPort()->sameValueAs($url->getPort()) &&
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\ValueObjectInterface as the method getPort() does only exist in the following implementations of said interface: ValueObjects\Web\Url.

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...
106 2
               $this->getQueryString()->sameValueAs($url->getQueryString()) &&
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\ValueObjectInterface as the method getQueryString() does only exist in the following implementations of said interface: ValueObjects\Web\Url.

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...
107 2
               $this->getFragmentIdentifier()->sameValueAs($url->getFragmentIdentifier())
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\ValueObjectInterface as the method getFragmentIdentifier() does only exist in the following implementations of said interface: ValueObjects\Web\Url.

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...
108 2
        ;
109
    }
110
111
    /**
112
     * Returns the domain of the Url
113
     *
114
     * @return Hostname|IPAddress
115
     */
116 6
    public function getDomain()
117
    {
118 6
        return clone $this->domain;
119
    }
120
121
    /**
122
     * Returns the fragment identifier of the Url
123
     *
124
     * @return FragmentIdentifier
125
     */
126 6
    public function getFragmentIdentifier()
127
    {
128 6
        return clone $this->fragmentIdentifier;
129
    }
130
131
    /**
132
     * Returns the password part of the Url
133
     *
134
     * @return StringLiteral
135
     */
136 5
    public function getPassword()
137
    {
138 5
        return clone $this->password;
139
    }
140
141
    /**
142
     * Returns the path of the Url
143
     *
144
     * @return Path
145
     */
146 6
    public function getPath()
147
    {
148 6
        return clone $this->path;
149
    }
150
151
    /**
152
     * Returns the port of the Url
153
     *
154
     * @return PortNumberInterface
155
     */
156 6
    public function getPort()
157
    {
158 6
        return clone $this->port;
159
    }
160
161
    /**
162
     * Returns the query string of the Url
163
     *
164
     * @return QueryString
165
     */
166 6
    public function getQueryString()
167
    {
168 6
        return clone $this->queryString;
169
    }
170
171
    /**
172
     * Returns the scheme of the Url
173
     *
174
     * @return SchemeName
175
     */
176 6
    public function getScheme()
177
    {
178 6
        return clone $this->scheme;
179
    }
180
181
    /**
182
     * Returns the user part of the Url
183
     *
184
     * @return StringLiteral
185
     */
186 6
    public function getUser()
187
    {
188 6
        return clone $this->user;
189
    }
190
191
    /**
192
     * Returns a string representation of the url
193
     *
194
     * @return string
195
     */
196 4
    public function __toString()
197
    {
198 4
        $userPass = '';
199 4
        if (false === $this->getUser()->isEmpty()) {
200 2
            $userPass = \sprintf('%s@', $this->getUser());
201
202 2
            if (false === $this->getPassword()->isEmpty()) {
203 1
                $userPass = \sprintf('%s:%s@', $this->getUser(), $this->getPassword());
204 1
            }
205 2
        }
206
207 4
        $port = '';
208 4
        if (false === NullPortNumber::create()->sameValueAs($this->getPort())) {
0 ignored issues
show
Documentation introduced by
$this->getPort() is of type object<ValueObjects\Web\PortNumberInterface>, but the function expects a object<ValueObjects\ValueObjectInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
209 2
            $port = \sprintf(':%d', $this->getPort()->toNative());
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ValueObjects\Web\PortNumberInterface as the method toNative() does only exist in the following implementations of said interface: ValueObjects\Web\PortNumber.

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...
210 2
        }
211
212 4
        $urlString = \sprintf('%s://%s%s%s%s%s%s', $this->getScheme(), $userPass, $this->getDomain(), $port, $this->getPath(), $this->getQueryString(), $this->getFragmentIdentifier());
213
214 4
        return $urlString;
215
    }
216
}
217