Passed
Push — master ( ad6b2a...b41ca0 )
by Caen
07:45 queued 14s
created

InteractivePublishCommandHelper::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 8
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Console\Helpers;
6
7
use Hyde\Facades\Filesystem;
8
use Illuminate\Support\Arr;
9
use Illuminate\Support\Str;
10
11
/**
12
 * @internal This class offloads logic from the PublishViewsCommand class and should not be used elsewhere.
13
 */
14
class InteractivePublishCommandHelper
15
{
16
    /** @var array<string, string> Map of source files to target files */
17
    protected array $publishableFilesMap;
18
19
    protected readonly int $originalFileCount;
20
21
    /** @param  array<string, string>  $publishableFilesMap */
22
    public function __construct(array $publishableFilesMap)
23
    {
24
        $this->publishableFilesMap = $publishableFilesMap;
25
        $this->originalFileCount = count($publishableFilesMap);
0 ignored issues
show
Bug introduced by
The property originalFileCount is declared read-only in Hyde\Console\Helpers\Int...ivePublishCommandHelper.
Loading history...
26
    }
27
28
    /** @return array<string, string> */
29
    public function getFileChoices(): array
30
    {
31
        return Arr::mapWithKeys($this->publishableFilesMap, /** @return array<string, string> */ function (string $target, string $source): array {
32
            return [$source => $this->pathRelativeToDirectory($source, $this->getBaseDirectory())];
33
        });
34
    }
35
36
    /**
37
     * Only publish the selected files.
38
     *
39
     * @param  array<string>  $selectedFiles  Array of selected file paths, matching the keys of the publishableFilesMap.
40
     */
41
    public function only(array $selectedFiles): void
42
    {
43
        $this->publishableFilesMap = Arr::only($this->publishableFilesMap, $selectedFiles);
44
    }
45
46
    /** Find the most specific common parent directory path for the files, trimming as much as possible whilst keeping specificity and uniqueness. */
47
    public function getBaseDirectory(): string
48
    {
49
        $partsMap = collect($this->publishableFilesMap)->map(function (string $file): array {
0 ignored issues
show
Bug introduced by
$this->publishableFilesMap of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

49
        $partsMap = collect(/** @scrutinizer ignore-type */ $this->publishableFilesMap)->map(function (string $file): array {
Loading history...
50
            return explode('/', $file);
51
        });
52
53
        $commonParts = $partsMap->reduce(function (array $carry, array $parts): array {
54
            return array_intersect($carry, $parts);
55
        }, $partsMap->first());
56
57
        return implode('/', $commonParts);
58
    }
59
60
    public function publishFiles(): void
61
    {
62
        foreach ($this->publishableFilesMap as $source => $target) {
63
            Filesystem::ensureDirectoryExists(dirname($target));
64
            Filesystem::copy($source, $target);
65
        }
66
    }
67
68
    public function formatOutput(string $group): string
69
    {
70
        $fileCount = count($this->publishableFilesMap);
71
        $publishedOneFile = $fileCount === 1;
72
        $publishedAllGroups = $group === 'all';
73
        $publishedAllFiles = $fileCount === $this->originalFileCount;
74
        $selectedFilesModifier = $publishedAllFiles ? 'all' : 'selected';
75
76
        return match (true) {
77
            $publishedAllGroups => sprintf('Published all %d files to [%s]', $fileCount, $this->getBaseDirectory()),
78
            $publishedOneFile => sprintf('Published selected file to [%s]', reset($this->publishableFilesMap)),
79
            default => sprintf('Published %s [%s] files to [%s]', $selectedFilesModifier, Str::singular($group), $this->getBaseDirectory())
80
        };
81
    }
82
83
    protected function pathRelativeToDirectory(string $source, string $directory): string
84
    {
85
        return Str::after($source, basename($directory).'/');
86
    }
87
}
88