ListStorage::listDirectory()   F
last analyzed

Complexity

Conditions 17
Paths 333

Size

Total Lines 96
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 17
eloc 44
c 2
b 1
f 0
nc 333
nop 4
dl 0
loc 96
rs 2.7208

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Consilience\Laravel\Ls\Console\Commands;
4
5
/**
6
 *
7
 */
8
9
use Illuminate\Console\Command;
0 ignored issues
show
Bug introduced by
The type Illuminate\Console\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Illuminate\Support\Facades\Storage;
11
use DateTimeInterface;
12
use DateTimeImmutable;
13
use DateTimeZone;
14
use Throwable;
15
16
class ListStorage extends Command
17
{
18
    /**
19
     * flyssytem object types, because flysystem does not have its own
20
     * constants for these.
21
     */
22
    const TYPE_DIR = 'dir';
23
    const TYPE_FILE = 'file';
24
25
    /**
26
     * Counts up the number of objects (files or directories) fetched.
27
     * Used for output formatting.
28
     */
29
    protected $dirIndex = 0;
30
31
    protected $signature = 'storage:ls
32
        {directory? : list a given directory}
33
        {--d|disk= : select the filesystem disk}
34
        {--l|long : long format}
35
        {--R|recursive : list subdirectories recursively}';
36
37
    protected $description = 'List the contents of a file storage disk';
38
39
    public function handle()
40
    {
41
        $disks = config('filesystems.disks');
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

41
        $disks = /** @scrutinizer ignore-call */ config('filesystems.disks');
Loading history...
42
43
        if ($disks === null) {
44
            $this->error('No disks defined on this system');
45
            return 1;
46
        }
47
48
        $selectedDir = $this->argument('directory') ?? '/';
49
50
        $selectedDisk = $this->option('disk') ?? '';
51
        $defaultDisk = config('filesystems.default');
52
53
        if ($selectedDisk === ''  && strpos($selectedDir, ':') !== false) {
54
            // User may be using the "disk:directory" format.
55
56
            [$diskSplit, $dirSplit] = explode(':', $selectedDir);
57
58
            if (array_key_exists($diskSplit, $disks)) {
59
                $selectedDisk = $diskSplit;
60
                $selectedDir = $dirSplit;
61
            }
62
        }
63
64
        if ($selectedDisk !== '' && ! array_key_exists($selectedDisk, $disks)) {
65
            $this->error(sprintf('Selected disk "%s" does not exist', $selectedDisk));
66
            $selectedDisk = '';
67
        }
68
69
        if ($selectedDisk === '') {
70
            $this->info('Available disks:');
71
72
            $this->table(
73
                ['name', 'driver'],
74
                collect($disks)->map(function ($disk, $name) use ($defaultDisk) {
75
                    return [
76
                        $name . ($defaultDisk === $name ? ' [*]' : ''),
77
                        $disk['driver'] ?? 'unknown',
78
                    ];
79
                })
80
            );
81
            return;
82
        }
83
84
        $recursive = $this->option('recursive');
85
        $longFormat = $this->option('long');
86
87
        $this->listDirectory($selectedDisk, $selectedDir, $recursive, $longFormat);
88
    }
89
90
    /**
91
     * List the contents of one directory and recurse if necessary.
92
     *
93
     * @param string $disk the name of the laravel filessystem disk
94
     * @param string $directory the path from the root of the disk, leading "/" optional
95
     * @param bool $recursive true to recurse into sub-directories
96
     * @param bool $longFormat true to output long format, with sizes and timestamps
97
     *
98
     * @return void
99
     */
100
    protected function listDirectory(
101
        string $disk,
102
        string $directory,
103
        bool $recursive,
104
        bool $longFormat
105
    ) {
106
        $content = Storage::disk($disk)->listContents($directory);
0 ignored issues
show
Bug introduced by
The method listContents() does not exist on Illuminate\Contracts\Filesystem\Filesystem. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

106
        $content = Storage::disk($disk)->/** @scrutinizer ignore-call */ listContents($directory);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
107
108
        // If we are recursing into subdirectories, then display the directory
109
        // before listing the contents.
110
        // Precede with a blank line after the first directory.
111
112
        if ($recursive) {
113
            if ($this->dirIndex) {
114
                $this->line('');
115
            }
116
117
            $this->dirIndex++;
118
119
            $this->line($directory . ':');
120
        }
121
122
        // To collect directories as we go through.
123
124
        $subDirs = [];
125
126
        $dt = new DateTimeImmutable();
127
128
        foreach ($content as $item) {
129
            $basename = $item['basename'] ?? 'unknown';
130
            $dirname = $item['dirname'] ?? '/';
131
132
            $pathname = $dirname . '/' . $basename;
133
134
            $size = $item['size'] ?? 0;
135
136
            $type = $item['type'] ?? static::TYPE_FILE;
137
138
            // Some drivers do not supply the file size by default,
139
            // so make another call to get it.
140
141
            if ($size === 0 && $type === static::TYPE_FILE && $longFormat) {
142
                try {
143
                    $size = Storage::disk($disk)->getSize($pathname);
0 ignored issues
show
Bug introduced by
The method getSize() does not exist on Illuminate\Contracts\Filesystem\Filesystem. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

143
                    $size = Storage::disk($disk)->/** @scrutinizer ignore-call */ getSize($pathname);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
144
                } catch (Throwable $e) {
145
                    // Some drivers throw exceptions in some circumstances.
146
                    // We just catch and ignore.
147
                }
148
            }
149
150
            // Format the timestamp if present.
151
            // Just going down the seconds for now, and UTC is implied.
152
153
            $timestamp = $item['timestamp'] ?? null;
154
155
            if ($timestamp !== null) {
156
                $datetime = $dt
157
                    ->setTimezone(new DateTimeZone('UTC'))
158
                    ->setTimestamp($timestamp)
159
                    ->format('Y-m-d H:i:s');
160
            } else {
161
                $datetime = '';
162
            }
163
164
            // Two output formats at present: long and not long.
165
166
            if ($longFormat) {
167
                $this->line(sprintf(
168
                    '%1s %10d %s %s',
169
                    $type === static::TYPE_DIR ? 'd' : '-',
170
                    $size,
171
                    $datetime,
172
                    $basename
173
                ));
174
            } else {
175
                $message = sprintf('%s', $basename);
176
177
                if ($type === static::TYPE_FILE) {
178
                    $this->info($message);
179
                } else {
180
                    $this->warn($message);
181
                }
182
            }
183
184
            // Collect the list of sub-directories as we go through.
185
186
            if ($recursive && $type === static::TYPE_DIR) {
187
                $subDirs[] = $pathname;
188
            }
189
        }
190
191
        // If recursing, go through the sub-directories collected.
192
193
        if ($recursive && $subDirs) {
0 ignored issues
show
introduced by
$subDirs is of type array|string[], thus it always evaluated to false.
Loading history...
194
            foreach ($subDirs as $subDir) {
195
                $this->listDirectory($disk, $subDir, $recursive, $longFormat);
196
            }
197
        }
198
    }
199
}
200