Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flysystem Bundle Laravel Package

league/flysystem-bundle

View on GitHub
Deep Wiki
Context7

Creating a custom adapter

Read the associated library documentation

If you have highly specific requirements, you may need to create your own Flysystem adapter. To do so, you first need to create the adapter code itself and then use it in your storages configuration.

Creating the adapter class

A Flysystem adapter is a class implementing the League\Flysystem\FilesystemAdapter interface. To learn all the details about how to create this class, you can read the library documentation.

You can create this class anywhere you want in your application. We usually recommend a clear namespace and class name such as App\Flysystem\MyCustomAdapter.

Using the adapter in a storage configuration

To use the adapter inside your storages configuration, you need to register your newly created as a service. Fortunately, in most Symfony 4.2+ applications, this is done automatically by Symfony.

Note: if you disabled autodiscovery, you can register manually your adapter as a normal service and use the ID your registered instead of the class name in the next YAML examples.

Once created and (automatically) registered as a service, you can reference your adapter inside your storages:

# config/packages/flysystem.yaml

flysystem:
    storages:
        users.storage:
            service: 'App\Flysystem\MyCustomAdapter'

Creating a custom adapter builder (advanced)

For more complex custom adapters that require configuration validation, IDE auto-completion, and integration with the bundle's configuration system, you can create a custom adapter builder.

This allows you to define your custom adapter directly in the configuration:

# config/packages/flysystem.yaml

flysystem:
    storages:
        users.storage:
            my_custom: # Your custom adapter type
                option1: 'value1'
                option2: 'value2'

Creating the adapter builder

Create a class implementing AdapterDefinitionBuilderInterface:

<?php

namespace App\Flysystem\Builder;

use App\Flysystem\MyCustomAdapter;
use League\FlysystemBundle\Adapter\Builder\AdapterDefinitionBuilderInterface;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

class MyCustomAdapterDefinitionBuilder implements AdapterDefinitionBuilderInterface
{
    public function getName(): string
    {
        return 'my_custom';
    }

    public function getRequiredPackages(): array
    {
        // Return required packages for your adapter
        // Format: ['ClassName' => 'vendor/package-name']
        return [];
    }

    public function addConfiguration(NodeDefinition $node): void
    {
        $node
            ->children()
                ->scalarNode('option1')
                    ->isRequired()
                    ->info('Description of option1')
                ->end()
                ->scalarNode('option2')
                    ->defaultValue('default_value')
                    ->info('Description of option2')
                ->end()
                ->booleanNode('option3')
                    ->defaultFalse()
                    ->info('Description of option3')
                ->end()
            ->end();
    }

    public function createAdapter(ContainerBuilder $container, string $storageName, array $options, ?string $defaultVisibilityForDirectories): string
    {
        $adapterId = 'flysystem.adapter.' . $storageName;

        $definition = new Definition(MyCustomAdapter::class);
        $definition->setPublic(false);
        
        // Configure your adapter with the options
        $definition->setArgument(0, $options['option1']);
        $definition->setArgument(1, $options['option2']);
        $definition->setArgument(2, $options['option3']);

        $container->setDefinition($adapterId, $definition);

        return $adapterId;
    }
}

Registering the adapter builder

Via Bundle (recommended for reusable bundles)

If you're creating a bundle, register your builder in your bundle class:

<?php

namespace App\MyCustomBundle;

use App\Flysystem\Builder\MyCustomAdapterDefinitionBuilder;
use League\FlysystemBundle\FlysystemBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class MyCustomBundle extends Bundle
{
    public function build(ContainerBuilder $container): void
    {
        parent::build($container);

        // Register your custom adapter builder
        $extension = $container->getExtension('flysystem');
        if ($extension instanceof FlysystemExtension) {
            $extension->addAdapterDefinitionBuilder(new MyCustomAdapterDefinitionBuilder());
        }
    }
}

Via Kernel (for application-specific adapters)

For application-specific adapters, register your builder in your Kernel:

<?php

namespace App;

use App\Flysystem\Builder\MyCustomAdapterDefinitionBuilder;
use League\FlysystemBundle\DependencyInjection\FlysystemExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
    // ...

    protected function build(ContainerBuilder $container): void
    {
        parent::build($container);

        // Register your custom adapter builder
        $extension = $container->getExtension('flysystem');
        if ($extension instanceof FlysystemExtension) {
            $extension->addAdapterDefinitionBuilder(new MyCustomAdapterDefinitionBuilder());
        }
    }
}

Once registered, you can use the debug:config flysystem command to see your custom adapter and all its available options in the configuration tree.

Testing your custom builder

Create a test class extending AbstractAdapterDefinitionBuilderTest:

<?php

namespace Tests\App\Flysystem\Builder;

use App\Flysystem\Builder\MyCustomAdapterDefinitionBuilder;
use App\Flysystem\MyCustomAdapter;
use League\FlysystemBundle\Test\AbstractAdapterDefinitionBuilderTest;
use Symfony\Component\DependencyInjection\Definition;

class MyCustomAdapterDefinitionBuilderTest extends AbstractAdapterDefinitionBuilderTest
{
    protected function createBuilder(): MyCustomAdapterDefinitionBuilder
    {
        return new MyCustomAdapterDefinitionBuilder();
    }

    public static function provideValidOptions(): \Generator
    {
        yield 'minimal' => [[
            'option1' => 'value1',
        ]];

        yield 'full' => [[
            'option1' => 'value1',
            'option2' => 'custom_value',
            'option3' => true,
        ]];
    }

    protected function assertDefinition(Definition $definition): void
    {
        $this->assertSame(MyCustomAdapter::class, $definition->getClass());
        $this->assertSame('value1', $definition->getArgument(0));
        $this->assertSame('custom_value', $definition->getArgument(1));
        $this->assertTrue($definition->getArgument(2));
    }
}

This provides comprehensive testing of your builder's configuration and adapter creation logic.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui