1<?php
2
3declare(strict_types=1);
4
5namespace League\Flysystem\UnixVisibility;
6
7use League\Flysystem\PortableVisibilityGuard;
8use League\Flysystem\Visibility;
9
10class PortableVisibilityConverter implements VisibilityConverter
11{
12    /**
13     * @var int
14     */
15    private $filePublic;
16
17    /**
18     * @var int
19     */
20    private $filePrivate;
21
22    /**
23     * @var int
24     */
25    private $directoryPublic;
26
27    /**
28     * @var int
29     */
30    private $directoryPrivate;
31
32    /**
33     * @var string
34     */
35    private $defaultForDirectories;
36
37    public function __construct(
38        int $filePublic = 0644,
39        int $filePrivate = 0600,
40        int $directoryPublic = 0755,
41        int $directoryPrivate = 0700,
42        string $defaultForDirectories = Visibility::PRIVATE
43    ) {
44        $this->filePublic = $filePublic;
45        $this->filePrivate = $filePrivate;
46        $this->directoryPublic = $directoryPublic;
47        $this->directoryPrivate = $directoryPrivate;
48        $this->defaultForDirectories = $defaultForDirectories;
49    }
50
51    public function forFile(string $visibility): int
52    {
53        PortableVisibilityGuard::guardAgainstInvalidInput($visibility);
54
55        return $visibility === Visibility::PUBLIC
56            ? $this->filePublic
57            : $this->filePrivate;
58    }
59
60    public function forDirectory(string $visibility): int
61    {
62        PortableVisibilityGuard::guardAgainstInvalidInput($visibility);
63
64        return $visibility === Visibility::PUBLIC
65            ? $this->directoryPublic
66            : $this->directoryPrivate;
67    }
68
69    public function inverseForFile(int $visibility): string
70    {
71        if ($visibility === $this->filePublic) {
72            return Visibility::PUBLIC;
73        } elseif ($visibility === $this->filePrivate) {
74            return Visibility::PRIVATE;
75        }
76
77        return Visibility::PUBLIC; // default
78    }
79
80    public function inverseForDirectory(int $visibility): string
81    {
82        if ($visibility === $this->directoryPublic) {
83            return Visibility::PUBLIC;
84        } elseif ($visibility === $this->directoryPrivate) {
85            return Visibility::PRIVATE;
86        }
87
88        return Visibility::PUBLIC; // default
89    }
90
91    public function defaultForDirectories(): int
92    {
93        return $this->defaultForDirectories === Visibility::PUBLIC ? $this->directoryPublic : $this->directoryPrivate;
94    }
95
96    /**
97     * @param array<mixed>  $permissionMap
98     */
99    public static function fromArray(array $permissionMap, string $defaultForDirectories = Visibility::PRIVATE): PortableVisibilityConverter
100    {
101        return new PortableVisibilityConverter(
102            $permissionMap['file']['public'] ?? 0644,
103            $permissionMap['file']['private'] ?? 0600,
104            $permissionMap['dir']['public'] ?? 0755,
105            $permissionMap['dir']['private'] ?? 0700,
106            $defaultForDirectories
107        );
108    }
109}
110