Completed
Push — master ( 298814...ce748c )
by Thomas
10:09
created

Application::setAutoExit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Joas Schilling <[email protected]>
4
 * @author Lukas Reschke <[email protected]>
5
 * @author Morris Jobke <[email protected]>
6
 * @author Robin McCorkell <[email protected]>
7
 * @author Thomas Müller <[email protected]>
8
 * @author Victor Dubiniuk <[email protected]>
9
 *
10
 * @copyright Copyright (c) 2016, ownCloud GmbH.
11
 * @license AGPL-3.0
12
 *
13
 * This code is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License, version 3,
15
 * as published by the Free Software Foundation.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License, version 3,
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
24
 *
25
 */
26
namespace OC\Console;
27
28
use OC_App;
29
use OC_Defaults;
30
use OCP\AppFramework\QueryException;
31
use OCP\Console\ConsoleEvent;
32
use OCP\IConfig;
33
use OCP\IRequest;
34
use Symfony\Component\Console\Application as SymfonyApplication;
35
use Symfony\Component\Console\Input\ArgvInput;
36
use Symfony\Component\Console\Input\InputInterface;
37
use Symfony\Component\Console\Input\InputOption;
38
use Symfony\Component\Console\Output\OutputInterface;
39
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
40
41
class Application {
42
	/** @var IConfig */
43
	private $config;
44
	/** @var EventDispatcherInterface */
45
	private $dispatcher;
46
	/** @var IRequest */
47
	private $request;
48
49
	/**
50
	 * @param IConfig $config
51
	 * @param EventDispatcherInterface $dispatcher
52
	 * @param IRequest $request
53
	 */
54
	public function __construct(IConfig $config, EventDispatcherInterface $dispatcher, IRequest $request) {
55
		$defaults = new OC_Defaults;
56
		$this->config = $config;
57
		$this->application = new SymfonyApplication($defaults->getName(), \OC_Util::getVersionString());
0 ignored issues
show
Bug introduced by
The property application does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
58
		$this->dispatcher = $dispatcher;
59
		$this->request = $request;
60
	}
61
62
	/**
63
	 * @param InputInterface $input
64
	 * @param OutputInterface $output
65
	 * @throws \Exception
66
	 */
67
	public function loadCommands(InputInterface $input, OutputInterface $output) {
68
		// $application is required to be defined in the register_command scripts
69
		$application = $this->application;
70
		$inputDefinition = $application->getDefinition();
71
		$inputDefinition->addOption(
72
			new InputOption(
73
				'no-warnings', 
74
				null, 
75
				InputOption::VALUE_NONE, 
76
				'Skip global warnings, show command output only', 
77
				null
78
			)
79
		);
80
		try {
81
			$input->bind($inputDefinition);
82
		} catch (\RuntimeException $e) {
83
			//expected if there are extra options
84
		}
85
		if ($input->getOption('no-warnings')) {
86
			$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
87
		}
88
		require_once __DIR__ . '/../../../core/register_command.php';
89
		if ($this->config->getSystemValue('installed', false)) {
90
			if (\OCP\Util::needUpgrade()) {
91
				$output->writeln("ownCloud or one of the apps require upgrade - only a limited number of commands are available");
92
				$output->writeln("You may use your browser or the occ upgrade command to do the upgrade");
93
			} elseif ($this->config->getSystemValue('maintenance', false)) {
94
				$output->writeln("ownCloud is in maintenance mode - no app have been loaded");
95
			} else {
96
				OC_App::loadApps();
97
				foreach (\OC::$server->getAppManager()->getInstalledApps() as $app) {
98
					$appPath = \OC_App::getAppPath($app);
99
					if($appPath === false) {
100
						continue;
101
					}
102
					// load commands using info.xml
103
					$info = \OC_App::getAppInfo($app);
104
					if (isset($info['commands'])) {
105
						$this->loadCommandsFromInfoXml($info['commands']);
106
					}
107
					// load from register_command.php
108
					\OC_App::registerAutoloading($app, $appPath);
109
					$file = $appPath . '/appinfo/register_command.php';
110
					if (file_exists($file)) {
111
						require $file;
112
					}
113
				}
114
			}
115
		} else {
116
			$output->writeln("ownCloud is not installed - only a limited number of commands are available");
117
		}
118
		$input = new ArgvInput();
119
		if ($input->getFirstArgument() !== 'check') {
120
			$errors = \OC_Util::checkServer(\OC::$server->getConfig());
121
			if (!empty($errors)) {
122
				foreach ($errors as $error) {
123
					$output->writeln((string)$error['error']);
124
					$output->writeln((string)$error['hint']);
125
					$output->writeln('');
126
				}
127
				throw new \Exception("Environment not properly prepared.");
128
			}
129
		}
130
	}
131
132
	/**
133
	 * Sets whether to automatically exit after a command execution or not.
134
	 *
135
	 * @param bool $boolean Whether to automatically exit after a command execution or not
136
	 */
137
	public function setAutoExit($boolean) {
138
		$this->application->setAutoExit($boolean);
139
	}
140
141
	/**
142
	 * @param InputInterface $input
143
	 * @param OutputInterface $output
144
	 * @return int
145
	 * @throws \Exception
146
	 */
147
	public function run(InputInterface $input = null, OutputInterface $output = null) {
148
		$args = isset($this->request->server['argv']) ? $this->request->server['argv'] : [];
0 ignored issues
show
Bug introduced by
Accessing server on the interface OCP\IRequest suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
149
		$this->dispatcher->dispatch(ConsoleEvent::EVENT_RUN, new ConsoleEvent(
150
			ConsoleEvent::EVENT_RUN,
151
			$args
152
		));
153
		return $this->application->run($input, $output);
154
	}
155
156
	private function loadCommandsFromInfoXml($commands) {
157 View Code Duplication
		foreach ($commands as $command) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
158
			try {
159
				$c = \OC::$server->query($command);
160
			} catch (QueryException $e) {
161
				if (class_exists($command)) {
162
					$c = new $command();
163
				} else {
164
					throw new \Exception("Console command '$command' is unknown and could not be loaded");
165
				}
166
			}
167
168
			$this->application->add($c);
169
		}
170
	}
171
}
172