I'm upgrading my project from Flysystem 1.x to 3.x, and I'm having trouble retrieving the root directory (previously accessible via getPathPrefix()
in Flysystem 1.x) when working with a FilesystemOperator
object.
In Flysystem 1.x, I could retrieve the root directory of an adapter using code like this:
$adapter = new League\Flysystem\Adapter\Local('/path/to/root');
$filesystem = new League\Flysystem\Filesystem($adapter);
echo $adapter->getPathPrefix(); // Outputs "/path/to/root"
However, in Flysystem 3.x, the FilesystemOperator
interface doesn't expose any direct methods to retrieve the root directory, and getPathPrefix()
has been removed.
Here’s an example of how I’m initializing the filesystem in Flysystem 3.x:
use League\Flysystem\FilesystemOperator;
use League\Flysystem\Local\LocalFilesystemAdapter;
$adapter = new LocalFilesystemAdapter('/path/to/root');
$filesystem = new Filesystem($adapter);
I need to retrieve the root directory (/path/to/root
) from the FilesystemOperator
object. After reading the Flysystem 3.x documentation, I see no straightforward way to do this.
Questions:
- Is there a recommended way to retrieve the root directory from the
FilesystemOperator
or theLocalFilesystemAdapter
in Flysystem 3.x? - I see the private
$rootLocation
property inLocalFilesystemAdapter
, but i can't access - How can I handle this in a way that keeps the code clean and respects Flysystem's new design principles?
I'm upgrading my project from Flysystem 1.x to 3.x, and I'm having trouble retrieving the root directory (previously accessible via getPathPrefix()
in Flysystem 1.x) when working with a FilesystemOperator
object.
In Flysystem 1.x, I could retrieve the root directory of an adapter using code like this:
$adapter = new League\Flysystem\Adapter\Local('/path/to/root');
$filesystem = new League\Flysystem\Filesystem($adapter);
echo $adapter->getPathPrefix(); // Outputs "/path/to/root"
However, in Flysystem 3.x, the FilesystemOperator
interface doesn't expose any direct methods to retrieve the root directory, and getPathPrefix()
has been removed.
Here’s an example of how I’m initializing the filesystem in Flysystem 3.x:
use League\Flysystem\FilesystemOperator;
use League\Flysystem\Local\LocalFilesystemAdapter;
$adapter = new LocalFilesystemAdapter('/path/to/root');
$filesystem = new Filesystem($adapter);
I need to retrieve the root directory (/path/to/root
) from the FilesystemOperator
object. After reading the Flysystem 3.x documentation, I see no straightforward way to do this.
Questions:
- Is there a recommended way to retrieve the root directory from the
FilesystemOperator
or theLocalFilesystemAdapter
in Flysystem 3.x? - I see the private
$rootLocation
property inLocalFilesystemAdapter
, but i can't access - How can I handle this in a way that keeps the code clean and respects Flysystem's new design principles?
- Can you share which problem you want to solve? From my POV, you're using a filesystem library to explicitly not care about the root directory on your own – Nico Haase Commented Mar 17 at 7:43
1 Answer
Reset to default 2The getPathPrefix()
method has been moved to https://github/thephpleague/flysystem/blob/3.x/src/PathPrefixer.php#L24
There is no way to use it from FilesystemOperator
or LocalFilesystemAdapter
As I understand it, the problem is
class SomeService
{
public function __construct(private readonly Filesystem $filesystem) {
}
public function someMethod() {
// required root directory previosly accessed from $this->filesystem->getPathPrefix();
}
}
class SomeController {
public function __construct(private readonly SomeService $someService) {
}
}
I see 2 options for refactoring
- Assume that the
PathPrefixer::prefixPath
method inSomeService::someMethod
is useless and the$location (/path/to/root)
property will suffice.
class SomeServiceFactory
{
public function create(string $location): SomeService {
$adapter = new LocalFilesystemAdapter($location);
$filesystem = new Filesystem($adapter);
return new SomeService($location, $filesystem);
}
}
class SomeService
{
public function __construct(
private readonly string $location,
private readonly Filesystem $filesystem
) {
}
public function someMethod() {
$this->location;
$this->filesystem;
}
}
class SomeController {
public function __construct(private readonly SomeServiceFactory $someServiceFactory) {
}
public function index(string $location) {
$this->someServiceFactory->create($location)->someMethod();
}
}
- Create the decorator
// use this class, instead of League\Flysystem\Filesystem
class Filesystem {
public function __construct(private readonly string $location) {
$adapter = new LocalFilesystemAdapter($location);
$this->filesystem = new \League\Flysystem\Filesystem($adapter);
}
// proxy to original class methods
public function __call($name, $arguments)
{
if (is_callable([$this->filesystem, $name])) {
return $this->filesystem->$name(...$arguments);
}
$message = sprintf('There is no callable method %s::%s', get_class($this->filesystem), $name);
throw new \BadMethodCallException($message);
}
public function getPathPrefix(): string {
$prefixer = new League\Flysystem\PathPrefixer($this->location, DIRECTORY_SEPARATOR);
return $prefixer->prefixPath($this->location);
}
}