Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Foundation\Console;
4
 
5
use Illuminate\Console\Command;
6
use Illuminate\Support\Composer;
7
use Illuminate\Support\Str;
8
use Symfony\Component\Console\Attribute\AsCommand;
9
 
10
#[AsCommand(name: 'about')]
11
class AboutCommand extends Command
12
{
13
    /**
14
     * The console command signature.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'about {--only= : The section to display}
19
                {--json : Output the information as JSON}';
20
 
21
    /**
22
     * The name of the console command.
23
     *
24
     * This name is used to identify the command during lazy loading.
25
     *
26
     * @var string|null
27
     *
28
     * @deprecated
29
     */
30
    protected static $defaultName = 'about';
31
 
32
    /**
33
     * The console command description.
34
     *
35
     * @var string
36
     */
37
    protected $description = 'Display basic information about your application';
38
 
39
    /**
40
     * The Composer instance.
41
     *
42
     * @var \Illuminate\Support\Composer
43
     */
44
    protected $composer;
45
 
46
    /**
47
     * The data to display.
48
     *
49
     * @var array
50
     */
51
    protected static $data = [];
52
 
53
    /**
54
     * The registered callables that add custom data to the command output.
55
     *
56
     * @var array
57
     */
58
    protected static $customDataResolvers = [];
59
 
60
    /**
61
     * Create a new command instance.
62
     *
63
     * @param  \Illuminate\Support\Composer  $composer
64
     * @return void
65
     */
66
    public function __construct(Composer $composer)
67
    {
68
        parent::__construct();
69
 
70
        $this->composer = $composer;
71
    }
72
 
73
    /**
74
     * Execute the console command.
75
     *
76
     * @return int
77
     */
78
    public function handle()
79
    {
80
        $this->gatherApplicationInformation();
81
 
82
        collect(static::$data)
83
            ->map(fn ($items) => collect($items)
84
                ->map(function ($value) {
85
                    if (is_array($value)) {
86
                        return [$value];
87
                    }
88
 
89
                    if (is_string($value)) {
90
                        $value = $this->laravel->make($value);
91
                    }
92
 
93
                    return collect($this->laravel->call($value))
94
                        ->map(fn ($value, $key) => [$key, $value])
95
                        ->values()
96
                        ->all();
97
                })->flatten(1)
98
            )
99
            ->sortBy(function ($data, $key) {
100
                $index = array_search($key, ['Environment', 'Cache', 'Drivers']);
101
 
102
                return $index === false ? 99 : $index;
103
            })
104
            ->filter(function ($data, $key) {
105
                return $this->option('only') ? in_array(Str::of($key)->lower()->snake(), $this->sections()) : true;
106
            })
107
            ->pipe(fn ($data) => $this->display($data));
108
 
109
        $this->newLine();
110
 
111
        return 0;
112
    }
113
 
114
    /**
115
     * Display the application information.
116
     *
117
     * @param  \Illuminate\Support\Collection  $data
118
     * @return void
119
     */
120
    protected function display($data)
121
    {
122
        $this->option('json') ? $this->displayJson($data) : $this->displayDetail($data);
123
    }
124
 
125
    /**
126
     * Display the application information as a detail view.
127
     *
128
     * @param  \Illuminate\Support\Collection  $data
129
     * @return void
130
     */
131
    protected function displayDetail($data)
132
    {
133
        $data->each(function ($data, $section) {
134
            $this->newLine();
135
 
136
            $this->components->twoColumnDetail('  <fg=green;options=bold>'.$section.'</>');
137
 
138
            $data->pipe(fn ($data) => $section !== 'Environment' ? $data->sort() : $data)->each(function ($detail) {
139
                [$label, $value] = $detail;
140
 
141
                $this->components->twoColumnDetail($label, value($value));
142
            });
143
        });
144
    }
145
 
146
    /**
147
     * Display the application information as JSON.
148
     *
149
     * @param  \Illuminate\Support\Collection  $data
150
     * @return void
151
     */
152
    protected function displayJson($data)
153
    {
154
        $output = $data->flatMap(function ($data, $section) {
155
            return [(string) Str::of($section)->snake() => $data->mapWithKeys(fn ($item, $key) => [(string) Str::of($item[0])->lower()->snake() => value($item[1])])];
156
        });
157
 
158
        $this->output->writeln(strip_tags(json_encode($output)));
159
    }
160
 
161
    /**
162
     * Gather information about the application.
163
     *
164
     * @return void
165
     */
166
    protected function gatherApplicationInformation()
167
    {
168
        static::addToSection('Environment', fn () => [
169
            'Application Name' => config('app.name'),
170
            'Laravel Version' => $this->laravel->version(),
171
            'PHP Version' => phpversion(),
172
            'Composer Version' => $this->composer->getVersion() ?? '<fg=yellow;options=bold>-</>',
173
            'Environment' => $this->laravel->environment(),
174
            'Debug Mode' => config('app.debug') ? '<fg=yellow;options=bold>ENABLED</>' : 'OFF',
175
            'URL' => Str::of(config('app.url'))->replace(['http://', 'https://'], ''),
176
            'Maintenance Mode' => $this->laravel->isDownForMaintenance() ? '<fg=yellow;options=bold>ENABLED</>' : 'OFF',
177
        ]);
178
 
179
        static::addToSection('Cache', fn () => [
180
            'Config' => $this->laravel->configurationIsCached() ? '<fg=green;options=bold>CACHED</>' : '<fg=yellow;options=bold>NOT CACHED</>',
181
            'Events' => $this->laravel->eventsAreCached() ? '<fg=green;options=bold>CACHED</>' : '<fg=yellow;options=bold>NOT CACHED</>',
182
            'Routes' => $this->laravel->routesAreCached() ? '<fg=green;options=bold>CACHED</>' : '<fg=yellow;options=bold>NOT CACHED</>',
183
            'Views' => $this->hasPhpFiles($this->laravel->storagePath('framework/views')) ? '<fg=green;options=bold>CACHED</>' : '<fg=yellow;options=bold>NOT CACHED</>',
184
        ]);
185
 
186
        $logChannel = config('logging.default');
187
 
188
        if (config('logging.channels.'.$logChannel.'.driver') === 'stack') {
189
            $secondary = collect(config('logging.channels.'.$logChannel.'.channels'))
190
                ->implode(', ');
191
 
192
            $logs = '<fg=yellow;options=bold>'.$logChannel.'</> <fg=gray;options=bold>/</> '.$secondary;
193
        } else {
194
            $logs = $logChannel;
195
        }
196
 
197
        static::addToSection('Drivers', fn () => array_filter([
198
            'Broadcasting' => config('broadcasting.default'),
199
            'Cache' => config('cache.default'),
200
            'Database' => config('database.default'),
201
            'Logs' => $logs,
202
            'Mail' => config('mail.default'),
203
            'Octane' => config('octane.server'),
204
            'Queue' => config('queue.default'),
205
            'Scout' => config('scout.driver'),
206
            'Session' => config('session.driver'),
207
        ]));
208
 
209
        collect(static::$customDataResolvers)->each->__invoke();
210
    }
211
 
212
    /**
213
     * Determine whether the given directory has PHP files.
214
     *
215
     * @param  string  $path
216
     * @return bool
217
     */
218
    protected function hasPhpFiles(string $path): bool
219
    {
220
        return count(glob($path.'/*.php')) > 0;
221
    }
222
 
223
    /**
224
     * Add additional data to the output of the "about" command.
225
     *
226
     * @param  string  $section
227
     * @param  callable|string|array  $data
228
     * @param  string|null  $value
229
     * @return void
230
     */
231
    public static function add(string $section, $data, string $value = null)
232
    {
233
        static::$customDataResolvers[] = fn () => static::addToSection($section, $data, $value);
234
    }
235
 
236
    /**
237
     * Add additional data to the output of the "about" command.
238
     *
239
     * @param  string  $section
240
     * @param  callable|string|array  $data
241
     * @param  string|null  $value
242
     * @return void
243
     */
244
    protected static function addToSection(string $section, $data, string $value = null)
245
    {
246
        if (is_array($data)) {
247
            foreach ($data as $key => $value) {
248
                self::$data[$section][] = [$key, $value];
249
            }
250
        } elseif (is_callable($data) || ($value === null && class_exists($data))) {
251
            self::$data[$section][] = $data;
252
        } else {
253
            self::$data[$section][] = [$data, $value];
254
        }
255
    }
256
 
257
    /**
258
     * Get the sections provided to the command.
259
     *
260
     * @return array
261
     */
262
    protected function sections()
263
    {
264
        return array_filter(explode(',', $this->option('only') ?? ''));
265
    }
266
}