Completed
Push — master ( 3ac6d3...638eef )
by Nazar
07:17
created

Controller::add_composer_loader_mapping()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 13
rs 9.4285
1
<?php
2
/**
3
 * @package   Http server
4
 * @category  modules
5
 * @author    Nazar Mokrynskyi <[email protected]>
6
 * @copyright Copyright (c) 2015-2017, Nazar Mokrynskyi
7
 * @license   MIT License, see license.txt
8
 */
9
namespace cs\modules\Http_server\cli;
10
use
11
	cs\ExitException,
12
	cs\modules\Psr15\Middleware,
13
	FriendsOfReact\Http\Middleware\Psr15Adapter\PSR15Middleware,
0 ignored issues
show
Bug introduced by
The type FriendsOfReact\Http\Midd...Adapter\PSR15Middleware was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
	React;
0 ignored issues
show
Bug introduced by
The type React was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
16
class Controller {
17
	public static function index_help () {
18
		return <<<HELP
19
<y>Http server module</y>
20
21
<y>Methods:</y>
22
  <g>run_server</g> Prints all cli paths and methods available for specified path
23
  <g>run_pool</g>   Displays help for module or path (should be provided by developer, otherwise will fallback to <g>cli</g>)
24
25
<y>Arguments:</y>
26
  <g>port</g>  Required for <g>run_server</g>, specifies port on which server will be running
27
  <g>ports</g> Required for <g>run_pool</g>, specifies ports on which server will be running (coma-separated list of ports or ports ranged separated by -)
28
29
<y>Examples:</y>
30
  Run HTTP server on port 8080:
31
    <g>./cli run_server:Http_server port=8080</g>
32
  Run pool of HTTP servers on ports 8080, 8081 and range of ports 8082-8087:
33
    <g>./cli run_pool:Http_server ports=8080,8081,8082-8087</g>
34
35
HELP;
36
	}
37
	/**
38
	 * @param \cs\Request $Request
39
	 *
40
	 * @throws ExitException
41
	 */
42
	public static function index_run_server ($Request) {
43
		$port = $Request->query('port');
0 ignored issues
show
Bug introduced by
'port' of type string is incompatible with the type array<mixed,string[]>|string[] expected by parameter $name of cs\Request::query(). ( Ignorable by Annotation )

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

43
		$port = $Request->query(/** @scrutinizer ignore-type */ 'port');
Loading history...
44
		if (!$port) {
45
			throw new ExitException('Port is required', 400);
46
		}
47
		$_SERVER['SERVER_SOFTWARE'] = 'ReactPHP';
48
		static::add_composer_loader_mapping();
49
50
		$loop   = React\EventLoop\Factory::create();
0 ignored issues
show
Bug introduced by
The type React\EventLoop\Factory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
51
		$socket = new React\Socket\Server($port, $loop);
0 ignored issues
show
Bug introduced by
The type React\Socket\Server was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
52
		$http   = new React\Http\StreamingServer(
0 ignored issues
show
Bug introduced by
The type React\Http\StreamingServer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
53
			[
54
				new React\Http\Middleware\RequestBodyBufferMiddleware(),
0 ignored issues
show
Bug introduced by
The type React\Http\Middleware\RequestBodyBufferMiddleware was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
55
				new PSR15Middleware(
56
					$loop,
57
					Middleware::class,
58
					[React\Http\Response::class]
0 ignored issues
show
Bug introduced by
The type React\Http\Response was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
59
				)
60
			]
61
		);
62
		$http->listen($socket);
63
		$loop->run();
64
	}
65
	/**
66
	 * Hack for PSR15Middleware that blindly relies on Composer's autoloader
67
	 */
68
	protected static function add_composer_loader_mapping () {
69
		foreach (get_declared_classes() as $class) {
70
			if (strpos($class, 'ComposerAutoloaderInit') === 0) {
71
				/**
72
				 * @var \Composer\Autoload\ClassLoader $loader
73
				 */
74
				$loader = $class::getLoader();
75
				$loader->addClassMap(
76
					[
77
						Middleware::class => MODULES.'/Psr15/Middleware.php'
78
					]
79
				);
80
				break;
81
			}
82
		}
83
	}
84
	/**
85
	 * @param \cs\Request $Request
86
	 *
87
	 * @throws ExitException
88
	 */
89
	public static function index_run_pool ($Request) {
90
		$ports = $Request->query('ports');
0 ignored issues
show
Bug introduced by
'ports' of type string is incompatible with the type array<mixed,string[]>|string[] expected by parameter $name of cs\Request::query(). ( Ignorable by Annotation )

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

90
		$ports = $Request->query(/** @scrutinizer ignore-type */ 'ports');
Loading history...
91
		if (!$ports) {
92
			throw new ExitException('Ports are required', 400);
93
		}
94
		$ports = static::prepare_ports($ports);
0 ignored issues
show
Bug introduced by
It seems like $ports can also be of type array and array; however, parameter $ports of cs\modules\Http_server\c...roller::prepare_ports() 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

94
		$ports = static::prepare_ports(/** @scrutinizer ignore-type */ $ports);
Loading history...
95
		foreach ($ports as $p) {
96
			static::cross_platform_server_in_background($p);
97
		}
98
		echo "Pool of Http servers started!\n";
99
	}
100
	/**
101
	 * @param string $ports
102
	 *
103
	 * @return int[]
104
	 */
105
	protected static function prepare_ports ($ports) {
106
		$result_ports = [];
107
		foreach (explode(',', $ports) as $p) {
108
			if (strpos($p, '-') !== false) {
109
				/** @noinspection SlowArrayOperationsInLoopInspection */
110
				$result_ports = array_merge($result_ports, range(...explode('-', $p)));
0 ignored issues
show
Bug introduced by
explode('-', $p) is expanded, but the parameter $low of range() does not expect variable arguments. ( Ignorable by Annotation )

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

110
				$result_ports = array_merge($result_ports, range(/** @scrutinizer ignore-type */ ...explode('-', $p)));
Loading history...
Bug introduced by
The call to range() has too few arguments starting with high. ( Ignorable by Annotation )

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

110
				$result_ports = array_merge($result_ports, /** @scrutinizer ignore-call */ range(...explode('-', $p)));

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
111
			} else {
112
				$result_ports[] = $p;
113
			}
114
		}
115
		sort($result_ports);
116
		return $result_ports;
117
	}
118
	/**
119
	 * Running Http server in background on any platform
120
	 *
121
	 * @param int $port
122
	 */
123
	protected static function cross_platform_server_in_background ($port) {
124
		$dir        = dirname(__DIR__);
125
		$supervisor = "php $dir/supervisor.php";
126
		$cmd        = escapeshellarg(PHP_BINARY.' '.DIR."/cli run_server:Http_server port=$port");
127
		if (strpos(PHP_OS, 'WIN') === false) {
128
			exec("$supervisor $cmd > /dev/null &");
129
		} else {
130
			pclose(popen("start /B $supervisor $cmd", 'r'));
0 ignored issues
show
Bug introduced by
It seems like popen(EncapsedNode, 'r') can also be of type false; however, parameter $handle of pclose() does only seem to accept resource, 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

130
			pclose(/** @scrutinizer ignore-type */ popen("start /B $supervisor $cmd", 'r'));
Loading history...
131
		}
132
	}
133
}
134