diff --git a/src/Flysystem/Plugin/Stat.php b/src/Flysystem/Plugin/Stat.php index 94bd492..39ef289 100644 --- a/src/Flysystem/Plugin/Stat.php +++ b/src/Flysystem/Plugin/Stat.php @@ -139,6 +139,38 @@ protected function getWithMetadata($path, array $ignore) return $metadata; } + /** + * Normalize a permissions string. + * + * @param string $permissions + * + * @return int + */ + protected function normalizePermissions($permissions) + { + if (is_numeric($permissions)) { + return $permissions & 0777; + } + + // remove the type identifier + $permissions = substr($permissions, 1); + + // map the string rights to the numeric counterparts + $map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1']; + $permissions = strtr($permissions, $map); + + // split up the permission groups + $parts = str_split($permissions, 3); + + // convert the groups + $mapper = function ($part) { + return array_sum(str_split($part)); + }; + + // converts to decimal number + return octdec(implode('', array_map($mapper, $parts))); + } + /** * Merges the available metadata from Filesystem::getMetadata(). * @@ -154,7 +186,11 @@ protected function mergeMeta(array $metadata) $ret['gid'] = $this->uid->getGid(); $ret['mode'] = $metadata['type'] === 'dir' ? 040000 : 0100000; - $ret['mode'] += $this->permissions[$metadata['type']][$metadata['visibility']]; + $visibility = $metadata['visibility']; + if ($visibility != AdapterInterface::VISIBILITY_PUBLIC && $visibility != AdapterInterface::VISIBILITY_PRIVATE) { + $visibility = $this->normalizePermissions($visibility) & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE; + } + $ret['mode'] += $this->permissions[$metadata['type']][$visibility]; if (isset($metadata['size'])) { $ret['size'] = (int) $metadata['size'];