Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | 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
 *
200 lars 6
 * (c) 2012-2023 Justin Hileman
148 lars 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
     *
200 lars 89
     * @return string[]
148 lars 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
     *
200 lars 111
     * @return string[]
148 lars 112
     */
113
    protected function getHiddenOptions(): array
114
    {
115
        return ['verbose'];
116
    }
117
 
118
    /**
119
     * Format command aliases as text..
120
     */
121
    private function aliasesAsText(): string
122
    {
123
        return '<comment>Aliases:</comment> <info>'.\implode(', ', $this->getAliases()).'</info>'.\PHP_EOL;
124
    }
125
 
126
    /**
127
     * Format command arguments as text.
128
     */
129
    private function argumentsAsText(): string
130
    {
131
        $max = $this->getMaxWidth();
132
        $messages = [];
133
 
134
        $arguments = $this->getArguments();
135
        if (!empty($arguments)) {
136
            $messages[] = '<comment>Arguments:</comment>';
137
            foreach ($arguments as $argument) {
138
                if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) {
139
                    $default = \sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($argument->getDefault()));
140
                } else {
141
                    $default = '';
142
                }
143
 
144
                $description = \str_replace("\n", "\n".\str_pad('', $max + 2, ' '), $argument->getDescription());
145
 
146
                $messages[] = \sprintf(" <info>%-{$max}s</info> %s%s", $argument->getName(), $description, $default);
147
            }
148
 
149
            $messages[] = '';
150
        }
151
 
152
        return \implode(\PHP_EOL, $messages);
153
    }
154
 
155
    /**
156
     * Format options as text.
157
     */
158
    private function optionsAsText(): string
159
    {
160
        $max = $this->getMaxWidth();
161
        $messages = [];
162
 
163
        $options = $this->getOptions();
164
        if ($options) {
165
            $messages[] = '<comment>Options:</comment>';
166
 
167
            foreach ($options as $option) {
168
                if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) {
169
                    $default = \sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($option->getDefault()));
170
                } else {
171
                    $default = '';
172
                }
173
 
174
                $multiple = $option->isArray() ? '<comment> (multiple values allowed)</comment>' : '';
175
                $description = \str_replace("\n", "\n".\str_pad('', $max + 2, ' '), $option->getDescription());
176
 
177
                $optionMax = $max - \strlen($option->getName()) - 2;
178
                $messages[] = \sprintf(
179
                    " <info>%s</info> %-{$optionMax}s%s%s%s",
180
                    '--'.$option->getName(),
181
                    $option->getShortcut() ? \sprintf('(-%s) ', $option->getShortcut()) : '',
182
                    $description,
183
                    $default,
184
                    $multiple
185
                );
186
            }
187
 
188
            $messages[] = '';
189
        }
190
 
191
        return \implode(\PHP_EOL, $messages);
192
    }
193
 
194
    /**
195
     * Calculate the maximum padding width for a set of lines.
196
     */
197
    private function getMaxWidth(): int
198
    {
199
        $max = 0;
200
 
201
        foreach ($this->getOptions() as $option) {
202
            $nameLength = \strlen($option->getName()) + 2;
203
            if ($option->getShortcut()) {
204
                $nameLength += \strlen($option->getShortcut()) + 3;
205
            }
206
 
207
            $max = \max($max, $nameLength);
208
        }
209
 
210
        foreach ($this->getArguments() as $argument) {
211
            $max = \max($max, \strlen($argument->getName()));
212
        }
213
 
214
        return ++$max;
215
    }
216
 
217
    /**
218
     * Format an option default as text.
219
     *
220
     * @param mixed $default
221
     */
222
    private function formatDefaultValue($default): string
223
    {
224
        if (\is_array($default) && $default === \array_values($default)) {
225
            return \sprintf("['%s']", \implode("', '", $default));
226
        }
227
 
228
        return \str_replace("\n", '', \var_export($default, true));
229
    }
230
 
231
    /**
232
     * Get a Table instance.
233
     *
234
     * Falls back to legacy TableHelper.
235
     *
236
     * @return Table|TableHelper
237
     */
238
    protected function getTable(OutputInterface $output)
239
    {
240
        if (!\class_exists(Table::class)) {
241
            return $this->getTableHelper();
242
        }
243
 
244
        $style = new TableStyle();
245
 
246
        // Symfony 4.1 deprecated single-argument style setters.
247
        if (\method_exists($style, 'setVerticalBorderChars')) {
248
            $style->setVerticalBorderChars(' ');
249
            $style->setHorizontalBorderChars('');
250
            $style->setCrossingChars('', '', '', '', '', '', '', '', '');
251
        } else {
252
            $style->setVerticalBorderChar(' ');
253
            $style->setHorizontalBorderChar('');
254
            $style->setCrossingChar('');
255
        }
256
 
257
        $table = new Table($output);
258
 
259
        return $table
260
            ->setRows([])
261
            ->setStyle($style);
262
    }
263
 
264
    /**
265
     * Legacy fallback for getTable.
266
     */
267
    protected function getTableHelper(): TableHelper
268
    {
269
        $table = $this->getApplication()->getHelperSet()->get('table');
270
 
271
        return $table
272
            ->setRows([])
273
            ->setLayout(TableHelper::LAYOUT_BORDERLESS)
274
            ->setHorizontalBorderChar('')
275
            ->setCrossingChar('');
276
    }
277
}