more type hints

This commit is contained in:
Robin Appelman 2021-03-09 18:01:42 +01:00
commit e9f6d00a93
28 changed files with 343 additions and 530 deletions

View file

@ -54,7 +54,7 @@ abstract class AbstractServer implements IServer {
* @param ITimeZoneProvider $timeZoneProvider
* @param IOptions $options
*/
public function __construct($host, IAuth $auth, ISystem $system, ITimeZoneProvider $timeZoneProvider, IOptions $options) {
public function __construct(string $host, IAuth $auth, ISystem $system, ITimeZoneProvider $timeZoneProvider, IOptions $options) {
$this->host = $host;
$this->auth = $auth;
$this->system = $system;
@ -62,23 +62,23 @@ abstract class AbstractServer implements IServer {
$this->options = $options;
}
public function getAuth() {
public function getAuth(): IAuth {
return $this->auth;
}
public function getHost() {
public function getHost(): string {
return $this->host;
}
public function getTimeZone() {
public function getTimeZone(): string {
return $this->timezoneProvider->get($this->host);
}
public function getSystem() {
public function getSystem(): ISystem {
return $this->system;
}
public function getOptions() {
public function getOptions(): IOptions {
return $this->options;
}
}

View file

@ -22,19 +22,19 @@
namespace Icewind\SMB;
class AnonymousAuth implements IAuth {
public function getUsername() {
public function getUsername(): ?string {
return null;
}
public function getWorkgroup() {
public function getWorkgroup(): ?string {
return 'dummy';
}
public function getPassword() {
public function getPassword(): ?string {
return null;
}
public function getExtraCommandLineArguments() {
public function getExtraCommandLineArguments(): string {
return '-N';
}

View file

@ -29,32 +29,25 @@ class BasicAuth implements IAuth {
/** @var string */
private $password;
/**
* BasicAuth constructor.
*
* @param string $username
* @param string $workgroup
* @param string $password
*/
public function __construct($username, $workgroup, $password) {
public function __construct(string $username, string $workgroup, string $password) {
$this->username = $username;
$this->workgroup = $workgroup;
$this->password = $password;
}
public function getUsername() {
public function getUsername(): ?string {
return $this->username;
}
public function getWorkgroup() {
public function getWorkgroup(): ?string {
return $this->workgroup;
}
public function getPassword() {
public function getPassword(): ?string {
return $this->password;
}
public function getExtraCommandLineArguments() {
public function getExtraCommandLineArguments(): string {
return ($this->workgroup) ? '-W ' . escapeshellarg($this->workgroup) : '';
}

View file

@ -8,7 +8,7 @@
namespace Icewind\SMB\Exception;
class Exception extends \Exception {
public static function unknown($path, $error) {
public static function unknown(?string $path, $error) {
$message = 'Unknown error (' . $error . ')';
if ($path) {
$message .= ' for ' . $path;
@ -17,13 +17,7 @@ class Exception extends \Exception {
return new Exception($message, is_string($error) ? 0 : $error);
}
/**
* @param array $exceptionMap
* @param mixed $error
* @param string $path
* @return Exception
*/
public static function fromMap(array $exceptionMap, $error, $path) {
public static function fromMap(array $exceptionMap, $error, ?string $path): Exception {
if (isset($exceptionMap[$error])) {
$exceptionClass = $exceptionMap[$error];
if (is_numeric($error)) {

View file

@ -22,27 +22,18 @@
namespace Icewind\SMB;
interface IAuth {
/**
* @return string|null
*/
public function getUsername();
public function getUsername(): ?string;
/**
* @return string|null
*/
public function getWorkgroup();
public function getWorkgroup(): ?string;
/**
* @return string|null
*/
public function getPassword();
public function getPassword(): ?string;
/**
* Any extra command line option for smbclient that are required
*
* @return string
*/
public function getExtraCommandLineArguments();
public function getExtraCommandLineArguments(): string;
/**
* Set any extra options for libsmbclient that are required

View file

@ -21,50 +21,23 @@ interface IFileInfo {
const MODE_ARCHIVE = 0x20;
const MODE_NORMAL = 0x80;
/**
* @return string
*/
public function getPath();
public function getPath(): string;
/**
* @return string
*/
public function getName();
public function getName(): string;
/**
* @return int
*/
public function getSize();
public function getSize(): int;
/**
* @return int
*/
public function getMTime();
public function getMTime(): int;
/**
* @return bool
*/
public function isDirectory();
public function isDirectory(): bool;
/**
* @return bool
*/
public function isReadOnly();
public function isReadOnly(): bool;
/**
* @return bool
*/
public function isHidden();
public function isHidden(): bool;
/**
* @return bool
*/
public function isSystem();
public function isSystem(): bool;
/**
* @return bool
*/
public function isArchived();
public function isArchived(): bool;
/**
* @return ACL[]

View file

@ -25,7 +25,7 @@ interface INotifyHandler {
*
* @return Change[]
*/
public function getChanges();
public function getChanges(): array;
/**
* Listen actively to all incoming changes
@ -34,7 +34,7 @@ interface INotifyHandler {
*
* @param callable $callback
*/
public function listen($callback);
public function listen(callable $callback): void;
/**
* Stop listening for changes

View file

@ -22,15 +22,9 @@
namespace Icewind\SMB;
interface IServer {
/**
* @return IAuth
*/
public function getAuth();
public function getAuth(): IAuth;
/**
* @return string
*/
public function getHost();
public function getHost(): string;
/**
* @return \Icewind\SMB\IShare[]
@ -38,32 +32,15 @@ interface IServer {
* @throws \Icewind\SMB\Exception\AuthenticationException
* @throws \Icewind\SMB\Exception\InvalidHostException
*/
public function listShares();
public function listShares(): array;
/**
* @param string $name
* @return \Icewind\SMB\IShare
*/
public function getShare($name);
public function getShare(string $name): IShare;
/**
* @return string
*/
public function getTimeZone();
public function getTimeZone(): string;
/**
* @return ISystem
*/
public function getSystem();
public function getSystem(): ISystem;
/**
* @return IOptions
*/
public function getOptions();
public function getOptions(): IOptions;
/**
* @param ISystem $system
* @return bool
*/
public static function available(ISystem $system);
public static function available(ISystem $system): bool;
}

View file

@ -7,13 +7,18 @@
namespace Icewind\SMB;
use Icewind\SMB\Exception\AlreadyExistsException;
use Icewind\SMB\Exception\InvalidRequestException;
use Icewind\SMB\Exception\InvalidTypeException;
use Icewind\SMB\Exception\NotFoundException;
interface IShare {
/**
* Get the name of the share
*
* @return string
*/
public function getName();
public function getName(): string;
/**
* Download a remote file
@ -22,10 +27,10 @@ interface IShare {
* @param string $target local file
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function get($source, $target);
public function get(string $source, string $target): bool;
/**
* Upload a local file
@ -34,10 +39,10 @@ interface IShare {
* @param string $target remove file
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function put($source, $target);
public function put(string $source, string $target): bool;
/**
* Open a readable stream top a remote file
@ -45,10 +50,10 @@ interface IShare {
* @param string $source
* @return resource a read only stream with the contents of the remote file
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function read($source);
public function read(string $source);
/**
* Open a writable stream to a remote file
@ -57,10 +62,10 @@ interface IShare {
* @param string $target
* @return resource a write only stream to upload a remote file
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function write($target);
public function write(string $target);
/**
* Open a writable stream to a remote file and set the cursor to the end of the file
@ -68,11 +73,11 @@ interface IShare {
* @param string $target
* @return resource a write only stream to upload a remote file
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws \Icewind\SMB\Exception\InvalidRequestException
* @throws NotFoundException
* @throws InvalidTypeException
* @throws InvalidRequestException
*/
public function append($target);
public function append(string $target);
/**
* Rename a remote file
@ -81,10 +86,10 @@ interface IShare {
* @param string $to
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\AlreadyExistsException
* @throws NotFoundException
* @throws AlreadyExistsException
*/
public function rename($from, $to);
public function rename(string $from, string $to): bool;
/**
* Delete a file on the share
@ -92,29 +97,29 @@ interface IShare {
* @param string $path
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function del($path);
public function del(string $path): bool;
/**
* List the content of a remote folder
*
* @param string $path
* @return \Icewind\SMB\IFileInfo[]
* @return IFileInfo[]
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function dir($path);
public function dir(string $path): array;
/**
* @param string $path
* @return \Icewind\SMB\IFileInfo
* @return IFileInfo
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws NotFoundException
*/
public function stat($path);
public function stat(string $path): IFileInfo;
/**
* Create a folder on the share
@ -122,10 +127,10 @@ interface IShare {
* @param string $path
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\AlreadyExistsException
* @throws NotFoundException
* @throws AlreadyExistsException
*/
public function mkdir($path);
public function mkdir(string $path): bool;
/**
* Remove a folder on the share
@ -133,23 +138,23 @@ interface IShare {
* @param string $path
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function rmdir($path);
public function rmdir(string $path): bool;
/**
* @param string $path
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
* @return mixed
*/
public function setMode($path, $mode);
public function setMode(string $path, int $mode);
/**
* @param string $path
* @return INotifyHandler
*/
public function notify($path);
public function notify(string $path);
/**
* Get the IServer instance for this share

View file

@ -32,47 +32,47 @@ interface ISystem {
* @param int $num the file descriptor id
* @return string
*/
public function getFD($num);
public function getFD(int $num): string;
/**
* Get the full path to the `smbclient` binary of false if the binary is not available
* Get the full path to the `smbclient` binary of null if the binary is not available
*
* @return string|bool
* @return string|null
*/
public function getSmbclientPath();
public function getSmbclientPath(): ?string;
/**
* Get the full path to the `net` binary of false if the binary is not available
* Get the full path to the `net` binary of null if the binary is not available
*
* @return string|bool
* @return string|null
*/
public function getNetPath();
public function getNetPath(): ?string;
/**
* Get the full path to the `smbcacls` binary of false if the binary is not available
* Get the full path to the `smbcacls` binary of null if the binary is not available
*
* @return string|bool
* @return string|null
*/
public function getSmbcAclsPath();
public function getSmbcAclsPath(): ?string;
/**
* Get the full path to the `stdbuf` binary of false if the binary is not available
* Get the full path to the `stdbuf` binary of null if the binary is not available
*
* @return string|bool
* @return string|null
*/
public function getStdBufPath();
public function getStdBufPath(): ?string;
/**
* Get the full path to the `date` binary of false if the binary is not available
* Get the full path to the `date` binary of null if the binary is not available
*
* @return string|bool
* @return string|null
*/
public function getDatePath();
public function getDatePath(): ?string;
/**
* Whether or not the smbclient php extension is enabled
*
* @return bool
*/
public function libSmbclientAvailable();
public function libSmbclientAvailable(): bool;
}

View file

@ -28,5 +28,5 @@ interface ITimeZoneProvider {
* @param string $host
* @return string
*/
public function get($host);
public function get(string $host): string;
}

View file

@ -25,19 +25,19 @@ namespace Icewind\SMB;
* Use existing kerberos ticket to authenticate
*/
class KerberosAuth implements IAuth {
public function getUsername() {
public function getUsername(): ?string {
return 'dummy';
}
public function getWorkgroup() {
public function getWorkgroup(): ?string {
return 'dummy';
}
public function getPassword() {
public function getPassword(): ?string {
return null;
}
public function getExtraCommandLineArguments() {
public function getExtraCommandLineArguments(): string {
return '-k';
}

View file

@ -11,55 +11,30 @@ use Icewind\SMB\ACL;
use Icewind\SMB\IFileInfo;
class NativeFileInfo implements IFileInfo {
/**
* @var string
*/
/** @var string */
protected $path;
/**
* @var string
*/
/** @var string */
protected $name;
/**
* @var NativeShare
*/
/** @var NativeShare */
protected $share;
/**
* @var array|null
*/
/** @var array|null */
protected $attributeCache = null;
/**
* @param NativeShare $share
* @param string $path
* @param string $name
*/
public function __construct($share, $path, $name) {
public function __construct(NativeShare $share, string $path, string $name) {
$this->share = $share;
$this->path = $path;
$this->name = $name;
}
/**
* @return string
*/
public function getPath() {
public function getPath(): string {
return $this->path;
}
/**
* @return string
*/
public function getName() {
public function getName(): string {
return $this->name;
}
/**
* @return array
*/
protected function stat() {
protected function stat(): array {
if (is_null($this->attributeCache)) {
$rawAttributes = explode(',', $this->share->getAttribute($this->path, 'system.dos_attr.*'));
$this->attributeCache = [];
@ -76,18 +51,12 @@ class NativeFileInfo implements IFileInfo {
return $this->attributeCache;
}
/**
* @return int
*/
public function getSize() {
public function getSize(): int {
$stat = $this->stat();
return $stat['size'];
}
/**
* @return int
*/
public function getMTime() {
public function getMTime(): int {
$stat = $this->stat();
return $stat['write_time'];
}
@ -104,10 +73,7 @@ class NativeFileInfo implements IFileInfo {
* as false (except for `hidden` where we use the unix dotfile convention)
*/
/**
* @return int
*/
protected function getMode() {
protected function getMode(): int {
$mode = $this->stat()['mode'];
// Let us ignore the ATTR_NOT_CONTENT_INDEXED for now
@ -116,10 +82,7 @@ class NativeFileInfo implements IFileInfo {
return $mode;
}
/**
* @return bool
*/
public function isDirectory() {
public function isDirectory(): bool {
$mode = $this->getMode();
if ($mode > 0x1000) {
return (bool)($mode & 0x4000); // 0x4000: unix directory flag
@ -128,10 +91,7 @@ class NativeFileInfo implements IFileInfo {
}
}
/**
* @return bool
*/
public function isReadOnly() {
public function isReadOnly(): bool {
$mode = $this->getMode();
if ($mode > 0x1000) {
return !(bool)($mode & 0x80); // 0x80: owner write permissions
@ -140,10 +100,7 @@ class NativeFileInfo implements IFileInfo {
}
}
/**
* @return bool
*/
public function isHidden() {
public function isHidden(): bool {
$mode = $this->getMode();
if ($mode > 0x1000) {
return strlen($this->name) > 0 && $this->name[0] === '.';
@ -152,10 +109,7 @@ class NativeFileInfo implements IFileInfo {
}
}
/**
* @return bool
*/
public function isSystem() {
public function isSystem(): bool {
$mode = $this->getMode();
if ($mode > 0x1000) {
return false;
@ -164,10 +118,7 @@ class NativeFileInfo implements IFileInfo {
}
}
/**
* @return bool
*/
public function isArchived() {
public function isArchived(): bool {
$mode = $this->getMode();
if ($mode > 0x1000) {
return false;

View file

@ -10,6 +10,7 @@ namespace Icewind\SMB\Native;
use Icewind\SMB\AbstractServer;
use Icewind\SMB\IAuth;
use Icewind\SMB\IOptions;
use Icewind\SMB\IShare;
use Icewind\SMB\ISystem;
use Icewind\SMB\ITimeZoneProvider;
@ -19,7 +20,7 @@ class NativeServer extends AbstractServer {
*/
protected $state;
public function __construct($host, IAuth $auth, ISystem $system, ITimeZoneProvider $timeZoneProvider, IOptions $options) {
public function __construct(string $host, IAuth $auth, ISystem $system, ITimeZoneProvider $timeZoneProvider, IOptions $options) {
parent::__construct($host, $auth, $system, $timeZoneProvider, $options);
$this->state = new NativeState();
}
@ -33,24 +34,20 @@ class NativeServer extends AbstractServer {
* @throws \Icewind\SMB\Exception\AuthenticationException
* @throws \Icewind\SMB\Exception\InvalidHostException
*/
public function listShares() {
public function listShares(): array {
$this->connect();
$shares = [];
$dh = $this->state->opendir('smb://' . $this->getHost());
while ($share = $this->state->readdir($dh)) {
while ($share = $this->state->readdir($dh, '')) {
if ($share['type'] === 'file share') {
$shares[] = $this->getShare($share['name']);
}
}
$this->state->closedir($dh);
$this->state->closedir($dh, '');
return $shares;
}
/**
* @param string $name
* @return \Icewind\SMB\IShare
*/
public function getShare($name) {
public function getShare(string $name): IShare {
return new NativeShare($this, $name);
}
@ -60,7 +57,7 @@ class NativeServer extends AbstractServer {
* @param ISystem $system
* @return bool
*/
public static function available(ISystem $system) {
public static function available(ISystem $system): bool {
return $system->libSmbclientAvailable();
}
}

View file

@ -8,9 +8,16 @@
namespace Icewind\SMB\Native;
use Icewind\SMB\AbstractShare;
use Icewind\SMB\Exception\AlreadyExistsException;
use Icewind\SMB\Exception\AuthenticationException;
use Icewind\SMB\Exception\ConnectionException;
use Icewind\SMB\Exception\DependencyException;
use Icewind\SMB\Exception\InvalidHostException;
use Icewind\SMB\Exception\InvalidPathException;
use Icewind\SMB\Exception\InvalidResourceException;
use Icewind\SMB\Exception\InvalidTypeException;
use Icewind\SMB\Exception\NotFoundException;
use Icewind\SMB\IFileInfo;
use Icewind\SMB\INotifyHandler;
use Icewind\SMB\IServer;
use Icewind\SMB\Wrapped\Server;
@ -32,22 +39,18 @@ class NativeShare extends AbstractShare {
*/
private $state;
/**
* @param IServer $server
* @param string $name
*/
public function __construct($server, $name) {
public function __construct(IServer $server, string $name) {
parent::__construct();
$this->server = $server;
$this->name = $name;
}
/**
* @throws \Icewind\SMB\Exception\ConnectionException
* @throws \Icewind\SMB\Exception\AuthenticationException
* @throws \Icewind\SMB\Exception\InvalidHostException
* @throws ConnectionException
* @throws AuthenticationException
* @throws InvalidHostException
*/
protected function getState() {
protected function getState(): NativeState {
if ($this->state and $this->state instanceof NativeState) {
return $this->state;
}
@ -62,11 +65,11 @@ class NativeShare extends AbstractShare {
*
* @return string
*/
public function getName() {
public function getName(): string {
return $this->name;
}
private function buildUrl($path) {
private function buildUrl(string $path): string {
$this->verifyPath($path);
$url = sprintf('smb://%s/%s', $this->server->getHost(), $this->name);
if ($path) {
@ -81,16 +84,16 @@ class NativeShare extends AbstractShare {
* List the content of a remote folder
*
* @param string $path
* @return \Icewind\SMB\IFileInfo[]
* @return IFileInfo[]
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function dir($path) {
public function dir(string $path): array {
$files = [];
$dh = $this->getState()->opendir($this->buildUrl($path));
while ($file = $this->getState()->readdir($dh)) {
while ($file = $this->getState()->readdir($dh, $path)) {
$name = $file['name'];
if ($name !== '.' and $name !== '..') {
$fullPath = $path . '/' . $name;
@ -98,15 +101,15 @@ class NativeShare extends AbstractShare {
}
}
$this->getState()->closedir($dh);
$this->getState()->closedir($dh, $path);
return $files;
}
/**
* @param string $path
* @return \Icewind\SMB\IFileInfo
* @return IFileInfo
*/
public function stat($path) {
public function stat(string $path): IFileInfo {
$info = new NativeFileInfo($this, $path, self::mb_basename($path));
// trigger attribute loading
@ -122,7 +125,7 @@ class NativeShare extends AbstractShare {
* @link http://php.net/manual/en/function.basename.php#121405
* @return string
*/
protected static function mb_basename($path) {
protected static function mb_basename(string $path): string {
if (preg_match('@^.*[\\\\/]([^\\\\/]+)$@s', $path, $matches)) {
return $matches[1];
} elseif (preg_match('@^([^\\\\/]+)$@s', $path, $matches)) {
@ -138,10 +141,10 @@ class NativeShare extends AbstractShare {
* @param string $path
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\AlreadyExistsException
* @throws NotFoundException
* @throws AlreadyExistsException
*/
public function mkdir($path) {
public function mkdir(string $path): bool {
return $this->getState()->mkdir($this->buildUrl($path));
}
@ -151,10 +154,10 @@ class NativeShare extends AbstractShare {
* @param string $path
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function rmdir($path) {
public function rmdir(string $path): bool {
return $this->getState()->rmdir($this->buildUrl($path));
}
@ -164,10 +167,10 @@ class NativeShare extends AbstractShare {
* @param string $path
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function del($path) {
public function del(string $path): bool {
return $this->getState()->unlink($this->buildUrl($path));
}
@ -178,10 +181,10 @@ class NativeShare extends AbstractShare {
* @param string $to
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\AlreadyExistsException
* @throws NotFoundException
* @throws AlreadyExistsException
*/
public function rename($from, $to) {
public function rename(string $from, string $to): bool{
return $this->getState()->rename($this->buildUrl($from), $this->buildUrl($to));
}
@ -192,10 +195,10 @@ class NativeShare extends AbstractShare {
* @param string $target remove file
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function put($source, $target) {
public function put(string $source, string $target): bool {
$sourceHandle = fopen($source, 'rb');
$targetUrl = $this->buildUrl($target);
@ -215,20 +218,18 @@ class NativeShare extends AbstractShare {
* @param string $target local file
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws \Icewind\SMB\Exception\InvalidPathException
* @throws \Icewind\SMB\Exception\InvalidResourceException
* @throws AuthenticationException
* @throws ConnectionException
* @throws InvalidHostException
* @throws InvalidPathException
* @throws InvalidResourceException
*/
public function get($source, $target) {
public function get(string $source, string $target): bool {
if (!$target) {
throw new InvalidPathException('Invalid target path: Filename cannot be empty');
}
$sourceHandle = $this->getState()->open($this->buildUrl($source), 'r');
if (!$sourceHandle) {
throw new InvalidResourceException('Failed opening remote file "' . $source . '" for reading');
}
$targetHandle = @fopen($target, 'wb');
if (!$targetHandle) {
@ -242,7 +243,7 @@ class NativeShare extends AbstractShare {
throw new InvalidResourceException('Failed opening local file "' . $target . '" for writing: ' . $reason);
}
while ($data = $this->getState()->read($sourceHandle, NativeReadStream::CHUNK_SIZE)) {
while ($data = $this->getState()->read($sourceHandle, NativeReadStream::CHUNK_SIZE, $source)) {
fwrite($targetHandle, $data);
}
$this->getState()->close($sourceHandle, $this->buildUrl($source));
@ -255,10 +256,10 @@ class NativeShare extends AbstractShare {
* @param string $source
* @return resource a read only stream with the contents of the remote file
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function read($source) {
public function read(string $source) {
$url = $this->buildUrl($source);
$handle = $this->getState()->open($url, 'r');
return NativeReadStream::wrap($this->getState(), $handle, 'r', $url);
@ -271,10 +272,10 @@ class NativeShare extends AbstractShare {
* @param string $source
* @return resource a writeable stream
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function write($source) {
public function write(string $source) {
$url = $this->buildUrl($source);
$handle = $this->getState()->create($url);
return NativeWriteStream::wrap($this->getState(), $handle, 'w', $url);
@ -286,10 +287,10 @@ class NativeShare extends AbstractShare {
* @param string $source
* @return resource a writeable stream
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function append($source) {
public function append(string $source) {
$url = $this->buildUrl($source);
$handle = $this->getState()->open($url, "a+");
return NativeWriteStream::wrap($this->getState(), $handle, "a", $url);
@ -302,7 +303,7 @@ class NativeShare extends AbstractShare {
* @param string $attribute attribute to get the info
* @return string the attribute value
*/
public function getAttribute($path, $attribute) {
public function getAttribute(string $path, string $attribute): string {
return $this->getState()->getxattr($this->buildUrl($path), $attribute);
}
@ -314,7 +315,7 @@ class NativeShare extends AbstractShare {
* @param string|int $value
* @return mixed the attribute value
*/
public function setAttribute($path, $attribute, $value) {
public function setAttribute(string $path, string $attribute, $value) {
if ($attribute === 'system.dos_attr.mode' and is_int($value)) {
$value = '0x' . dechex($value);
}
@ -329,7 +330,7 @@ class NativeShare extends AbstractShare {
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
* @return mixed
*/
public function setMode($path, $mode) {
public function setMode(string $path, int $mode) {
return $this->setAttribute($path, 'system.dos_attr.mode', $mode);
}
@ -340,7 +341,7 @@ class NativeShare extends AbstractShare {
* @param string $path
* @return INotifyHandler
*/
public function notify($path) {
public function notify(string $path): INotifyHandler {
// php-smbclient does not support notify (https://github.com/eduardok/libsmbclient-php/issues/29)
// so we use the smbclient based backend for this
if (!Server::available($this->server->getSystem())) {

View file

@ -58,7 +58,7 @@ class NativeState {
113 => NoRouteToHostException::class
];
protected function handleError($path) {
protected function handleError(?string $path) {
$error = smbclient_state_errno($this->state);
if ($error === 0) {
return;
@ -66,7 +66,7 @@ class NativeState {
throw Exception::fromMap(self::EXCEPTION_MAP, $error, $path);
}
protected function testResult($result, $uri) {
protected function testResult($result, ?string $uri) {
if ($result === false or $result === null) {
// smb://host/share/path
if (is_string($uri) && count(explode('/', $uri, 5)) > 4) {
@ -111,32 +111,24 @@ class NativeState {
* @param string $uri
* @return resource
*/
public function opendir($uri) {
public function opendir(string $uri) {
$result = @smbclient_opendir($this->state, $uri);
$this->testResult($result, $uri);
return $result;
}
/**
* @param resource $dir
* @return array
*/
public function readdir($dir) {
public function readdir($dir, string $path): array {
$result = @smbclient_readdir($this->state, $dir);
$this->testResult($result, $dir);
$this->testResult($result, $path);
return $result;
}
/**
* @param resource $dir
* @return bool
*/
public function closedir($dir) {
public function closedir($dir, string $path): bool {
$result = smbclient_closedir($this->state, $dir);
$this->testResult($result, $dir);
$this->testResult($result, $path);
return $result;
}
@ -145,7 +137,7 @@ class NativeState {
* @param string $new
* @return bool
*/
public function rename($old, $new) {
public function rename(string $old, string $new): bool {
$result = @smbclient_rename($this->state, $old, $this->state, $new);
$this->testResult($result, $new);
@ -156,7 +148,7 @@ class NativeState {
* @param string $uri
* @return bool
*/
public function unlink($uri) {
public function unlink(string $uri): bool {
$result = @smbclient_unlink($this->state, $uri);
$this->testResult($result, $uri);
@ -168,7 +160,7 @@ class NativeState {
* @param int $mask
* @return bool
*/
public function mkdir($uri, $mask = 0777) {
public function mkdir(string $uri, int $mask = 0777): bool {
$result = @smbclient_mkdir($this->state, $uri, $mask);
$this->testResult($result, $uri);
@ -179,7 +171,7 @@ class NativeState {
* @param string $uri
* @return bool
*/
public function rmdir($uri) {
public function rmdir(string $uri): bool {
$result = @smbclient_rmdir($this->state, $uri);
$this->testResult($result, $uri);
@ -190,21 +182,17 @@ class NativeState {
* @param string $uri
* @return array
*/
public function stat($uri) {
public function stat(string $uri): array {
$result = @smbclient_stat($this->state, $uri);
$this->testResult($result, $uri);
return $result;
}
/**
* @param resource $file
* @return array
*/
public function fstat($file) {
public function fstat($file, string $path): array {
$result = @smbclient_fstat($this->state, $file);
$this->testResult($result, $file);
$this->testResult($result, $path);
return $result;
}
@ -214,7 +202,7 @@ class NativeState {
* @param int $mask
* @return resource
*/
public function open($uri, $mode, $mask = 0666) {
public function open(string $uri, string $mode, int $mask = 0666) {
$result = @smbclient_open($this->state, $uri, $mode, $mask);
$this->testResult($result, $uri);
@ -226,22 +214,17 @@ class NativeState {
* @param int $mask
* @return resource
*/
public function create($uri, $mask = 0666) {
public function create(string $uri, int $mask = 0666) {
$result = @smbclient_creat($this->state, $uri, $mask);
$this->testResult($result, $uri);
return $result;
}
/**
* @param resource $file
* @param int $bytes
* @return string
*/
public function read($file, $bytes) {
public function read($file, int $bytes, string $path): string {
$result = @smbclient_read($this->state, $file, $bytes);
$this->testResult($result, $file);
$this->testResult($result, $path);
return $result;
}
@ -249,10 +232,10 @@ class NativeState {
* @param resource $file
* @param string $data
* @param string $path
* @param int $length
* @param int|null $length
* @return int
*/
public function write($file, $data, $path, $length = null) {
public function write($file, string $data, string $path, ?int $length = null): int {
$result = @smbclient_write($this->state, $file, $data, $length);
$this->testResult($result, $path);
@ -263,28 +246,24 @@ class NativeState {
* @param resource $file
* @param int $offset
* @param int $whence SEEK_SET | SEEK_CUR | SEEK_END
* @param string|null $path
* @return int|bool new file offset as measured from the start of the file on success, false on failure.
*/
public function lseek($file, $offset, $whence = SEEK_SET) {
public function lseek($file, int $offset, int $whence = SEEK_SET, string $path = null) {
$result = @smbclient_lseek($this->state, $file, $offset, $whence);
$this->testResult($result, $file);
$this->testResult($result, $path);
return $result;
}
/**
* @param resource $file
* @param int $size
* @return bool
*/
public function ftruncate($file, $size) {
public function ftruncate($file, int $size, string $path): bool {
$result = @smbclient_ftruncate($this->state, $file, $size);
$this->testResult($result, $file);
$this->testResult($result, $path);
return $result;
}
public function close($file, $path) {
public function close($file, string $path) {
$result = @smbclient_close($this->state, $file);
$this->testResult($result, $path);
@ -296,7 +275,7 @@ class NativeState {
* @param string $key
* @return string
*/
public function getxattr($uri, $key) {
public function getxattr(string $uri, string $key) {
$result = @smbclient_getxattr($this->state, $uri, $key);
$this->testResult($result, $uri);
@ -310,7 +289,7 @@ class NativeState {
* @param int $flags
* @return mixed
*/
public function setxattr($uri, $key, $value, $flags = 0) {
public function setxattr(string $uri, string $key, string $value, int $flags = 0) {
$result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags);
$this->testResult($result, $uri);

View file

@ -86,7 +86,7 @@ class NativeStream implements File {
}
public function stream_read($count) {
$result = $this->state->read($this->handle, $count);
$result = $this->state->read($this->handle, $count, $this->url);
if (strlen($result) < $count) {
$this->eof = true;
}
@ -96,7 +96,7 @@ class NativeStream implements File {
public function stream_seek($offset, $whence = SEEK_SET) {
$this->eof = false;
try {
return $this->state->lseek($this->handle, $offset, $whence) !== false;
return $this->state->lseek($this->handle, $offset, $whence, $this->url) !== false;
} catch (InvalidRequestException $e) {
return false;
}
@ -111,7 +111,7 @@ class NativeStream implements File {
}
public function stream_tell() {
return $this->state->lseek($this->handle, 0, SEEK_CUR);
return $this->state->lseek($this->handle, 0, SEEK_CUR, $this->url);
}
public function stream_write($data) {
@ -119,7 +119,7 @@ class NativeStream implements File {
}
public function stream_truncate($size) {
return $this->state->ftruncate($this->handle, $size);
return $this->state->ftruncate($this->handle, $size, $this->url);
}
public function stream_set_option($option, $arg1, $arg2) {

View file

@ -73,7 +73,7 @@ class ServerFactory {
* @return IServer
* @throws DependencyException
*/
public function createServer(string $host, IAuth $credentials) {
public function createServer(string $host, IAuth $credentials): IServer {
foreach (self::BACKENDS as $backend) {
if (call_user_func("$backend::available", $this->system)) {
return new $backend($host, $credentials, $this->system, $this->timeZoneProvider, $this->options);

View file

@ -32,7 +32,7 @@ class StringBuffer {
$this->pos = 0;
}
public function push(string $data) {
public function push(string $data): int {
$this->buffer = $this->flush() . $data;
return strlen($data);
}

View file

@ -10,7 +10,7 @@ namespace Icewind\SMB;
use Icewind\SMB\Exception\Exception;
class System implements ISystem {
/** @var (string|bool)[] */
/** @var (string|null)[] */
private $paths = [];
/**
@ -20,7 +20,7 @@ class System implements ISystem {
* @return string
* @throws Exception
*/
public function getFD($num) {
public function getFD(int $num): string {
$folders = [
'/proc/self/fd',
'/dev/fd'
@ -33,36 +33,36 @@ class System implements ISystem {
throw new Exception('Cant find file descriptor path');
}
public function getSmbclientPath() {
public function getSmbclientPath(): ?string {
return $this->getBinaryPath('smbclient');
}
public function getNetPath() {
public function getNetPath(): ?string {
return $this->getBinaryPath('net');
}
public function getSmbcAclsPath() {
public function getSmbcAclsPath(): ?string {
return $this->getBinaryPath('smbcacls');
}
public function getStdBufPath() {
public function getStdBufPath(): ?string {
return $this->getBinaryPath('stdbuf');
}
public function getDatePath() {
public function getDatePath(): ?string {
return $this->getBinaryPath('date');
}
public function libSmbclientAvailable() {
public function libSmbclientAvailable(): bool {
return function_exists('smbclient_state_new');
}
protected function getBinaryPath($binary) {
protected function getBinaryPath($binary): ?string {
if (!isset($this->paths[$binary])) {
$result = null;
$output = [];
exec("which $binary 2>&1", $output, $result);
$this->paths[$binary] = $result === 0 ? trim(implode('', $output)) : false;
$this->paths[$binary] = $result === 0 ? trim(implode('', $output)) : null;
}
return $this->paths[$binary];
}

View file

@ -25,7 +25,7 @@ class TimeZoneProvider implements ITimeZoneProvider {
$this->system = $system;
}
public function get($host) {
public function get(string $host): string {
if (!isset($this->timeZones[$host])) {
$timeZone = null;
$net = $this->system->getNetPath();

View file

@ -7,6 +7,7 @@
namespace Icewind\SMB\Wrapped;
use Icewind\SMB\Exception\AccessDeniedException;
use Icewind\SMB\Exception\AuthenticationException;
use Icewind\SMB\Exception\ConnectException;
use Icewind\SMB\Exception\ConnectionException;
@ -31,7 +32,7 @@ class Connection extends RawConnection {
*
* @param string $input
*/
public function write($input) {
public function write(string $input) {
return parent::write($input . PHP_EOL);
}
@ -56,15 +57,16 @@ class Connection extends RawConnection {
/**
* get all unprocessed output from smbclient until the next prompt
*
* @param callable $callback (optional) callback to call for every line read
* @param callable|null $callback (optional) callback to call for every line read
* @return string[]
* @throws AuthenticationException
* @throws ConnectException
* @throws ConnectionException
* @throws InvalidHostException
* @throws NoLoginServerException
* @throws AccessDeniedException
*/
public function read(callable $callback = null) {
public function read(callable $callback = null): array {
if (!$this->isValid()) {
throw new ConnectionException('Connection not valid');
}
@ -98,13 +100,7 @@ class Connection extends RawConnection {
return $output;
}
/**
* Check
*
* @param string $line
* @return bool
*/
private function isPrompt(string $line) {
private function isPrompt(string $line): bool {
return mb_substr($line, 0, self::DELIMITER_LENGTH) === self::DELIMITER;
}
@ -125,7 +121,7 @@ class Connection extends RawConnection {
}
}
public function close($terminate = true) {
public function close(bool $terminate = true) {
if (get_resource_type($this->getInputStream()) === 'stream') {
// ignore any errors while trying to send the close command, the process might already be dead
@$this->write('close' . PHP_EOL);

View file

@ -11,45 +11,20 @@ use Icewind\SMB\ACL;
use Icewind\SMB\IFileInfo;
class FileInfo implements IFileInfo {
/**
* @var string
*/
/** @var string */
protected $path;
/**
* @var string
*/
/** @var string */
protected $name;
/**
* @var int
*/
/** @var int */
protected $size;
/**
* @var int
*/
/** @var int */
protected $time;
/**
* @var int
*/
/** @var int */
protected $mode;
/**
* @var callable
*/
/** @var callable */
protected $aclCallback;
/**
* @param string $path
* @param string $name
* @param int $size
* @param int $time
* @param int $mode
* @param callable $aclCallback
*/
public function __construct($path, $name, $size, $time, $mode, callable $aclCallback) {
public function __construct(string $path, string $name, int $size, int $time, int $mode, callable $aclCallback) {
$this->path = $path;
$this->name = $name;
$this->size = $size;
@ -61,63 +36,39 @@ class FileInfo implements IFileInfo {
/**
* @return string
*/
public function getPath() {
public function getPath(): string {
return $this->path;
}
/**
* @return string
*/
public function getName() {
public function getName(): string {
return $this->name;
}
/**
* @return int
*/
public function getSize() {
public function getSize(): int {
return $this->size;
}
/**
* @return int
*/
public function getMTime() {
public function getMTime(): int {
return $this->time;
}
/**
* @return bool
*/
public function isDirectory() {
public function isDirectory(): bool {
return (bool)($this->mode & IFileInfo::MODE_DIRECTORY);
}
/**
* @return bool
*/
public function isReadOnly() {
public function isReadOnly(): bool {
return (bool)($this->mode & IFileInfo::MODE_READONLY);
}
/**
* @return bool
*/
public function isHidden() {
public function isHidden(): bool {
return (bool)($this->mode & IFileInfo::MODE_HIDDEN);
}
/**
* @return bool
*/
public function isSystem() {
public function isSystem(): bool {
return (bool)($this->mode & IFileInfo::MODE_SYSTEM);
}
/**
* @return bool
*/
public function isArchived() {
public function isArchived(): bool {
return (bool)($this->mode & IFileInfo::MODE_ARCHIVE);
}

View file

@ -35,7 +35,7 @@ class NotifyHandler implements INotifyHandler {
* @param Connection $connection
* @param string $path
*/
public function __construct(Connection $connection, $path) {
public function __construct(Connection $connection, string $path) {
$this->connection = $connection;
$this->path = $path;
}
@ -45,7 +45,7 @@ class NotifyHandler implements INotifyHandler {
*
* @return Change[]
*/
public function getChanges() {
public function getChanges(): array {
if (!$this->listening) {
return [];
}
@ -66,7 +66,7 @@ class NotifyHandler implements INotifyHandler {
*
* @param callable $callback
*/
public function listen($callback) {
public function listen(callable $callback): void {
if ($this->listening) {
$this->connection->read(function ($line) use ($callback) {
$this->checkForError($line);
@ -78,7 +78,7 @@ class NotifyHandler implements INotifyHandler {
}
}
private function parseChangeLine($line) {
private function parseChangeLine(string $line): ?Change {
$code = (int)substr($line, 0, 4);
if ($code === 0) {
return null;
@ -91,7 +91,7 @@ class NotifyHandler implements INotifyHandler {
}
}
private function checkForError($line) {
private function checkForError(string $line) {
if (substr($line, 0, 16) === 'notify returned ') {
$error = substr($line, 16);
throw Exception::fromMap(array_merge(self::EXCEPTION_MAP, Parser::EXCEPTION_MAP), $error, 'Notify is not supported with the used smb version');

View file

@ -29,11 +29,6 @@ class Parser {
*/
protected $timeZone;
/**
* @var string
*/
private $host;
// see error.h
const EXCEPTION_MAP = [
ErrorCodes::LogonFailure => AuthenticationException::class,
@ -65,17 +60,17 @@ class Parser {
$this->timeZone = $timeZone;
}
private function getErrorCode($line) {
private function getErrorCode(string $line): ?string {
$parts = explode(' ', $line);
foreach ($parts as $part) {
if (substr($part, 0, 9) === 'NT_STATUS') {
return $part;
}
}
return false;
return null;
}
public function checkForError($output, $path) {
public function checkForError(array $output, string $path): void {
if (strpos($output[0], 'does not exist')) {
throw new NotFoundException($path);
}
@ -98,7 +93,7 @@ class Parser {
* @throws NoLoginServerException
* @throws AccessDeniedException
*/
public function checkConnectionError(string $line) {
public function checkConnectionError(string $line): void {
$line = rtrim($line, ')');
if (substr($line, -23) === ErrorCodes::LogonFailure) {
throw new AuthenticationException('Invalid login');
@ -120,7 +115,7 @@ class Parser {
}
}
public function parseMode($mode) {
public function parseMode(string $mode): int {
$result = 0;
foreach (self::MODE_STRINGS as $char => $val) {
if (strpos($mode, $char) !== false) {
@ -130,7 +125,7 @@ class Parser {
return $result;
}
public function parseStat($output) {
public function parseStat(array $output): array {
$data = [];
foreach ($output as $line) {
// A line = explode statement may not fill all array elements
@ -151,7 +146,13 @@ class Parser {
];
}
public function parseDir($output, $basePath, callable $aclCallback) {
/**
* @param array $output
* @param string $basePath
* @param callable $aclCallback
* @return FileInfo[]
*/
public function parseDir(array $output, string $basePath, callable $aclCallback): array {
//last line is used space
array_pop($output);
$regex = '/^\s*(.*?)\s\s\s\s+(?:([NDHARS]*)\s+)?([0-9]+)\s+(.*)$/';
@ -173,7 +174,11 @@ class Parser {
return $content;
}
public function parseListShares($output) {
/**
* @param array $output
* @return string[]
*/
public function parseListShares(array $output): array {
$shareNames = [];
foreach ($output as $line) {
if (strpos($line, '|')) {

View file

@ -9,7 +9,6 @@ namespace Icewind\SMB\Wrapped;
use Icewind\SMB\Exception\ConnectException;
use Icewind\SMB\Exception\ConnectionException;
use Icewind\SMB\Exception\ConnectionResetException;
class RawConnection {
/**
@ -43,9 +42,7 @@ class RawConnection {
*/
private $authStream = null;
private $connected = false;
public function __construct($command, array $env = []) {
public function __construct(string $command, array $env = []) {
$this->command = $command;
$this->env = $env;
}
@ -78,7 +75,6 @@ class RawConnection {
if (!$this->isValid()) {
throw new ConnectionException();
}
$this->connected = true;
}
/**
@ -86,7 +82,7 @@ class RawConnection {
*
* @return bool
*/
public function isValid() {
public function isValid(): bool {
if (is_resource($this->process)) {
$status = proc_get_status($this->process);
return $status['running'];
@ -99,8 +95,9 @@ class RawConnection {
* send input to the process
*
* @param string $input
* @return int|bool
*/
public function write($input) {
public function write(string $input) {
$result = @fwrite($this->getInputStream(), $input);
fflush($this->getInputStream());
return $result;
@ -118,7 +115,7 @@ class RawConnection {
/**
* read a line of output
*
* @return string
* @return string|false
*/
public function readError() {
return trim(stream_get_line($this->getErrorStream(), 4086));
@ -127,9 +124,9 @@ class RawConnection {
/**
* get all output until the process closes
*
* @return array
* @return string[]
*/
public function readAll() {
public function readAll(): array {
$output = [];
while ($line = $this->readLine()) {
$output[] = $line;
@ -161,8 +158,8 @@ class RawConnection {
return $this->pipes[5];
}
public function writeAuthentication($user, $password) {
$auth = ($password === false)
public function writeAuthentication(?string $user, ?string $password) {
$auth = ($password === null)
? "username=$user"
: "username=$user\npassword=$password\n";
@ -170,7 +167,7 @@ class RawConnection {
fwrite($this->getAuthStream(), $auth);
}
public function close($terminate = true) {
public function close(bool $terminate = true) {
if (!is_resource($this->process)) {
return;
}

View file

@ -23,11 +23,11 @@ class Server extends AbstractServer {
* @param ISystem $system
* @return bool
*/
public static function available(ISystem $system) {
return $system->getSmbclientPath();
public static function available(ISystem $system): bool {
return $system->getSmbclientPath() !== null;
}
private function getAuthFileArgument() {
private function getAuthFileArgument(): string {
if ($this->getAuth()->getUsername()) {
return '--authentication-file=' . $this->system->getFD(3);
} else {
@ -42,7 +42,7 @@ class Server extends AbstractServer {
* @throws InvalidHostException
* @throws ConnectException
*/
public function listShares() {
public function listShares(): array {
$maxProtocol = $this->options->getMaxProtocol();
$minProtocol = $this->options->getMinProtocol();
$command = sprintf(
@ -93,7 +93,7 @@ class Server extends AbstractServer {
* @param string $name
* @return IShare
*/
public function getShare($name) {
public function getShare(string $name): IShare {
return new Share($this, $name, $this->system);
}
}

View file

@ -9,9 +9,12 @@ namespace Icewind\SMB\Wrapped;
use Icewind\SMB\AbstractShare;
use Icewind\SMB\ACL;
use Icewind\SMB\Exception\AlreadyExistsException;
use Icewind\SMB\Exception\AuthenticationException;
use Icewind\SMB\Exception\ConnectionException;
use Icewind\SMB\Exception\DependencyException;
use Icewind\SMB\Exception\FileInUseException;
use Icewind\SMB\Exception\InvalidHostException;
use Icewind\SMB\Exception\InvalidTypeException;
use Icewind\SMB\Exception\NotFoundException;
use Icewind\SMB\Exception\InvalidRequestException;
@ -63,7 +66,7 @@ class Share extends AbstractShare {
* @param string $name
* @param ISystem $system
*/
public function __construct(IServer $server, $name, ISystem $system) {
public function __construct(IServer $server, string $name, ISystem $system) {
parent::__construct();
$this->server = $server;
$this->name = $name;
@ -71,7 +74,7 @@ class Share extends AbstractShare {
$this->parser = new Parser($server->getTimeZone());
}
private function getAuthFileArgument() {
private function getAuthFileArgument(): string {
if ($this->server->getAuth()->getUsername()) {
return '--authentication-file=' . $this->system->getFD(3);
} else {
@ -79,7 +82,7 @@ class Share extends AbstractShare {
}
}
protected function getConnection() {
protected function getConnection(): Connection {
$maxProtocol = $this->server->getOptions()->getMaxProtocol();
$minProtocol = $this->server->getOptions()->getMinProtocol();
$command = sprintf(
@ -106,9 +109,9 @@ class Share extends AbstractShare {
}
/**
* @throws \Icewind\SMB\Exception\ConnectionException
* @throws \Icewind\SMB\Exception\AuthenticationException
* @throws \Icewind\SMB\Exception\InvalidHostException
* @throws ConnectionException
* @throws AuthenticationException
* @throws InvalidHostException
*/
protected function connect() {
if ($this->connection and $this->connection->isValid()) {
@ -129,11 +132,11 @@ class Share extends AbstractShare {
*
* @return string
*/
public function getName() {
public function getName(): string {
return $this->name;
}
protected function simpleCommand($command, $path) {
protected function simpleCommand(string $command, string $path): bool {
$escapedPath = $this->escapePath($path);
$cmd = $command . ' ' . $escapedPath;
$output = $this->execute($cmd);
@ -144,12 +147,12 @@ class Share extends AbstractShare {
* List the content of a remote folder
*
* @param string $path
* @return \Icewind\SMB\IFileInfo[]
* @return IFileInfo[]
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function dir($path) {
public function dir(string $path): array {
$escapedPath = $this->escapePath($path);
$output = $this->execute('cd ' . $escapedPath);
//check output for errors
@ -165,9 +168,9 @@ class Share extends AbstractShare {
/**
* @param string $path
* @return \Icewind\SMB\IFileInfo
* @return IFileInfo
*/
public function stat($path) {
public function stat(string $path): IFileInfo {
// some windows server setups don't seem to like the allinfo command
// use the dir command instead to get the file info where possible
if ($path !== "" && $path !== "/") {
@ -204,10 +207,10 @@ class Share extends AbstractShare {
* @param string $path
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\AlreadyExistsException
* @throws NotFoundException
* @throws AlreadyExistsException
*/
public function mkdir($path) {
public function mkdir(string $path): bool {
return $this->simpleCommand('mkdir', $path);
}
@ -217,10 +220,10 @@ class Share extends AbstractShare {
* @param string $path
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function rmdir($path) {
public function rmdir(string $path): bool {
return $this->simpleCommand('rmdir', $path);
}
@ -234,7 +237,7 @@ class Share extends AbstractShare {
* @throws NotFoundException
* @throws \Exception
*/
public function del($path, $secondTry = false) {
public function del(string $path, bool $secondTry = false): bool {
//del return a file not found error when trying to delete a folder
//we catch it so we can check if $path doesn't exist or is of invalid type
try {
@ -265,10 +268,10 @@ class Share extends AbstractShare {
* @param string $to
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\AlreadyExistsException
* @throws NotFoundException
* @throws AlreadyExistsException
*/
public function rename($from, $to) {
public function rename(string $from, string $to): bool {
$path1 = $this->escapePath($from);
$path2 = $this->escapePath($to);
$output = $this->execute('rename ' . $path1 . ' ' . $path2);
@ -282,10 +285,10 @@ class Share extends AbstractShare {
* @param string $target remove file
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function put($source, $target) {
public function put(string $source, string $target): bool {
$path1 = $this->escapeLocalPath($source); //first path is local, needs different escaping
$path2 = $this->escapePath($target);
$output = $this->execute('put ' . $path1 . ' ' . $path2);
@ -299,10 +302,10 @@ class Share extends AbstractShare {
* @param string $target local file
* @return bool
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function get($source, $target) {
public function get(string $source, string $target): bool {
$path1 = $this->escapePath($source);
$path2 = $this->escapeLocalPath($target); //second path is local, needs different escaping
$output = $this->execute('get ' . $path1 . ' ' . $path2);
@ -315,10 +318,10 @@ class Share extends AbstractShare {
* @param string $source
* @return resource a read only stream with the contents of the remote file
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function read($source) {
public function read(string $source) {
$source = $this->escapePath($source);
// since returned stream is closed by the caller we need to create a new instance
// since we can't re-use the same file descriptor over multiple calls
@ -337,10 +340,10 @@ class Share extends AbstractShare {
* @param string $target
* @return resource a write only stream to upload a remote file
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws NotFoundException
* @throws InvalidTypeException
*/
public function write($target) {
public function write(string $target) {
$target = $this->escapePath($target);
// since returned stream is closed by the caller we need to create a new instance
// since we can't re-use the same file descriptor over multiple calls
@ -363,9 +366,9 @@ class Share extends AbstractShare {
*
* @param string $target
*
* @throws \Icewind\SMB\Exception\DependencyException
* @throws DependencyException
*/
public function append($target) {
public function append(string $target) {
throw new DependencyException('php-libsmbclient is required for append');
}
@ -374,7 +377,7 @@ class Share extends AbstractShare {
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
* @return mixed
*/
public function setMode($path, $mode) {
public function setMode(string $path, int $mode) {
$modeString = '';
foreach (self::MODE_MAP as $modeByte => $string) {
if ($mode & $modeByte) {
@ -404,7 +407,7 @@ class Share extends AbstractShare {
* @throws ConnectionException
* @throws DependencyException
*/
public function notify($path) {
public function notify(string $path): INotifyHandler {
if (!$this->system->getStdBufPath()) { //stdbuf is required to disable smbclient's output buffering
throw new DependencyException('stdbuf is required for usage of the notify command');
}
@ -418,7 +421,7 @@ class Share extends AbstractShare {
* @param string $command
* @return array
*/
protected function execute($command) {
protected function execute(string $command): array {
$this->connect();
$this->connection->write($command . PHP_EOL);
return $this->connection->read();
@ -431,14 +434,14 @@ class Share extends AbstractShare {
* @param string $path
*
* @return bool
* @throws \Icewind\SMB\Exception\AlreadyExistsException
* @throws AlreadyExistsException
* @throws \Icewind\SMB\Exception\AccessDeniedException
* @throws \Icewind\SMB\Exception\NotEmptyException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws InvalidTypeException
* @throws \Icewind\SMB\Exception\Exception
* @throws NotFoundException
*/
protected function parseOutput($lines, $path = '') {
protected function parseOutput(array $lines, string $path = ''): bool {
if (count($lines) === 0) {
return true;
} else {
@ -451,7 +454,7 @@ class Share extends AbstractShare {
* @param string $string
* @return string
*/
protected function escape($string) {
protected function escape(string $string): string {
return escapeshellarg($string);
}
@ -459,7 +462,7 @@ class Share extends AbstractShare {
* @param string $path
* @return string
*/
protected function escapePath($path) {
protected function escapePath(string $path): string {
$this->verifyPath($path);
if ($path === '/') {
$path = '';
@ -474,12 +477,12 @@ class Share extends AbstractShare {
* @param string $path
* @return string
*/
protected function escapeLocalPath($path) {
protected function escapeLocalPath(string $path): string {
$path = str_replace('"', '\"', $path);
return '"' . $path . '"';
}
protected function getAcls($path) {
protected function getAcls(string $path): array {
$commandPath = $this->system->getSmbcAclsPath();
if (!$commandPath) {
return [];