Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/*
4
 * This file is part of Psy Shell.
5
 *
6
 * (c) 2012-2022 Justin Hileman
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Psy\Command;
13
 
14
use Psy\Shell;
15
use Symfony\Component\Console\Application;
16
use Symfony\Component\Console\Command\Command as BaseCommand;
17
use Symfony\Component\Console\Helper\Table;
18
use Symfony\Component\Console\Helper\TableHelper;
19
use Symfony\Component\Console\Helper\TableStyle;
20
use Symfony\Component\Console\Output\OutputInterface;
21
 
22
/**
23
 * The Psy Shell base command.
24
 */
25
abstract class Command extends BaseCommand
26
{
27
    /**
28
     * Sets the application instance for this command.
29
     *
30
     * @param Application|null $application An Application instance
31
     *
32
     * @api
33
     */
34
    public function setApplication(Application $application = null)
35
    {
36
        if ($application !== null && !$application instanceof Shell) {
37
            throw new \InvalidArgumentException('PsySH Commands require an instance of Psy\Shell');
38
        }
39
 
40
        return parent::setApplication($application);
41
    }
42
 
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function asText(): string
47
    {
48
        $messages = [
49
            '<comment>Usage:</comment>',
50
            ' '.$this->getSynopsis(),
51
            '',
52
        ];
53
 
54
        if ($this->getAliases()) {
55
            $messages[] = $this->aliasesAsText();
56
        }
57
 
58
        if ($this->getArguments()) {
59
            $messages[] = $this->argumentsAsText();
60
        }
61
 
62
        if ($this->getOptions()) {
63
            $messages[] = $this->optionsAsText();
64
        }
65
 
66
        if ($help = $this->getProcessedHelp()) {
67
            $messages[] = '<comment>Help:</comment>';
68
            $messages[] = ' '.\str_replace("\n", "\n ", $help)."\n";
69
        }
70
 
71
        return \implode("\n", $messages);
72
    }
73
 
74
    /**
75
     * {@inheritdoc}
76
     */
77
    private function getArguments(): array
78
    {
79
        $hidden = $this->getHiddenArguments();
80
 
81
        return \array_filter($this->getNativeDefinition()->getArguments(), function ($argument) use ($hidden) {
82
            return !\in_array($argument->getName(), $hidden);
83
        });
84
    }
85
 
86
    /**
87
     * These arguments will be excluded from help output.
88
     *
89
     * @return array
90
     */
91
    protected function getHiddenArguments(): array
92
    {
93
        return ['command'];
94
    }
95
 
96
    /**
97
     * {@inheritdoc}
98
     */
99
    private function getOptions(): array
100
    {
101
        $hidden = $this->getHiddenOptions();
102
 
103
        return \array_filter($this->getNativeDefinition()->getOptions(), function ($option) use ($hidden) {
104
            return !\in_array($option->getName(), $hidden);
105
        });
106
    }
107
 
108
    /**
109
     * These options will be excluded from help output.
110
     *
111
     * @return array
112
     */
113
    protected function getHiddenOptions(): array
114
    {
115
        return ['verbose'];
116
    }
117
 
118
    /**
119
     * Format command aliases as text..
120
     *
121
     * @return string
122
     */
123
    private function aliasesAsText(): string
124
    {
125
        return '<comment>Aliases:</comment> <info>'.\implode(', ', $this->getAliases()).'</info>'.\PHP_EOL;
126
    }
127
 
128
    /**
129
     * Format command arguments as text.
130
     *
131
     * @return string
132
     */
133
    private function argumentsAsText(): string
134
    {
135
        $max = $this->getMaxWidth();
136
        $messages = [];
137
 
138
        $arguments = $this->getArguments();
139
        if (!empty($arguments)) {
140
            $messages[] = '<comment>Arguments:</comment>';
141
            foreach ($arguments as $argument) {
142
                if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) {
143
                    $default = \sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($argument->getDefault()));
144
                } else {
145
                    $default = '';
146
                }
147
 
148
                $description = \str_replace("\n", "\n".\str_pad('', $max + 2, ' '), $argument->getDescription());
149
 
150
                $messages[] = \sprintf(" <info>%-{$max}s</info> %s%s", $argument->getName(), $description, $default);
151
            }
152
 
153
            $messages[] = '';
154
        }
