Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Shell.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\Console;
013
014 use Symfony\Component\Console\Input\StringInput;
015 use Symfony\Component\Console\Output\ConsoleOutput;
016 use Symfony\Component\Process\ProcessBuilder;
017 use Symfony\Component\Process\PhpExecutableFinder;
018
019 /**
020 * A Shell wraps an Application to add shell capabilities to it.
021 *
022 * Support for history and completion only works with a PHP compiled
023 * with readline support (either --with-readline or --with-libedit)
024 *
025 * @author Fabien Potencier <fabien@symfony.com>
026 * @author Martin Hasoň <martin.hason@gmail.com>
027 */
028 class Shell
029 {
030 private $application;
031 private $history;
032 private $output;
033 private $hasReadline;
034 private $processIsolation;
035
036 /**
037 * Constructor.
038 *
039 * If there is no readline support for the current PHP executable
040 * a \RuntimeException exception is thrown.
041 *
042 * @param Application $application An application instance
043 */
044 public function __construct(Application $application)
045 {
046 $this->hasReadline = function_exists('readline');
047 $this->application = $application;
048 $this->history = getenv('HOME').'/.history_'.$application->getName();
049 $this->output = new ConsoleOutput();
050 $this->processIsolation = false;
051 }
052
053 /**
054 * Runs the shell.
055 */
056 public function run()
057 {
058 $this->application->setAutoExit(false);
059 $this->application->setCatchExceptions(true);
060
061 if ($this->hasReadline) {
062 readline_read_history($this->history);
063 readline_completion_function(array($this, 'autocompleter'));
064 }
065
066 $this->output->writeln($this->getHeader());
067 $php = null;
068 if ($this->processIsolation) {
069 $finder = new PhpExecutableFinder();
070 $php = $finder->find();
071 $this->output->writeln(<<<EOF
072 <info>Running with process isolation, you should consider this:</info>
073 * each command is executed as separate process,
074 * commands don't support interactivity, all params must be passed explicitly,
075 * commands output is not colorized.
076
077 EOF
078 );
079 }
080
081 while (true) {
082 $command = $this->readline();
083
084 if (false === $command) {
085 $this->output->writeln("\n");
086
087 break;
088 }
089
090 if ($this->hasReadline) {
091 readline_add_history($command);
092 readline_write_history($this->history);
093 }
094
095 if ($this->processIsolation) {
096 $pb = new ProcessBuilder();
097
098 $process = $pb
099 ->add($php)
100 ->add($_SERVER['argv'][0])
101 ->add($command)
102 ->inheritEnvironmentVariables(true)
103 ->getProcess()
104 ;
105
106 $output = $this->output;
107 $process->run(function ($type, $data) use ($output) {
108 $output->writeln($data);
109 });
110
111 $ret = $process->getExitCode();
112 } else {
113 $ret = $this->application->run(new StringInput($command), $this->output);
114 }
115
116 if (0 !== $ret) {
117 $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
118 }
119 }
120 }
121
122 /**
123 * Returns the shell header.
124 *
125 * @return string The header string
126 */
127 protected function getHeader()
128 {
129 return <<<EOF
130
131 Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).
132
133 At the prompt, type <comment>help</comment> for some help,
134 or <comment>list</comment> to get a list of available commands.
135
136 To exit the shell, type <comment>^D</comment>.
137
138 EOF;
139
140 }
141
142 /**
143 * Renders a prompt.
144 *
145 * @return string The prompt
146 */
147 protected function getPrompt()
148 {
149 // using the formatter here is required when using readline
150 return $this->output->getFormatter()->format($this->application->getName().' > ');
151 }
152
153 protected function getOutput()
154 {
155 return $this->output;
156 }
157
158 protected function getApplication()
159 {
160 return $this->application;
161 }
162
163 /**
164 * Tries to return autocompletion for the current entered text.
165 *
166 * @param string $text The last segment of the entered text
167 *
168 * @return bool|array A list of guessed strings or true
169 */
170 private function autocompleter($text)
171 {
172 $info = readline_info();
173 $text = substr($info['line_buffer'], 0, $info['end']);
174
175 if ($info['point'] !== $info['end']) {
176 return true;
177 }
178
179 // task name?
180 if (false === strpos($text, ' ') || !$text) {
181 return array_keys($this->application->all());
182 }
183
184 // options and arguments?
185 try {
186 $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
187 } catch (\Exception $e) {
188 return true;
189 }
190
191 $list = array('--help');
192 foreach ($command->getDefinition()->getOptions() as $option) {
193 $list[] = '--'.$option->getName();
194 }
195
196 return $list;
197 }
198
199 /**
200 * Reads a single line from standard input.
201 *
202 * @return string The single line from standard input
203 */
204 private function readline()
205 {
206 if ($this->hasReadline) {
207 $line = readline($this->getPrompt());
208 } else {
209 $this->output->write($this->getPrompt());
210 $line = fgets(STDIN, 1024);
211 $line = (!$line && strlen($line) == 0) ? false : rtrim($line);
212 }
213
214 return $line;
215 }
216
217 public function getProcessIsolation()
218 {
219 return $this->processIsolation;
220 }
221
222 public function setProcessIsolation($processIsolation)
223 {
224 $this->processIsolation = (bool) $processIsolation;
225
226 if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) {
227 throw new \RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.');
228 }
229 }
230 }
231