Issues (64)

src/Configurator/Collections/HostnameList.php (1 issue)

1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) The s9e authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Configurator\Collections;
9
10
use s9e\TextFormatter\Configurator\Helpers\RegexpBuilder;
11
use s9e\TextFormatter\Configurator\Items\Regexp;
12
13
class HostnameList extends NormalizedList
14
{
15
	/**
16
	* Return this hostname list as a regexp's config
17
	*
18
	* @return Regexp|null A Regexp instance, or NULL if the collection is empty
19
	*/
20 8
	public function asConfig()
21
	{
22 8
		if (empty($this->items))
23
		{
24 1
			return null;
25
		}
26
27 7
		return new Regexp($this->getRegexp());
0 ignored issues
show
Bug Best Practice introduced by
The expression return new s9e\TextForma...exp($this->getRegexp()) returns the type s9e\TextFormatter\Configurator\Items\Regexp which is incompatible with the return type mandated by s9e\TextFormatter\Config...figProvider::asConfig() of array|null|s9e\TextForma...r\JavaScript\Dictionary.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
28
	}
29
30
	/**
31
	* Return a regexp that matches the list of hostnames
32
	*
33
	* @return string
34
	*/
35 7
	public function getRegexp()
36
	{
37 7
		$hosts = [];
38 7
		foreach ($this->items as $host)
39
		{
40 7
			$hosts[] = $this->normalizeHostmask($host);
41
		}
42
43 7
		$regexp = RegexpBuilder::fromList(
44 7
			$hosts,
45
			[
46
				// Asterisks * are turned into a catch-all expression, while ^ and $ are preserved
47
				'specialChars' => [
48 7
					'*' => '.*',
49
					'^' => '^',
50
					'$' => '$'
51
				]
52
			]
53
		);
54
55 7
		return '/' . $regexp . '/DSis';
56
	}
57
58
	/**
59
	* Normalize a hostmask to a regular expression
60
	*
61
	* @param  string $host Hostname or hostmask
62
	* @return string
63
	*/
64 7
	protected function normalizeHostmask($host)
65
	{
66 7
		if (preg_match('#[\\x80-\xff]#', $host) && function_exists('idn_to_ascii'))
67
		{
68 1
			$variant = (defined('INTL_IDNA_VARIANT_UTS46')) ? INTL_IDNA_VARIANT_UTS46 : 0;
69 1
			$host = idn_to_ascii($host, 0, $variant);
70
		}
71
72 7
		if (substr($host, 0, 1) === '*')
73
		{
74
			// *.example.com => /\.example\.com$/
75 1
			$host = ltrim($host, '*');
76
		}
77
		else
78
		{
79
			// example.com => /^example\.com$/
80 6
			$host = '^' . $host;
81
		}
82
83 7
		if (substr($host, -1) === '*')
84
		{
85
			// example.* => /^example\./
86 1
			$host = rtrim($host, '*');
87
		}
88
		else
89
		{
90
			// example.com => /^example\.com$/
91 6
			$host .= '$';
92
		}
93
94 7
		return $host;
95
	}
96
}