155
 
156
        return \implode(\PHP_EOL, $messages);
157
    }
158
 
159
    /**
160
     * Format options as text.
161
     *
162
     * @return string
163
     */
164
    private function optionsAsText(): string
165
    {
166
        $max = $this->getMaxWidth();
167
        $messages = [];
168
 
169
        $options = $this->getOptions();
170
        if ($options) {
171
            $messages[] = '<comment>Options:</comment>';
172
 
173
            foreach ($options as $option) {
174
                if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) {
175
                    $default = \sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($option->getDefault()));
176
                } else {
177
                    $default = '';
178
                }
179
 
180
                $multiple = $option->isArray() ? '<comment> (multiple values allowed)</comment>' : '';
181
                $description = \str_replace("\n", "\n".\str_pad('', $max + 2, ' '), $option->getDescription());
182
 
183
                $optionMax = $max - \strlen($option->getName()) - 2;
184
                $messages[] = \sprintf(
185
                    " <info>%s</info> %-{$optionMax}s%s%s%s",
186
                    '--'.$option->getName(),
187
                    $option->getShortcut() ? \sprintf('(-%s) ', $option->getShortcut()) : '',
188
                    $description,
189
                    $default,
190
                    $multiple
191
                );
192
            }
193
 
194
            $messages[] = '';
195
        }
196
 
197
        return \implode(\PHP_EOL, $messages);
198
    }
199
 
200
    /**
201
     * Calculate the maximum padding width for a set of lines.
202
     *
203
     * @return int
204
     */
205
    private function getMaxWidth(): int
206
    {
207
        $max = 0;
208
 
209
        foreach ($this->getOptions() as $option) {
210
            $nameLength = \strlen($option->getName()) + 2;
211
            if ($option->getShortcut()) {
212
                $nameLength += \strlen($option->getShortcut()) + 3;
213
            }
214
 
215
            $max = \max($max, $nameLength);
216
        }
217
 
218
        foreach ($this->getArguments() as $argument) {
219
            $max = \max($max, \strlen($argument->getName()));
220
        }
221
 
222
        return ++$max;
223
    }
224
 
225
    /**
226
     * Format an option default as text.
227
     *
228
     * @param mixed $default
229
     *
230
     * @return string
231
     */
232
    private function formatDefaultValue($default): string
233
    {
234
        if (\is_array($default) && $default === \array_values($default)) {
235
            return \sprintf("['%s']", \implode("', '", $default));
236
        }
237
 
238
        return \str_replace("\n", '', \var_export($default, true));
239
    }
240
 
241
    /**
242
     * Get a Table instance.
243
     *
244
     * Falls back to legacy TableHelper.
245
     *
246
     * @return Table|TableHelper
247
     */
248
    protected function getTable(OutputInterface $output)
249
    {
250
        if (!\class_exists(Table::class)) {
251
            return $this->getTableHelper();
252
        }
253
 
254
        $style = new TableStyle();
255
 
256
        // Symfony 4.1 deprecated single-argument style setters.
257
        if (\method_exists($style, 'setVerticalBorderChars')) {
258
            $style->setVerticalBorderChars(' ');
259
            $style->setHorizontalBorderChars('');
260
            $style->setCrossingChars('', '', '', '', '', '', '', '', '');
261
        } else {
262
            $style->setVerticalBorderChar(' ');
263
            $style->setHorizontalBorderChar('');
264
            $style->setCrossingChar('');
265
        }
266
 
267
        $table = new Table($output);
268
 
269
        return $table
270
            ->setRows([])
271
            ->setStyle($style);
272
    }
273
 
274
    /**
275
     * Legacy fallback for getTable.
276
     *
277
     * @return TableHelper
278
     */
279
    protected function getTableHelper(): TableHelper
280
    {
281
        $table = $this->getApplication()->getHelperSet()->get('table');
282
 
283
        return $table
284
            ->setRows([])
285
            ->setLayout(TableHelper::LAYOUT_BORDERLESS)
286
            ->setHorizontalBorderChar('')
287
            ->setCrossingChar('');
288
    }
289
}