master

laravel/framework

Last updated at: 29/12/2023 09:23

StorageLinkCommand.php

TLDR

This file defines the StorageLinkCommand class, which is a command for creating symbolic links for the storage of an application. It extends the Command class and is triggered by the storage:link command. The command has options to create relative symbolic links and to force the recreation of existing symbolic links.

Methods

handle

Executes the console command. It iterates over the configured links and performs the necessary actions to create the symbolic links. If a link already exists and the force option is not enabled, an error message is displayed. If the link is a symbolic link, it is deleted before creating the new link. The type of link (relative or absolute) is determined based on the provided option. Information messages are displayed for each successful link creation.

links

Gets the symbolic links that are configured for the application. It retrieves the links from the filesystems.links configuration array in the Laravel container. If the configuration does not exist, a default link configuration (public_path('storage') => storage_path('app/public')) is returned.

isRemovableSymlink

Determines if the provided path is a symlink that can be removed. It checks if the path is a symbolic link and if the force option is enabled.

<?php

namespace Illuminate\Foundation\Console;

use Illuminate\Console\Command;
use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'storage:link')]
class StorageLinkCommand extends Command
{
    /**
     * The console command signature.
     *
     * @var string
     */
    protected $signature = 'storage:link
                {--relative : Create the symbolic link using relative paths}
                {--force : Recreate existing symbolic links}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Create the symbolic links configured for the application';

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        $relative = $this->option('relative');

        foreach ($this->links() as $link => $target) {
            if (file_exists($link) && ! $this->isRemovableSymlink($link, $this->option('force'))) {
                $this->components->error("The [$link] link already exists.");
                continue;
            }

            if (is_link($link)) {
                $this->laravel->make('files')->delete($link);
            }

            if ($relative) {
                $this->laravel->make('files')->relativeLink($target, $link);
            } else {
                $this->laravel->make('files')->link($target, $link);
            }

            $this->components->info("The [$link] link has been connected to [$target].");
        }
    }

    /**
     * Get the symbolic links that are configured for the application.
     *
     * @return array
     */
    protected function links()
    {
        return $this->laravel['config']['filesystems.links'] ??
               [public_path('storage') => storage_path('app/public')];
    }

    /**
     * Determine if the provided path is a symlink that can be removed.
     *
     * @param  string  $link
     * @param  bool  $force
     * @return bool
     */
    protected function isRemovableSymlink(string $link, bool $force): bool
    {
        return is_link($link) && $force;
    }
}