Test Setup Failed
Push — master ( b88989...23c882 )
by smiley
09:01
created

CLIRunner::run()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 19
rs 9.2
cc 4
eloc 11
nc 5
nop 1
1
<?php
2
/**
3
 * Class CLIRunner
4
 *
5
 * @filesource   CLIRunner.php
6
 * @created      01.04.2016
7
 * @package      chillerlan\Threema
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2016 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Threema;
14
15
use chillerlan\Threema\Crypto\CryptoInterface;
16
use ReflectionClass;
17
use ReflectionMethod;
18
19
/**
20
 * 
21
 */
22
class CLIRunner implements CLIRunnerInterface{
23
24
	/**
25
	 * @var array
26
	 */
27
	const COMMANDS = [
28
		// local
29
		'keypair'      => 'getKeypair',
30
		'hash_email'   => 'hashEmail',
31
		'hash_phone'   => 'hashPhone',
32
#		'encrypt'      => '',
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
33
#		'decrypt'      => '',
34
		// network
35
		'credits'      => 'checkCredits',
36
		'check'        => 'checkCapabilities',
37
#		'idbyemail'    => '',
0 ignored issues
show
Unused Code Comprehensibility introduced by
51% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
38
#		'idbyphone'    => '',
39
#		'keybyid'      => '',
40
#		'send'         => '',
41
#		'sende2e'      => '',
42
#		'sendimage'    => '',
43
#		'sendfile'     => '',
44
#		'receive'      => '',
45
	];
46
47
	/**
48
	 * @var \chillerlan\Threema\Crypto\CryptoInterface
49
	 */
50
	protected $cryptoInterface;
51
52
	/**
53
	 * @var \chillerlan\Threema\GatewayOptions
54
	 */
55
	protected $gatewayOptions;
56
57
	/**
58
	 * @var \chillerlan\Threema\Gateway
59
	 */
60
	protected $threemaGateway;
61
62
	/**
63
	 * @var \ReflectionClass
64
	 */
65
	protected $reflection;
66
67
	/**
68
	 * @var array[\ReflectionMethod]
69
	 */
70
	private   $CLIRunnerInterfaceMap;
71
72
	/**
73
	 * CLIRunner constructor.
74
	 *
75
	 * @param \chillerlan\Threema\Crypto\CryptoInterface $cryptoInterface
76
	 * @param \chillerlan\Threema\GatewayOptions         $gatewayOptions
77
	 */
78
	public function __construct(CryptoInterface $cryptoInterface, GatewayOptions $gatewayOptions){
79
		$this->cryptoInterface = $cryptoInterface;
80
		$this->gatewayOptions  = $gatewayOptions;
81
		$this->threemaGateway  = new Gateway($this->cryptoInterface, $gatewayOptions);
82
		$this->reflection      = new ReflectionClass(CLIRunnerInterface::class);
83
84
		foreach($this->reflection ->getMethods() as $method){
85
			$this->CLIRunnerInterfaceMap[$method->name] = $method;
86
		}
87
	}
88
89
	/**
90
	 * @inheritdoc
91
	 */
92
	public function run(array $arguments):string{
93
		/** @noinspection PhpUnusedLocalVariableInspection */
94
		$scriptName = basename(array_shift($arguments));
0 ignored issues
show
Unused Code introduced by
$scriptName is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
95
		$command    = strtolower(array_shift($arguments));
96
97
		if(array_key_exists($command, self::COMMANDS) && array_key_exists(self::COMMANDS[$command], $this->CLIRunnerInterfaceMap)){
98
			try{
99
				$method = $this->CLIRunnerInterfaceMap[self::COMMANDS[$command]];
100
				$method = new ReflectionMethod($this, $method->name);
101
102
				return $this->log2cli($method->invokeArgs($this, $arguments));
103
			}
104
			catch(GatewayException $gatewayException){
105
				return $this->log2cli('ERROR: '.$gatewayException->getMessage());
106
			}
107
		}
108
109
		return $this->log2cli($this->help());
110
	}
111
112
	/**
113
	 * output a string, wrap at 100 chars
114
	 *
115
	 * @param string $string string to output
116
	 *
117
	 * @return string
118
	 */
119
	protected function log2cli(string $string):string{
120
		return PHP_EOL.wordwrap($string, 78, PHP_EOL).PHP_EOL;
121
	}
122
123
	/**
124
	 * @return string
125
	 * @codeCoverageIgnore
126
	 */
127
	protected function readStdIn(){
128
		$stdin = fopen('php://stdin', 'r');
129
		$lines = [];
130
131
		while($line = trim(fgets($stdin))){
132
133
			if(strlen($line) === 0 || $line === "\n"){
134
				continue;
135
			}
136
137
			$lines[] = $line;
138
		}
139
140
		return implode("\n", $lines);
141
	}
142
143
	/**
144
	 * @inheritdoc
145
	 */
146
	public function help():string{
147
		// return info in case no command was found
148
		$help  = 'Threema Gateway CLI tool.'.PHP_EOL;
149
		$help .= 'Crypto: '.$this->threemaGateway->cryptoVersion().PHP_EOL.PHP_EOL;
150
151
		foreach(self::COMMANDS as $command => $method){
152
			$comment = $this->reflection->getMethod($method)->getDocComment();
153
			$comment = str_replace(["\t", ' *'], '', substr($comment, 3, -2));
154
155
			$params  = explode('@', $comment);
156
			$comment = trim(array_shift($params));
157
158
			$paramNames = [];
159
			$paramDoc = [];
160
			$returnDoc = '';
161
			if(count($params) > 0){
162
				foreach($params as $p){
163
					$p = explode(' ', $p, 2);
164
					if(isset($p[1])){
165
						if($p[0] === 'param'){
166
							$p = (explode(' ', trim($p[1]), 3));
167
							$paramNames[] = '<'.trim($p[1], ' $').'>';
168
							$d =  trim($p[1]);
169
#							$d .= ' ('.trim($p[0]).'): ';
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
170
							$d .= isset($p[2]) ? ': '.trim($p[2]) : '';
171
							$paramDoc[] = $d;
172
						}
173
						else if($p[0] === 'return'){
174
							$p = explode(' ', trim($p[1]), 2);
175
#							$returnDoc  = '('.trim($p[0]).') ';
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
176
							$returnDoc .= isset($p[1]) ? trim($p[1]) : '';
177
						}
178
					}
179
180
				}
181
			}
182
183
			$help .= PHP_EOL.'threema.php '.$command.' '.implode(' ', $paramNames).PHP_EOL;
184
			$help .= str_repeat('-', strlen($command)+12).PHP_EOL;
185
			$help .= PHP_EOL.$comment.PHP_EOL;
186
			$help .= PHP_EOL.implode(PHP_EOL, $paramDoc).PHP_EOL;
187
			$help .= PHP_EOL.'Returns: '.$returnDoc.PHP_EOL;
188
		}
189
190
		return $help;
191
	}
192
193
	/**
194
	 * @inheritdoc
195
	 * @todo file output
196
	 */
197
	public function getKeypair(string $privateKeyFile = null, string $publicKeyFile = null):string{
198
		$keypair = $this->cryptoInterface->getKeypair();
199
200
		return 'private:'.$keypair->privateKey.PHP_EOL.'public:'.$keypair->publicKey;
201
	}
202
203
	/**
204
	 * @inheritdoc
205
	 */
206
	public function hashEmail(string $email):string{
207
		return $this->cryptoInterface->hmac_hash($email, GatewayInterface::HMAC_KEY_EMAIL_BIN);
208
	}
209
210
	/**
211
	 * @inheritdoc
212
	 */
213
	public function hashPhone(string $phoneNo):string{
214
		return $this->cryptoInterface->hmac_hash($phoneNo, GatewayInterface::HMAC_KEY_PHONE_BIN);
215
	}
216
217
	/**
218
	 * @inheritdoc
219
	 */
220
	public function checkCredits():string{
221
		return $this->threemaGateway->checkCredits();
222
	}
223
224
	/**
225
	 * @inheritdoc
226
	 */
227
	public function checkCapabilities(string $threemaID):string{
228
		return implode(',', $this->threemaGateway->checkCapabilities($threemaID));
229
	}
230
}
231