Symfony autowiring issues since docker update - php

I'm having autowiring issues within symfony since I have updated my Docker to the latest version.
I am not entirely sure of the causality here but certainly, my issues started appearing only after updating my docker. Since this was the case I obviously tried to revert back to a previous docker version but still had the same issues as on the new build. That's why I am doubtful of the causality.
I'm now on: Docker version 3.5.2 with Docker Engine v20.10.7
docker-engine config is the unchanged config:
{
"registry-mirrors": [],
"insecure-registries": [],
"debug": false,
"experimental": false,
"features": {
"buildkit": true
},
"builder": {
"gc": {
"enabled": true,
"defaultKeepStorage": "20GB"
}
}
}
when I started my first project I had an issue with the composer not reading my lib-folder. This was solved as described below but it might provide some more insight, context and things I have checked/done
At first my mind went to this Windows env variable. Alas, it was set so it was not the problem.
Secondly, my mind went to file ownership or file permissions but also not the problem. Everything in my containers was owned by root and had rwx permissions.
Thirdly I thought it might be because of the new WSL2 backend I had to install. Until the day of the update I had still been running on the Hyper-V backend. Luckily there is a setting in docker where you can switch off the use of WSL-2 and revert to Hyper-V but this was also not the solution to my problem.
My composer.json looked like this:
"autoload": {
"classmap": [
"scripts/composer/ScriptHandler.php",
"lib/",
...
],
"psr-4": {
...
}
},
Everything but (some) files of lib were present in my autoload_classmap.php
After fiddling about for too long I finally tried the following and suddenly my problems on my first project were gone
"autoload": {
"classmap": [
"scripts/composer/ScriptHandler.php",
"lib/*",
...
],
"psr-4": {
...
}
},
I still don't understand why the first one should not work. It has worked until this thursday since the infamous update.
Now on to the second project and I really can't figure out what's going on and I'm at a loss for words. My colleagues can't seem to figure out what's wrong either. This second project is something more recent so not loading a classmap anymore and everything follows PSR-4 standards.
This is the autoload part of the composer.json:
"autoload": {
"psr-4": {
"App\\": "src/",
"Project\\": "scripts/"
}
},
This is my services.yaml (These are just the standard symfony settings AFAIK):
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,Kernel.php}'
This is my docker PHP container:
php:
container_name: "${DOCKER_PROJECT_NAME}_php"
environment:
COLUMNS: 80
PHP_FPM_GROUP: wodby
PHP_FPM_USER: wodby
PHP_SENDMAIL_PATH: "/usr/sbin/sendmail -t -i -S mailhog:1025"
PHP_DEFAULT_CHARSET: 'utf-8'
PHP_DATE_TIMEZONE: 'UTC'
PHP_UPLOAD_MAX_FILESIZE: '10M'
PHP_POST_MAX_SIZE: '10M'
PHP_DISPLAY_ERRORS: 'On'
PHP_DISPLAY_STARTUP_ERRORS: 'On'
PHP_MAX_EXECUTION_TIME: '30000'
PHP_MAX_INPUT_TIME: '60'
PHP_MAX_INPUT_VARS: '2000'
PHP_ERROR_REPORTING: 'E_ALL'
PHP_LOG_ERRORS: 'On'
PHP_LOG_ERRORS_MAX_LEN: '0'
PHP_MEMORY_LIMIT: '512M'
PHP_SESSION_GC_MAXLIFETIME: '700000'
PHP_REALPATH_CACHE_SIZE: '4096K'
PHP_REALPATH_CACHE_TTL: '3600'
PHP_XHPROF: $PROFILING_ENABLED
env_file:
- .env
image: "wodby/php:7.4-dev-4.16.2"
volumes:
- "./:/var/www/html"
## For php profiler traces
- "files:/mnt/files"
On startup I am getting the following Runtime Exception:
Cannot autowire service "App\Form\Wizard\DaysOffType": argument "$daycareTransformer" of method "__construct()" references class "App\Form\DaycareTransformer" but no such service exists.
This class is not new, it's been in code for 2 years. It's in the right folder and the namespacing is correct. Also the src folder is included in the autoload_psr4.php.
The DaycareTransformer that "can't be found" is located in src/Form under the namespace App\Form as per psr4 namespace convention
<?php
namespace App\Form;
use App\Entity\Daycare;
use App\Service\DaycareService;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class DaycareTransformer implements DataTransformerInterface
{
private $daycareService;
public function __construct(DaycareService $daycareService)
{
$this->daycareService = $daycareService;
}
...
}
There have not been any recent changes to this code. Not to the DaysOffType which has the DaycareTransformer injected and not to the DaycareTransformer.
I am the only person having these issues as I am the only one who runs Docker on a Windows machine. Production and QA environments are all up and running so there is no structural problem in the code.

