Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 34 additions & 40 deletions lib/Files/AbstractLocalNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,30 @@ abstract class AbstractLocalNode extends AbstractNode implements NodeInterface
/** @var string */
protected $path;

/** @var string */
protected $basePath;

/** @var LocalFolder */
/** @var LocalFolder|null */
protected $parentFolder;

/** @var int */
/** @var string */
protected $rootPath;

/** @var int|null */
protected $permissions;

/**
* AbstractLocalNode constructor.
*
* @param string $path
* @param string $basePath
* @param string $path
* @param string|null $rootPath
*
* @throws InvalidPathException
* @throws NotFoundException
*/
public function __construct(string $path, string $basePath)
public function __construct(string $path, string $rootPath = null)
{
parent::__construct();

$this->path = $this->normalizePath($path);
$this->basePath = realpath($basePath ?: \OC::$SERVERROOT);
$this->rootPath = realpath($rootPath ?? \OC::$SERVERROOT);

if (!file_exists($this->getLocalPath())) {
throw new NotFoundException();
Expand All @@ -73,7 +73,11 @@ public function rename(string $name): NodeInterface
{
$this->assertValidFileName($name);

$parentNode = $this->getParentNode();
if (!$this->isDeletable()) {
throw new NotPermittedException();
}

$parentNode = $this->getParentFolder();
if ($parentNode->exists($name)) {
throw new AlreadyExistsException();
}
Expand Down Expand Up @@ -114,7 +118,7 @@ public function copy(FolderInterface $targetPath, string $name = null): NodeInte
throw new GenericFileException();
}

return new LocalFile($targetPath->getPath() . '/' . $name, $targetPath->basePath);
return new LocalFile($targetPath->getPath() . '/' . $name, $targetPath->getRootPath());
} else {
return parent::copy($targetPath, $name);
}
Expand All @@ -132,6 +136,10 @@ public function move(FolderInterface $targetPath, string $name = null): NodeInte
$name = $this->getName();
}

if (!$this->isDeletable()) {
throw new NotPermittedException();
}

if ($targetPath->exists($name)) {
throw new AlreadyExistsException();
}
Expand All @@ -143,26 +151,12 @@ public function move(FolderInterface $targetPath, string $name = null): NodeInte
throw new GenericFileException();
}

return new LocalFile($targetPath->getPath() . '/' . $name, $targetPath->getBasePath());
return new LocalFile($targetPath->getPath() . '/' . $name, $targetPath->getRootPath());
} else {
return parent::move($targetPath, $name);
}
}

/**
* {@inheritDoc}
*/
public function delete(): void
{
if (!$this->isDeletable()) {
throw new NotPermittedException();
}

if (!@unlink($this->getLocalPath())) {
throw new GenericFileException();
}
}

/**
* {@inheritDoc}
*/
Expand All @@ -171,20 +165,12 @@ public function getPath(): string
return $this->path;
}

/**
* @return string
*/
public function getBasePath(): string
{
return $this->basePath;
}

/**
* {@inheritDoc}
*/
public function getLocalPath(): string
{
return $this->basePath . (($this->path !== '/') ? $this->path : '');
return $this->rootPath . (($this->path !== '/') ? $this->path : '');
}

