1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-09-20 14:34:03 +00:00
tenancy/src/Actions/RemoveStorageSymlinksAction.php
lukinovec 35d96b5b6f Use rmdir instead of deleteDirectory
rmdir refuses to delete non-empty directories, so it's the better alternative to deleteDirectory here.
2026-09-15 11:09:40 +02:00

79 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Actions;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Stancl\Tenancy\Concerns\DealsWithTenantSymlinks;
use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Events\RemovingStorageSymlink;
use Stancl\Tenancy\Events\StorageSymlinkRemoved;
class RemoveStorageSymlinksAction
{
use DealsWithTenantSymlinks;
/**
* Should the directories created for nested symlinks be removed along with the symlink.
*
* Before enabling this, make sure you understand the removeLink() method
* and the high stakes of recursively removing parent directories (even if the logic should be sound).
*
* @see CreateStorageSymlinksAction
*/
public static bool $removeNestedDirectories = false;
/**
* @param Tenant|Collection<covariant int|string, Tenant&\Illuminate\Database\Eloquent\Model>|LazyCollection<covariant int|string, Tenant&\Illuminate\Database\Eloquent\Model> $tenants
*/
public function __invoke(Tenant|Collection|LazyCollection $tenants): void
{
$tenants = $tenants instanceof Tenant ? collect([$tenants]) : $tenants;
/** @var Tenant $tenant */
foreach ($tenants as $tenant) {
foreach ($this->possibleTenantSymlinks($tenant) as $publicPath => $storagePath) {
$this->removeLink($publicPath, $tenant);
}
}
}
protected function removeLink(string $publicPath, Tenant $tenant): void
{
if (! $this->symlinkExists($publicPath)) {
return;
}
$files = app()->make('files');
event(new RemovingStorageSymlink($tenant));
$files->delete($publicPath);
event(new StorageSymlinkRemoved($tenant));
if (! static::$removeNestedDirectories) {
return;
}
$publicRoot = realpath(public_path());
$directory = realpath(dirname($publicPath));
if ($publicRoot === false || $directory === false) {
return;
}
// Remove the directories CreateStorageSymlinksAction created for the symlink
// until a non-empty one is reached.
while (str_starts_with(rtrim($directory, '/\\'), rtrim($publicRoot, '/\\') . DIRECTORY_SEPARATOR) && $files->isEmptyDirectory($directory)) {
if (! @rmdir($directory)) {
// Stop the loop if the directory couldn't be removed
break;
}
$directory = dirname($directory);
}
}
}