It could be because the project running symphony in this case was locate at Windows partition (C: or D: or whatever inside your window) and not Linux distro.
If you are using WSL (most likely), you should always store Linux related project inside your distro (Ubuntu in my case, I store it it ~/...). You should not store Linux related project in /mnt/... when using WSL.
When I said "Linux related" I mean whatever project usually want to run on Linux environment, or using docker
Don't know if this could solve it for others because there could be a wide range of reason for this problem. But this is how I solve mine.

We've got the same problem on a Windows machine with Docker and Symfony 5.x.
We continued to work on this machine, but we changed our configuration.
For example, for your error I would use the following config.
Cannot autowire service "App\Form\Wizard\DaysOffType": argument "$daycareTransformer" of method "__construct()" references class "App\Form\DaycareTransformer" but no such service exists.
config/services.yml or config/services_dev.yml
services:
App\Form\DaycareTransformer: ~
We defined all the required classes from our errors and it solved our problem. But it solved problem only for one URL instead of all. You need to check each your routes or classes that use Symfony's autowire.
Unfortunately, the solution like declaration of resources didn't for us. We had to define all the required classes from our errors.
services:
App\DataTransformer\:
resource: '../src/DataTransformer/'
Don't redefined your classes that have already defined in your config, because it replaces your configuration and may make other errors.
You can do it in config/services.yml and commit it or you can use config/service_dev.yml and don't commit it if you haven't use this config before. In the second way you also can change .gitignore and add there the filename.
# Ignore changes for the file and don't track it.
config/services_dev.yml
WARNING! If you still have problems with it define all the required classes in services.yml instead of two or more config files.
We don't have this problem on Linux and MacOS machines.

Related

`lando artisan` command returns a weird error

If you've worked with Laravel and Lando together, you probably know that Lando gives you its own artisan shortcut. So instead of having to run lando php artisan ..., you can run lando artisan ....
However, when I do that, I get this error:
Could not open input file: /app/./../artisan
This forces me to have to run lando php artisan to run any artisan commands, and that does work fine. So far, this is all that's going wrong with my project in Lando. Everything else is running smoothly.
Here's what my lando config looks like:
name: laravel-project
recipe: laravel
config:
php: '7.4'
composer_version: '2.0.12'
database: mysql:8.0
services:
appserver:
webroot: public
xdebug: true
config:
php: .vscode/php.ini
node:
type: node:14
tooling:
node:
service: node
yarn:
service: node
Also, this does look a bit different from Lando's sample config on their website. This is because I was trying to configure xdebug according to their "Using Lando with VSCode" instructions (see Lando rc.2+ version).
Appreciate any help figuring this weird issue out. It's not debilitating, but it does get in the way when I forget the workaround.
Other notes:
"webroot" is set to "public" because that's where the public-facing directory is for a Laravel app. The example Lando config for Laravel has this part wrong and it causes the project root to be visible to the browser.
I got it working. I moved the webroot key back under the top-level config. Not sure what the difference is, but as long as it works... I guess the only thing I really need to specify in the appserver service is the Xdebug settings.
name: laravel-project
recipe: laravel
config:
php: '7.4'
composer_version: '2.0.12'
webroot: public
database: mysql:8.0
services:
appserver:
xdebug: true
config:
php: .vscode/php.ini
node:
type: node:14
tooling:
node:
service: node
yarn:
service: node

Could not find any fixture services to load

