I want to use create folder function with vich considering id.
My service:
<?php
namespace App\Service\Namers;
use Vich\UploaderBundle\Mapping\PropertyMapping;
use Vich\UploaderBundle\Naming\DirectoryNamerInterface;
use App\Entity\Users;
class VichNamer implements DirectoryNamerInterface {
public function directoryName(object $object, PropertyMapping $mapping): string {
return 'test';
}
}
my vich_uploader.yaml:
vich_uploader:
db_driver: orm
metadata:
type: attribute
mappings:
tattoo_images:
uri_prefix: /images/
upload_destination: '%kernel.project_dir%/public/images/'
directory_namer: App\Service\Namers\VichNamer
My services.yaml:
parameters:
images_directory: '%kernel.project_dir%/public/uploads'
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.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
App\EventSubscriber\EasyAdminSubscriber:
tags:
- { name: 'doctrine.event_subscriber', event: preUpdate }
App\Service\Namers\VichNamer:
public: true
tags:
- { name: 'vich.namedirectory' }
My error:
A namer must be configured.
I user symfoy 6.2
thank you
The namer is used to name the files and directories it saves to the filesystem
You can add nammer by default like this in your config:
vich_uploader:
.....
mappings:
tattoo_images:
uri_prefix: /images/
upload_destination: '%kernel.project_dir%/public/images/'
directory_namer: App\Service\Namers\VichNamer
namer:
service: Vich\UploaderBundle\Naming\PropertyNamer
options: { property: 'slug' }
You can see all options working with namer here : namers
Related
Need to connect to multiple databases and followed the Symfony documentation on this matter.
I have created multiple doctrine connections and orm entity managers, and disabled autowiring.
# config/packages/doctrine.yaml
doctrine:
dbal:
default_connection: default
connections:
default:
# configure these for your database server
url: "%env(resolve:DATABASE_URL)%"
driver: "pdo_mysql"
server_version: "5.7"
charset: utf8mb4
lc_cvo:
# configure these for your database server
url: "%env(resolve:DATABASE_LC_CVO_URL)%"
driver: "pdo_mysql"
server_version: "5.7"
charset: utf8mb4
lc_cvt:
# configure these for your database server
url: "%env(resolve:DATABASE_LC_CVT_URL)%"
driver: "pdo_mysql"
server_version: "5.7"
charset: utf8mb4
lc_ewi:
# configure these for your database server
url: "%env(resolve:DATABASE_LC_EWI_URL)%"
driver: "pdo_mysql"
server_version: "5.7"
charset: utf8mb4
lc_tbo:
# configure these for your database server
url: "%env(resolve:DATABASE_LC_TBO_URL)%"
driver: "pdo_mysql"
server_version: "5.7"
charset: utf8mb4
lc_users:
# configure these for your database server
url: "%env(resolve:DATABASE_LC_USERS_URL)%"
driver: "pdo_mysql"
server_version: "5.7"
charset: utf8mb4
orm:
entity_managers:
default:
connection: default
mappings:
Main:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake"
prefix: 'App\Entity\lmc_lemoncake'
alias: Main
lc_cvo:
connection: lc_cvo
mappings:
lc_cvo:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake-cvo"
prefix: 'App\Entity\lmc_lemoncake_cvo'
alias: lc_cvo
lc_cvt:
connection: lc_cvt
mappings:
lc_cvt:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake-cvt"
prefix: 'App\Entity\lmc_lemoncake_cvt'
alias: lc_cvt
lc_ewi:
connection: lc_ewi
mappings:
lc_ewi:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake-ewi"
prefix: 'App\Entity\lmc_lemoncake_ewi'
alias: lc_ewi
lc_tbo:
connection: lc_tbo
mappings:
lc_tbo:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/src/Entity/lmc_lemoncake-tbo"
prefix: 'App\Entity\lmc_lemoncake_tbo'
alias: lc_tbo
lc_users:
connection: lc_users
mappings:
lc_users:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/src/Entity/lmc_users"
prefix: 'App\Entity\lmc_users'
alias: lc_users
My services.yaml file looks like this
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
services:
# default configuration for services in *this* file
_defaults:
autowire: false # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: "../src/"
exclude:
- "../src/DependencyInjection/"
- "../src/Entity/"
- "../src/Kernel.php"
- "../src/Tests/"
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: "../src/Controller/"
tags: ["controller.service_arguments"]
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
Unfortunately I am receiving the following error when trying to access the login page.
Too few arguments to function App\Security\LoginFormAuthenticator::__construct(), 0 passed in /var/www/html/app/var/cache/dev/Container12fc4el/getSecurity_Firewall_Map_Context_MainService.php on line 53 and exactly 4 expected
The LoginFormAuthenticator it is referring to is listed here and needs to connect to the lc_users connection where the users' info (username, pw) is located.
I will be needing the other connections to get the client data.
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;
public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
{
$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
}
I believe I need to add something to my services so the Authenticator can retrieve the correct connection, unfortunately my knowledge on the matter is not sufficient.
I need to use multiple databases for multiple clients.
How do I fix the issue at hand?
How do I prevent this issue from occurring with the other connections?
Am I handling this in a correct way, or is there a better approach for connecting to multiple databases?
Thank you in advance for your help, feel free to ask for more info.
EDIT:
Thanks to #msg for the answer; I've managed to make it work through the following code:
app/config/services.yaml:
App\Security\LoginFormAuthenticator:
autowire: true
tags: ["doctrine.repository_service"]
arguments:
$entityManager: "#doctrine.orm.lc_users_entity_manager"
app/config/doctrine.yaml:
orm:
default_entity_manager: default
entity_managers:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
default:
...
lc_users:
connection: lc_users
mappings:
App\Entity\lmc_lemoncake:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/src/Entity/lmc_users"
prefix: 'App\Entity\lmc_users'
alias: lc_users
(part of) the getUser function of the LoginFormAuthenticator:
$em = $this->entityManager;
$repo = $em->getRepository(Users::class, 'lc_users');
$user = $repo->findOneBy(['username' => $credentials['username']]);
As already said, injecting EntityManager will get you the default one. Doctrine will register one service per manager with the name doctrine.orm.%manager_name%_entity_manager.
So if you need a different one, you have several options:
1. Explicitly configure your service to use the manager you need:
services:
App\Security\LoginFormAuthenticator:
arguments:
# Override the Manager, other arguments will be autowired.
$entityManager: '#doctrine.orm.lc_users_entity_manager'
2. Create different bindings for the different entity managers:
_defauts:
bind:
$cvoManager: '#doctrine.orm.lc_cvo_entity_manager'
$usersManager: '#doctrine.orm.lc_users_entity_manager'
# Other managers...
Based on the variable name on your dependency, the appropiate manager will be injected:
public function __construct(
EntityManagerInterface $entityManager, // Default manager
EntityManagerInterface $usersManager,
)
3. If you have many dependencies, you can also inject ManagerRegistry (the object you get in an AbstractController when you call getDoctrine()). It acts as a service locator from where you can retrieve managers or repositories:
use Doctrine\Persistence\ManagerRegistry;
public function __construct(ManagerRegistry $registry) {
$userManager = $registry->getManager('users');
}
The first option can get unwieldy fast if you have many services with different dependencies, and the third one will mask your real dependencies and complicate testing if you need to mock the registry.
I'm trying to encode the password im passing through post but it is giving me an error when I declare the argument in the function.
Could not resolve argument $encoder of "App\Controller\UsuarioController::altapropietario()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?*
Here I paste the whole function, it has a form and its just for registering new users.
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class UsuarioController extends AbstractController
{
public function altaPropietario(Request $request, UserPasswordEncoderInterface $encoder )
{
$propietario = new Usuario();
$form = $this->createForm(AltaPropietarioType::class, $propietario);
$form->handleRequest($request);
if ($form->isSubmitted())
{
$propietario->setRole("ROLE_PROP");
$encoded = $encoder->encodePassword($propietario, $propietario->getPassword());
$propietario->setPassword($encoded);
// rest of the implementation not included.
}
}
}
My security yml is the following:
security:
encoders:
App\Entity\Usuario: bcrypt
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
users_in_memory: { memory: null }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: lazy
provider: users_in_memory
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
services.yaml:
parameters:
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.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
I have the following Doctrine entities where EntityA is the owning side:
<?php
class EntityA
{
/**
* #ORM\ManyToOne(targetEntity="EntityB" , inversedBy="propertyA")
*/
private $propertyB;
// ....
public function setEntityB(EntityB $entBRef)
{
$this->propertyB = $entBRef;
}
}
class EntityB
{
/**
* #ORM\OneToMany(targetEntity="EntityA", mappedBy="propertyB")
*/
private $propertyA;
// ....
}
I do also have a RepositoryB class:
<?php
class RepositoryB extends \Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository
{
public function __construct(\Doctrine\Common\Persistence\ManagerRegistry $registry)
{
parent::__construct($registry, EntityB::class);
}
}
Then in my class I am trying to persist an EntityA object:
<?php
class SomeService
{
/** #var RepositoryB */
private $repositoryB;
/** #var EntityManagerInterface */
private $entityManager;
public function __construct(RepositoryB $repositoryB, EntityManagerInterface $entityManager)
{
$this->repositoryB = $repositoryB;
$this->entityManager = $entityManager;
}
public function testSomething()
{
$entBRef = $this->repositoryB->find(1);
$newEnt = (new EntityA());
$newEnt->setEntityB($entBRef);
$this->entityManager->persist($newEnt);
$this->flush();
}
}
But I've got the following error:
A new entity was found through the relationship 'EntityA#propertyB'
that was not configured to cascade persist operations for entity:
EntityB. To solve this issue: Either explicitly call
EntityManager#persist() on this unknown entity or configure cascade
Here is how my doctrine.yaml file looks like:
parameters:
env(DATABASE_URL_WRITE): ''
services:
gedmo.listener.timestampable:
class: Org\CompBundle\Gedmo\Timestampable\TimestampableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ "#annotation_reader" ] ]
gedmo.listener.loggable:
class: Gedmo\Loggable\LoggableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ "#annotation_reader" ] ]
gedmo.listener.deleteable:
class: Gedmo\SoftDeleteable\SoftDeleteableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ '#annotation_reader' ] ]
doctrine:
dbal:
default_connection: default
types:
microseconds: Org\CompBundle\DBAL\Types\DateTimeMicrosecondsType
connections:
read_only:
url: '%env(resolve:DATABASE_URL_READ)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
default:
url: '%env(resolve:DATABASE_URL_WRITE)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: default
entity_managers:
filters:
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
enabled: true
read_only:
connection: read_only
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
gedmo_loggable:
type: annotation
prefix: Gedmo\Loggable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Loggable/Entity"
alias: GedmoLoggable
is_bundle: false
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/vendor/org/comp-bundle/Entity'
prefix: 'Org\CompBundle\Entity'
alias: Drm
dql:
datetime_functions:
timetosec: DoctrineExtensions\Query\Mysql\TimeToSec
timediff: DoctrineExtensions\Query\Mysql\TimeDiff
now: DoctrineExtensions\Query\Mysql\Now
numeric_functions:
rand: DoctrineExtensions\Query\Mysql\Rand
default:
connection: default
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
enabled: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
gedmo_loggable:
type: annotation
prefix: Gedmo\Loggable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Loggable/Entity"
alias: GedmoLoggable
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/vendor/org/comp-bundle/Entity'
prefix: 'Org\CompBundle\Entity'
alias: Drm
dql:
datetime_functions:
timetosec: DoctrineExtensions\Query\Mysql\TimeToSec
timediff: DoctrineExtensions\Query\Mysql\TimeDiff
now: DoctrineExtensions\Query\Mysql\Now
numeric_functions:
rand: DoctrineExtensions\Query\Mysql\Rand
Last but not least I do have the following setup at org\compbundle\Resources\services.yaml:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
bind:
$logger: '#Psr\Log\LoggerInterface'
Org\CompBundle\Repository\:
resource: '../../Repository/{Case,Main}'
exclude: ['../../Repository/**/*Interface.php']
tags: ['doctrine.repository_service']
Org\CompBundle\Interfaces\Queues\QueueRepositoryInterface:
class: Org\CompBundle\Repository\DrmCase\QueueRepository
Org\CompBundle\Interfaces\Cases\CasesRepositoryInterface:
class: Org\CompBundle\Repository\DrmCase\CasesRepository
Doctrine\Common\Persistence\ManagerRegistry: '#doctrine'
What I have done so far?
Read a lot of post here on SO leading to the same solution add cascade={"persist"} to the owning side which I did and I must say did not work.
Read Doctrine docs looking for mistakes on my entities definition but so far everything looks fine to me.
I did found this which is helpful but I keep questioning myself why would Doctrine tries to insert and existent entity just because of the reference? Is there any way to get this working?
I do not want the EntityB persisted nor updated, it already exists. I do want the new EntityA have a FK to an existent record in EntityB.
During the weekend a work colleague did work very hard to find out what was causing the issue and after a lot of hours debugging how Doctrine and the UoW works he found where the problem was: how Doctrine and the Repository pattern works. Let me explain a little bit.
If you check this closer and go deep inside Doctrine you will notice how the following code leads to two different entities manager:
public function __construct(RepositoryB $repositoryB, EntityManagerInterface $entityManager)
{
$this->repositoryB = $repositoryB; // spin his own EM
$this->entityManager = $entityManager; // this is a new EM object
}
So:
$entBRef = $this->repositoryB->find(1);
Is being fetched through another EM and since I am using $this->entityManager to persist/flush the recently created entityA object then Doctrine sees $entBRef as a new entity that has to be persisted.
Our solution was to fetch everything through the same repository class which I do not like so much because we are querying things that does not belongs there and we had to ever persist/flush using the same EM.
If you have any other solution it is more than welcome.
I have the following simple class:
<?php
namespace App\EventListener;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class LoginListener implements EventSubscriberInterface
{
private $logger = null;
public function __construct (LoggerInterface $logger)
{
$this->logger = $logger;
}
public function onInteractiveLogin (InteractiveLoginEvent $event)
{
$this->logger->info('TEST');
}
public static function getSubscribedEvents ()
{
return [
SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin',
];
}
}
It is under the /src and should autoload (Symfony 4.1.0).
When I run:
bin/console debug:event-dispatcher security.interactive_login
I see expected results:
Registered Listeners for "security.interactive_login" Event
------- ------------------------------------------------------- ----------
Order Callable Priority
------- ------------------------------------------------------- ----------
#1 App\EventListener\LoginListener::onInteractiveLogin() 0
------- ------------------------------------------------------- ----------
And yet when I login successfully (or otherwise) that log message isn't where there - digging into Symfony profiler - I can see it's under the "Not Called Listeners" tab???
Any ideas what I am missing?
EDIT |
services.yaml:
imports:
- { resource: 'company.yaml' }
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
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.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Legacy}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
#
# ldap authentication service configuration
# https://symfony.com/doc/current/reference/configuration/security.html
Symfony\Component\Ldap\Ldap:
arguments: ['#Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
arguments:
- host: davinci-1
port: 389
#encryption: tls
options:
protocol_version: 3
referrals: false
#
# We need to hook into default LDAP authentication to properly populate Symfony
# roles and / or return legacy groups
# http://symfony.com/doc/current/components/security/authentication.html#authentication-events
# http://symfony.com/doc/current/event_dispatcher.html
#App\EventListener\LoginListener:
# tags:
# - { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin }
security.yaml
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
ad_ldap:
ldap:
service: Symfony\Component\Ldap\Ldap
base_dn: dc=company,dc=local
search_dn: 'appuser'
search_password: "XXX"
default_roles: ROLE_USER
uid_key: 'sAMAccountName'
filter: '({uid_key}={username})'
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
http_basic_ldap:
provider: ad_ldap
service: Symfony\Component\Ldap\Ldap
dn_string: 'Company\{username}'
#query_string: '(sAMAccountName={username})'
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
I tring to get an argument in my services.yaml for my ImageManager.php but it's not working and I can not solve this error.
here is the mistake :
Type error: Too few arguments to function App\Manager\ImageManager::__construct(), 0 passed in C:\wamp64\www\SymfonyAPI\var\cache\dev\ContainerZxFSS5S\getImageManagerService.php on line 14 and exactly 1 expected
services.yaml
parameters:
images_directory: '%kernel.project_dir%/public/uploads/images/'
...
services:
_defaults:
autowire: false
autoconfigure: false
public: true
App\Manager\ImageManager:
arguments:
$targetDir: '%images_directory%'
if for autowire & autoconfigure I put true I have this error :
RuntimeException
Cannot autowire service "App\Manager\ImageManager": argument "$targetDir" of method "__construct()" has type "App\Manager\targetDir" but this class was not found.
ImageManager.php
private $targetDir;
public function __construct(targetDir $targetDir)
{
$this->targetDir = $targetDir;
}
Full services.yml
parameters:
liip_imagine.mozjpeg.binary: /mozjpeg/cjpeg.exe
images_directory: '%kernel.project_dir%/public/uploads/images/'
mozjpg_directory: '%kernel.project_dir%/mozjpg'
locale: 'en'
services:
_defaults:
autowire: false
autoconfigure: false
public: true
App\Manager\ImageManager:
arguments:
$targetDir: '%images_directory%'
App\EventListener\ImageUploadListener:
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
app.post_processor.my_custom_post_processor:
class: '%kernel.project_dir%/src/Controller/ImageController.php'
tags:
- { name: 'liip_imagine.filter.post_processor', post_processor: 'mozjpeg' }
You are adding a type of targetDir and your Application thinks that is some kind of class and you can see that in your error has type "App\Manager\targetDir" but this class was not found., just replace targetDir with string if you are on php 7 or don't put anything as a type and it will work even if you have autowire true/false because of:
App\Manager\ImageManager:
arguments:
$targetDir: '%images_directory%'
To clarify the answer by #kunicmarko20
Your service constructor requires an object of App\Manager\targetDir as the $targetDir argument, but you are supplying your service with a string as the $targetDir argument.
You need to change your service constructor to look like one of the following.
PHP 7.x
public function __construct(string $targetDir)
PHP 5.x
public function __construct($targetDir)
Update with configuration changes
The second issue you have is that you have prototyping enabled on your service class directory. This causes Symfony to override your manual service definition with the prototype service definition.
So what happens is your manual service definition is created, then overridden by the auto configured definition.
The prototype definition is
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
Since it is below your manual service definition, Symfony uses it instead of your manual definition.
For example if I write
services:
AppBundle\MyDirectory\Object:
parameters: ['a']
AppBundle\MyDirectory\Object:
parameters: ['b']
The end result of what symfony uses as the service definition would be.
new AppBundle\MyDirectory\Object('b');
You should change your services.yml to the following:
parameters:
liip_imagine.mozjpeg.binary: /mozjpeg/cjpeg.exe
images_directory: '%kernel.project_dir%/public/uploads/images/'
mozjpg_directory: '%kernel.project_dir%/mozjpg'
locale: 'en'
services:
_defaults:
autowire: false
autoconfigure: false
public: true
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
#... Your manual service definitions below here.
App\Manager\ImageManager:
arguments:
$targetDir: '%images_directory%'
App\EventListener\ImageUploadListener:
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
app.post_processor.my_custom_post_processor:
class: '%kernel.project_dir%/src/Controller/ImageController.php'
tags:
- { name: 'liip_imagine.filter.post_processor', post_processor: 'mozjpeg' }