/**
Expand All @@ -198,7 +184,7 @@ public function getName(): string
/**
* {@inheritDoc}
*/
public function getParent(): string
public function getParentPath(): string
{
if ($this->path === '/') {
throw new InvalidPathException();
Expand All @@ -210,15 +196,23 @@ public function getParent(): string
/**
* {@inheritDoc}
*/
public function getParentNode(): FolderInterface
public function getParentFolder(): FolderInterface
{
if ($this->parentFolder === null) {
$this->parentFolder = new LocalFolder($this->getParent(), $this->basePath);
$this->parentFolder = new LocalFolder($this->getParentPath(), $this->rootPath);
}

return $this->parentFolder;
}

/**
* @return string
*/
public function getRootPath(): string
{
return $this->rootPath;
}

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -265,13 +259,13 @@ public function getPermissions(): int
if (is_writable($localPath)) {
$this->permissions |= Constants::PERMISSION_UPDATE;

if ($this->isFolder()) {
if ($this->isFolder() && is_executable($localPath)) {
$this->permissions |= Constants::PERMISSION_CREATE;
}
}

try {
if (is_writable($this->getParentNode()->getLocalPath())) {
if (is_writable($this->getParentFolder()->getLocalPath())) {
$this->permissions |= Constants::PERMISSION_DELETE;
}
} catch (\Exception $e) {
Expand Down
5 changes: 5 additions & 0 deletions lib/Files/AbstractNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use OCA\CMSPico\Service\MiscService;
use OCP\Constants;
use OCP\Files\InvalidPathException;
use OCP\Files\NotPermittedException;

abstract class AbstractNode implements NodeInterface
{
Expand Down Expand Up @@ -74,6 +75,10 @@ public function move(FolderInterface $targetPath, string $name = null): NodeInte
$this->assertValidFileName($name);
}

if (!$this->isDeletable()) {
throw new NotPermittedException();
}

if ($this->isFolder()) {
/** @var FolderInterface $this */
$target = $targetPath->newFolder($name ?? $this->getName());
Expand Down
38 changes: 19 additions & 19 deletions lib/Files/AbstractStorageNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,31 @@ abstract class AbstractStorageNode extends AbstractNode implements NodeInterface
/** @var OCNode */
protected $node;

/** @var string */
/** @var string|null */
protected $path;

/** @var StorageFolder */
/** @var StorageFolder|null */
protected $parentFolder;

/**
* StorageNode constructor.
*
* @param OCNode $node
* @param string|null $basePath
* @param string|null $parentPath
*
* @throws InvalidPathException
*/
public function __construct(OCNode $node, string $basePath = null)
public function __construct(OCNode $node, string $parentPath = null)
{
parent::__construct();

$this->node = $node;

if ($basePath !== null) {
$basePath = $this->normalizePath($basePath);
if ($parentPath !== null) {
$parentPath = $this->normalizePath($parentPath);
$nodePath = $this->normalizePath($node->getPath());

$path = (($basePath !== '/') ? $basePath : '') . '/' . basename($nodePath);
$path = (($parentPath !== '/') ? $parentPath : '') . '/' . basename($nodePath);
if (substr_compare($nodePath, $path, -strlen($path)) !== 0) {
throw new InvalidPathException();
}
Expand All @@ -73,7 +73,7 @@ public function __construct(OCNode $node, string $basePath = null)
*/
public function rename(string $name): NodeInterface
{
return $this->move($this->getParentNode(), $name);
return $this->move($this->getParentFolder(), $name);
}

/**
Expand Down Expand Up @@ -133,7 +133,7 @@ public function getOCNode(): OCNode
*/
public function getPath(): string
{
return $this->path ?: ($this->isFolder() ? '/' : '/' . $this->getName());
return $this->path ?? ($this->isFolder() ? '/' : '/' . $this->getName());
}

/**
Expand Down Expand Up @@ -171,15 +171,15 @@ public function getName(): string
/**
* {@inheritDoc}
*/
public function getParent(): string
public function getParentPath(): string
{
return $this->getParentNode()->getPath();
return $this->getParentFolder()->getPath();
}

/**
* {@inheritDoc}
*/
public function getParentNode(): FolderInterface
public function getParentFolder(): FolderInterface
{
if ($this->parentFolder === null) {
if ($this->path === null) {
Expand All @@ -192,9 +192,9 @@ public function getParentNode(): FolderInterface
throw new InvalidPathException();
}

$parentBasePath = dirname($this->path);
$parentBasePath = ($parentBasePath !== '/') ? dirname($parentBasePath) : null;
$this->parentFolder = new StorageFolder($ocNode, $parentBasePath);
$grandParentPath = dirname($this->path);
$grandParentPath = ($grandParentPath !== '/') ? dirname($grandParentPath) : null;
$this->parentFolder = new StorageFolder($ocNode, $grandParentPath);
}

return $this->parentFolder;
Expand Down Expand Up @@ -242,17 +242,17 @@ public function getPermissions(): int

/**
* @param OCNode $node
* @param string|null $basePath
* @param string|null $parentPath
*
* @return AbstractStorageNode
* @throws InvalidPathException
*/
protected function repackNode(OCNode $node, string $basePath = null): AbstractStorageNode
protected function repackNode(OCNode $node, string $parentPath = null): AbstractStorageNode
{
if ($node instanceof OCFile) {
return new StorageFile($node, $basePath);
return new StorageFile($node, $parentPath);
} elseif ($node instanceof OCFolder) {
return new StorageFolder($node, $basePath);
return new StorageFolder($node, $parentPath);
} else {
throw new \UnexpectedValueException();
}
Expand Down
33 changes: 33 additions & 0 deletions lib/Files/FolderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

namespace OCA\CMSPico\Files;

use OCP\Files\AlreadyExistsException;
use OCP\Files\GenericFileException;
use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
Expand Down Expand Up @@ -72,6 +73,38 @@ public function getFile(string $path): FileInterface
return $file;
}

/**
* @param string $fullPath
*
* @return FolderInterface
* @throws AlreadyExistsException
* @throws InvalidPathException
* @throws NotPermittedException
*/
protected function newFolderRecursive(string $fullPath): FolderInterface
{
if ($fullPath !== '/') {
if (!$this->getRootFolder()->exists($fullPath)) {
return $this->getRootFolder()->newFolder($fullPath);
} else {
/** @var FolderInterface $parentFolder */
$parentFolder = $this->getRootFolder()->get($fullPath);
if (!$parentFolder->isFolder()) {
throw new AlreadyExistsException();
}
return $parentFolder;
}
} else {
return $this->getRootFolder();
}
}

/**
* @return FolderInterface
* @throws InvalidPathException
*/
abstract protected function getRootFolder(): FolderInterface;

/**
* @return \Generator
* @throws NotPermittedException
Expand Down
22 changes: 18 additions & 4 deletions lib/Files/LocalFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,35 @@ class LocalFile extends AbstractLocalNode implements FileInterface
/**
* LocalFile constructor.
*
* @param string $path
* @param string $basePath
* @param string $path
* @param string|null $rootPath
*
* @throws InvalidPathException
* @throws NotFoundException
*/
public function __construct(string $path, string $basePath)
public function __construct(string $path, string $rootPath = null)
{
parent::__construct($path, $basePath);
parent::__construct($path, $rootPath);

if (!is_file($this->getLocalPath())) {
throw new InvalidPathException();
}
}

/**
* {@inheritDoc}
*/
public function delete(): void
{
if (!$this->isDeletable()) {
throw new NotPermittedException();
}

if (!@unlink($this->getLocalPath())) {
throw new GenericFileException();
}
}

/**
* {@inheritDoc}
*/
Expand Down
Loading