i know this question has been asked already multiple times:
Symfony 3.4 and Fixtures Bundle issue with bundle version 3.0
Symfony 3.4.0 Could not find any fixture services to load
Symfony Doctrine can't find fixtures to load
Could not find any fixture services to load - Symfony 3.2
None of the above actually helped me out. That said, this is my configuration:
Composer.json
"require": {
"php": ">=7.0",
"doctrine/doctrine-bundle": "^1.6",
"doctrine/orm": "^2.5",
....
},
"require-dev": {
....
"doctrine/doctrine-fixtures-bundle": "^3.0",
}
I'm using a company-developed Bundle which worked fine until the last version of the above (last tested and working configuration had PHP 5.6, Doctrine bundle ^1.6,doctrine orm ^2.5, fixture bundle ^3.0).
This bundle has some Fixture inside VendorName/BundleName/DataFixtures/ORM, all the fixtures have the following declaration:
Class MyFixture1 extends Fixture implements OrderedFixtureInterface,FixtureInterface, ContainerAwareInterface{
...
}
Inside this bundle there's a services.yml file, loaded by this:
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
VendorName/BundleName/Resources/config/Services.yml i tried different configurations:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
VendorName\BundleName\:
resource: '../../*'
# you can exclude directories or files but if a service is unused, it's removed anyway
exclude: '../../{Entity,Repository,Tests,EventListener}'
I tried expliciting searching inside DataFixtures:
VendorName/BundleName\DataFixtures\:
resource: '../../src/VendorName/BundleName/DataFixtures'
tags: ['doctrine.fixture.orm']
And even manually configure the service:
VendorName\BundleName\DataFixtures\ORM\MyFixture1:
class: VendorName/BundleNamee\DataFixtures\ORM\MyFixture1
tags: ['doctrine.fixture.orm']
But unfortunately it keeps giving the error. Any idea of what i'm doing wrong? Long time ago it was possible to manually specify to the fixture command which bundle to look in, but now it's not possible anymore
UPDATE 1:
Sorry guys forgot to point the error message: "Could not find any fixture services to load"
The accepted answer helped point me in the right direction to get this working. Though cache could indeed be a problem, having Fixtures in your own bundles does require you to register them.
Using SF 5.1.* I created a services_dev.yaml file and added in:
services:
// other config
Namespace\Registered\In\Composer\For\Fixtures\:
resource: '../vendor/path/registered/in/composer/to/fixtures'
tags: ['doctrine.fixture.orm']
Then indeed, clear cache and it should work.
Added *_dev to the services.yaml file as it's a way for Symfony to only load it in when in your in a dev environment (per APP_ENV Environment variable).
For everyone landing here i solved my problem, what i can tell you is:
Double check you enabled the Bundle in the AppKernel
Clear your symfony cache using the command php bin/console cache:clear --env=dev (or env=prod)
Manually delete cache folder

Can not run in DEV environment

I write you because I have a problem to run my project Symfony 4 DEV environment. Indeed, I have the impression that this one does not turn correctly because:
when I make a modification it is not visible immediately and I usually have to empty the caches to see them
the profiler and the associated "black bar" do not appear and return a 404 (I have the body tags in my base.htm.twig)
he does not see "immediately" the roads that I created
I installed the profiler via the following command composer require profiler --dev and I am in web server (directly on my NDD and my server).
I also have the variable APP_ENV in dev and it shows me well "dev" when I display it directly in a twig via {{app.environment}}
I hope that my explanations are clear enough and that you will be able to help me. thank you in advance
ps: sorry for my English, but I'm on Google Translate ;)
EDIT : I found the solution with the help of someone on Symfony slack ... I did not install the apache-pack bundle which created a .htaccess file in the public folder and manages the rewrites of url ... that's why my roads were not found.
For my defense, I did not see this bundle anywhere in the documentation
The first you have to install symfony/dotenv (dotenv)
In the .env follow this:
APP_ENV=dev
If you have not install symfony/dotenv
composer require symfony/dotenv
You can read about this here https://symfony.com/doc/current/components/dotenv.html
Also you have to follow config/packages/dev/web_profiler.yaml:
web_profiler:
toolbar: true
intercept_redirects: false
framework:
profiler: { only_exceptions: false }
It's not mandatory added APP_ENV=dev to your .env.
In Symfony 4 you can see in public/index.php this
if (!isset($_SERVER['APP_ENV'])) {
if (!class_exists(Dotenv::class)) {
throw new \RuntimeException('APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.');
}
(new Dotenv())->load(__DIR__.'/../.env');
}
$env = $_SERVER['APP_ENV'] ?? 'dev';
So if you APP_ENV is empty also you environment use is dev, but it's better use APP_ENV in .env

Symfony4 Error loading classes custom folder "Expected to find class... but it was not found"

