Completed
Push — master ( 6994a2...1178e8 )
by Roeland
13:08
created

Base::writeArrayInOutputFormat()   B

Complexity

Conditions 8
Paths 7

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 7
nop 4
dl 0
loc 29
rs 8.2114
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 * @author Thomas Müller <[email protected]>
7
 *
8
 * @license AGPL-3.0
9
 *
10
 * This code is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License, version 3,
12
 * as published by the Free Software Foundation.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License, version 3,
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
21
 *
22
 */
23
24
namespace OC\Core\Command;
25
26
use OC\Core\Command\User\ListCommand;
27
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
28
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
29
use Symfony\Component\Console\Command\Command;
30
use Symfony\Component\Console\Input\InputInterface;
31
use Symfony\Component\Console\Input\InputOption;
32
use Symfony\Component\Console\Output\OutputInterface;
33
34
class Base extends Command implements CompletionAwareInterface {
35
	const OUTPUT_FORMAT_PLAIN = 'plain';
36
	const OUTPUT_FORMAT_JSON = 'json';
37
	const OUTPUT_FORMAT_JSON_PRETTY = 'json_pretty';
38
39
	protected $defaultOutputFormat = self::OUTPUT_FORMAT_PLAIN;
40
41
	/** @var boolean */
42
	private $php_pcntl_signal = false;
43
44
	/** @var boolean */
45
	private $interrupted = false;
46
47
	protected function configure() {
48
		$this
49
			->addOption(
50
				'output',
51
				null,
52
				InputOption::VALUE_OPTIONAL,
53
				'Output format (plain, json or json_pretty, default is plain)',
54
				$this->defaultOutputFormat
55
			)
56
		;
57
	}
58
59
	/**
60
	 * @param InputInterface $input
61
	 * @param OutputInterface $output
62
	 * @param array $items
63
	 * @param string $prefix
64
	 */
65
	protected function writeArrayInOutputFormat(InputInterface $input, OutputInterface $output, $items, $prefix = '  - ') {
66
		switch ($input->getOption('output')) {
67
			case self::OUTPUT_FORMAT_JSON:
68
				$output->writeln(json_encode($items));
69
				break;
70
			case self::OUTPUT_FORMAT_JSON_PRETTY:
71
				$output->writeln(json_encode($items, JSON_PRETTY_PRINT));
72
				break;
73
			default:
74
				foreach ($items as $key => $item) {
75
					if (is_array($item)) {
76
						$output->writeln($prefix . $key . ':');
77
						$this->writeArrayInOutputFormat($input, $output, $item, '  ' . $prefix);
78
						continue;
79
					}
80
					if (!is_int($key) || ListCommand::class === get_class($this)) {
81
						$value = $this->valueToString($item);
82
						if (!is_null($value)) {
83
							$output->writeln($prefix . $key . ': ' . $value);
84
						} else {
85
							$output->writeln($prefix . $key);
86
						}
87
					} else {
88
						$output->writeln($prefix . $this->valueToString($item));
89
					}
90
				}
91
				break;
92
		}
93
	}
94
95
	/**
96
	 * @param InputInterface $input
97
	 * @param OutputInterface $output
98
	 * @param mixed $item
99
	 */
100
	protected function writeMixedInOutputFormat(InputInterface $input, OutputInterface $output, $item) {
101
		if (is_array($item)) {
102
			$this->writeArrayInOutputFormat($input, $output, $item, '');
103
			return;
104
		}
105
106
		switch ($input->getOption('output')) {
107
			case self::OUTPUT_FORMAT_JSON:
108
				$output->writeln(json_encode($item));
109
				break;
110
			case self::OUTPUT_FORMAT_JSON_PRETTY:
111
				$output->writeln(json_encode($item, JSON_PRETTY_PRINT));
112
				break;
113
			default:
114
				$output->writeln($this->valueToString($item, false));
115
				break;
116
		}
117
	}
118
119
	protected function valueToString($value, $returnNull = true) {
120
		if ($value === false) {
121
			return 'false';
122
		} else if ($value === true) {
123
			return 'true';
124
		} else if ($value === null) {
125
			return $returnNull ? null : 'null';
126
		} else {
127
			return $value;
128
		}
129
	}
130
131
	/**
132
	 * Throw InterruptedException when interrupted by user
133
	 *
134
	 * @throws InterruptedException
135
	 */
136
	protected function abortIfInterrupted() {
137
		if ($this->php_pcntl_signal === false) {
138
			return;
139
		}
140
141
		pcntl_signal_dispatch();
142
143
		if ($this->interrupted === true) {
144
			throw new InterruptedException('Command interrupted by user');
145
		}
146
	}
147
148
	/**
149
	 * Changes the status of the command to "interrupted" if ctrl-c has been pressed
150
	 *
151
	 * Gives a chance to the command to properly terminate what it's doing
152
	 */
153
	protected function cancelOperation() {
154
		$this->interrupted = true;
155
	}
156
157
	public function run(InputInterface $input, OutputInterface $output) {
158
		// check if the php pcntl_signal functions are accessible
159
		$this->php_pcntl_signal = function_exists('pcntl_signal');
160
		if ($this->php_pcntl_signal) {
161
			// Collect interrupts and notify the running command
162
			pcntl_signal(SIGTERM, [$this, 'cancelOperation']);
163
			pcntl_signal(SIGINT, [$this, 'cancelOperation']);
164
		}
165
166
		return parent::run($input, $output);
167
	}
168
169
	/**
170
	 * @param string $optionName
171
	 * @param CompletionContext $context
172
	 * @return string[]
173
	 */
174
	public function completeOptionValues($optionName, CompletionContext $context) {
175
		if ($optionName === 'output') {
176
			return ['plain', 'json', 'json_pretty'];
177
		}
178
		return [];
179
	}
180
181
	/**
182
	 * @param string $argumentName
183
	 * @param CompletionContext $context
184
	 * @return string[]
185
	 */
186
	public function completeArgumentValues($argumentName, CompletionContext $context) {
187
		return [];
188
	}
189
}
190