Completed
Pull Request — master (#355)
by Victor
03:24
created

OccRunner::runAsRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 19
ccs 0
cts 14
cp 0
rs 9.4285
cc 1
eloc 13
nc 1
nop 2
crap 2
1
<?php
2
/**
3
 * @author Victor Dubiniuk <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2015, ownCloud, Inc.
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace Owncloud\Updater\Utils;
23
24
use GuzzleHttp\Client;
25
use Owncloud\Updater\Console\Application;
26
use Symfony\Component\Process\Process;
27
use Symfony\Component\Process\ProcessUtils;
28
use Symfony\Component\Process\Exception\ProcessFailedException;
29
use Owncloud\Updater\Utils\Locator;
30
31
class OccRunner {
32
	/**
33
	 * @var Locator $locator
34
	 */
35
	protected $locator;
36
37
	/**
38
	 * @var bool
39
	 */
40
	protected $canUseProcess;
41
42
	/**
43
	 *
44
	 * @param Locator $locator
45
	 * @param bool $canUseProcess
46
	 */
47 2
	public function __construct(Locator $locator, $canUseProcess){
48 2
		$this->locator = $locator;
49 2
		$this->canUseProcess = $canUseProcess;
50 2
	}
51
52 2
	public function run($command, $args = [], $asJson = false){
53 2
		if ($this->canUseProcess){
54 1
			$extra = $asJson ? '--output=json' : '';
55 1
			$cmdLine = trim($command . ' ' . $extra);
56 1
			foreach ($args as $optionTitle => $optionValue){
57
				if (strpos($optionTitle, '--') === 0){
58
					$line = trim("$optionTitle $optionValue");
59
				} else {
60
					$line = $optionValue;
61
				}
62
				$escapedLine = ProcessUtils::escapeArgument($line);
63
				$cmdLine .= " $escapedLine";
64 1
			}
65 1
			return $this->runAsProcess($cmdLine);
66
		} else {
67 1
			if ($asJson){
68 1
				$args['--output'] = 'json';
69 1
			}
70 1
			$response = $this->runAsRequest($command, $args);
71 1
			$decodedResponse = json_decode($response, true);
72 1
			return $decodedResponse['response'];
73
		}
74
	}
75
76 5
	public function runJson($command, $args = []){
77 5
		$plain = $this->run($command, $args, true);
78 5
		$decoded = json_decode($plain, true);
79 5
		if (!is_array($decoded)){
80 1
			throw new \UnexpectedValueException('Could not parse a response for ' . $command . '. Please check if the current shell user can run occ command. Raw output: ' . PHP_EOL . $plain);
81
		}
82 4
		return $decoded;
83
	}
84
85
	protected function runAsRequest($command, $args){
86
		$application = $this->getApplication();
87
		$client = new Client();
88
		$request = $client->createRequest(
89
			'POST',
90
			$application->getEndpoint() . $command,
91
			[
92
				'timeout' => 0,
93
				'json' => [
94
					'token' => $application->getAuthToken(),
95
					'params'=> $args
96
				]
97
			]
98
		);
99
100
		$response = $client->send($request);
101
		$responseBody = $response->getBody()->getContents();
102
		return $responseBody;
103
	}
104
105
	protected function getApplication(){
106
		$container = Application::$container;
107
		$application = $container['application'];
108
		return $application;
109
	}
110
111
	protected function runAsProcess($cmdLine){
112
		$occPath = $this->locator->getPathToOccFile();
113
		$cmd = "php $occPath --no-warnings $cmdLine";
114
		$process = new Process($cmd);
115
		$process->setTimeout(null);
116
		$process->run();
117
118
		if (!$process->isSuccessful()){
119
			throw new ProcessFailedException($process);
120
		}
121
		return $process->getOutput();
122
	}
123
}
124