Problem
I'm trying to setup a custom directory structure
for some shared classes in my Symfony project. I
want to create a custom folder in the root of my
project and I want to use the Symfony auto-load
feature to automatically register services from
that folder.
So I added a custom services namespace to the
services.yaml file:
# src ./config/services.yaml
services:
...
TestNamespace\:
resource: '../TestNamespace/*'
...
And I added an empty class in the custom folder:
# src ./TestNamespace/TestClass.php
namespace TestNamespace;
class TestClass
{
}
When I run the app I get the following error:
(1/2) InvalidArgumentException
Expected to find class "TestNamespace\TestClass" in file
"/path/to/ClassLoadErrorDemo/demo/TestNamespace/TestClass.php"
while importing services from resource
"../TestNamespace/*", but it was not found! Check the
namespace prefix used with the resource.
(2/2) FileLoaderLoadException
Expected to find class "TestNamespace\TestClass" in file
"/path/to/ClassLoadErrorDemo/demo/TestNamespace/TestClass.php" while
importing services from resource "../TestNamespace/*", but it was not
found! Check the namespace prefix used with the resource in
/path/to/ClassLoadErrorDemo/demo/config/services.yaml (which is loaded
in resource "/path/to/ClassLoadErrorDemo/demo/config/services.yaml").
I double checked the paths, namespace and the class
name multiple times and everything seems fine and I
don't understand why I still get the error.
Controllers in the ./src folder seem to load fine.
What am I doing wrong here?
Steps to reproduce
I created a demo repo to isolate the problem.
git clone https://github.com/smoelker/SymfonyClassLoadErrorDemo.git
cd SymfonyClassLoadErrorDemo/demo
composer install
mv TestNamespace/TestClass.php_ TestNamespace/TestClass.php
php bin/console server:start
Update your composer.json autoload setup
{
[...]
"autoload": {
"psr-4": {
"TestNamespace\\": "TestNamespace/",
"": "src/"
}
},
[...]
}
After run: composer dump-autoload and try again.
composer dump-autoload --classmap-authoritative will only work if your src directory is present at the time you run the command.
This can be an issue with multi-stage Docker builds in particular, when you are normally only copying the composer.json/composer.lock into the build image.

Installation of a symfony2 bundle (DoctrineCouchDBBundle)

I wish to install the bundle into my symfony project. However, I am coming across a few issues. Please accept my ignorance if the answer is trivial but I've tried searching for a solution but alas, I've found nothing.
In my deps file, I have:
[doctrine-couchdb]
git=http://github.com/doctrine/couchdb-odm.git
[DoctrineCouchDBBundle]
git=http://github.com/doctrine/DoctrineCouchDBBundle.git
target=/bundles/Symfony/Bundle/DoctrineCouchDBBundle
I run the bin/vendors install command
In my autoload.php file I have:
'Doctrine\\ODM\\CouchDB'=> __DIR__.'/../vendor/doctrine-couchdb/lib',
I've registered the bundle:
new Doctrine\Bundle\CouchDBBundle\DoctrineCouchDBBundle()
When I run php app/console I get the error:
Fatal error: Class 'Doctrine\Bundle\CouchDBBundle\DoctrineCouchDBBundle' not found in /var/www/symfony2.test/app/AppKernel.php on line 22
I've noticed that for MongoDB ODM you have:
[doctrine-mongodb]
git=http://github.com/doctrine/mongodb.git
is there not a doctrine-couchdb repo? Have you used this bundle?
I changed target to
target= /bundles/Doctrine/Bundle/CouchDBBundle
so now looks like this
[DoctrineCouchDBBundle]
git=http://github.com/doctrine/DoctrineCouchDBBundle.git
target=/bundles/Doctrine/Bundle/CouchDBBundle
because I noticed that name space for couchdb bundle is
namespace Doctrine\Bundle\CouchDBBundle;
therefore adding
new Doctrine\Bundle\CouchDBBundle\DoctrineCouchDBBundle()
to AppKernel will fail, if installation location does not match namespace/class_name.
Detailed setup and configuration here DoctrineCouchDBBundle Git Hub Issue Log
For those that are new to Symfony 2 bundling architecture, you probably wonder what configuration keys are mandatory and available for bundles. Info can be obtained from:
bundle_dir/bundle_name/.../configuration.php
Update :
1.) Check that you also have installed and autoloaded Doctrine\CouchDB
2.) in your git installation
target=/bundles/Symfony/Bundle/DoctrineCouchDBBundle should probably be
target=/bundles/Doctrine/Bundle/DoctrineCouchDBBundle (notice Symfony => Doctrine)
3.) Then change
'Doctrine' => __DIR__.'/../vendor/doctrine/lib',
to
'Doctrine' => array(__DIR__.'/../vendor/doctrine/lib', __DIR__.'/../vendor/bundles'),
Off the top of my head I'd assume either these things:
1.) Cache
2.) 'Doctrine\\ODM\\CouchDB'=> __DIR__.'/../vendor/doctrine-couchdb/lib',
should be above any higher level namespaces ('Doctrine', 'Doctrine\Common')
so it should look like this:
'Doctrine\\ODM\\CouchDB'=> __DIR__.'/../vendor/doctrine-couchdb/lib',
'Doctrine\\DBAL' => __DIR__.'/../vendor/doctrine-dbal/lib',
'Doctrine' => __DIR__.'/../vendor/doctrine/lib',
3.) some configuration missing in config.yml

Categories