I got a class use to upload file as service like symfony documentation. https://symfony.com/doc/current/controller/upload_file.html#creating-an-uploader-service
I use symfony 5.
When i declare service in main config/services.yaml, this work.
But i have a bundle for file management and i want to put service declaration in this bundle : App/AD/ExplorerBundle/Resources/config/services.yaml.
When i do that this doesn't work anymore.
I have error
Cannot resolve argument $fileUploader of "App\AD\ExplorerBundle\Controller\FileController::addAction()": Cannot autowire service "App\AD\ExplorerBundle\Service\FileUploader": argument "$targetDirectory" of method "__construct()" is type-hinted "string", you should configure its value explicitly.
I don't understand why, because _defaults autoconfigure and autowire = true
I test cache:clear, reload server, but nothing work.
Any help will be apreciate
Edit : my bundle extension: in AD\ExplorerBundle\DependencyInjection
<?php
namespace App\AD\ExplorerBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
/**
* This is the class that loads and manages your bundle configuration.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class ADExplorerExtension extends Extension
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
my bundle service : in AD\ExplorerBundle\Service
<?php
namespace App\AD\ExplorerBundle\Service;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\String\Slugger\SluggerInterface;
class FileUploader
{
private $targetDirectory;
private $slugger;
public function __construct(string $targetDirectory, SluggerInterface $slugger)
{
$this->targetDirectory = $targetDirectory;
$this->slugger = $slugger;
}
public function upload(UploadedFile $file): array
{
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $this->slugger->slug($originalFilename);
$fileName = $safeFilename.'-'.uniqid().'.'.$file->guessExtension();
$result = array(
'filename' => $fileName,
'originalName' => $originalFilename,
'extension' => $file->guessExtension()
);
try {
$file->move($this->getTargetDirectory(), $fileName);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
return $result;
}
public function getTargetDirectory()
{
return $this->targetDirectory;
}
}
my config/services.yaml
parameters:
locale: 'fr'
doctrine_behaviors_translatable_fetch_mode: "LAZY"
doctrine_behaviors_translation_fetch_mode: "LAZY"
imports:
- { resource: '@ADCoreBundle/Resources/config/services.yml' }
- { resource: './parameters.yaml' }
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
my Bundle service : in AD\ExplorerBundle\Resources\config\service.yaml
parameters:
brochures_directory: '%kernel.project_dir%/public/uploads'
services:
ad_file_uploader:
class: App\AD\ExplorerBundle\Service\FileUploader
arguments:
$targetDirectory: '%brochures_directory%'
I read documentation : https://symfony.com/doc/current/bundles/extension.html
https://symfony.com/doc/current/service_container.html#manually-wiring-arguments
https://symfony.com/doc/current/service_container/autowiring.html
I don't really understand this :
Public and Reusable Bundles¶
Public bundles should explicitly configure their services and not rely on autowiring. Autowiring depends on the services that are available in the container and bundles have no control over the service container of applications they are included in. You can use autowiring when building reusable bundles within your company, as you have full control over all code.
I think it's ok because it's my bundle and my application so i have full control of code.
So, i test a lot of thing but nothing work.
If anybody have an idea Thanks
App\: resource: '../src/*' exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
in my services.yaml ? – threeside