The Symfony PHP framework
MIT License
27476
1149
8831

Symfony version(s) affected

6.1.4

Description

Ok I appreciate this is a piss-poor bug report but it's all I have at the moment. Im logging it here in case others see the same thing, and if those with better Symfony skills have a 💡 moment and know exactly what the problem is.

How to reproduce

Using PHP 8.2RC ... (I know I know)

When deployed, on the very very first page load (so probably when compiling and caching the container) Im getting one of a few exceptions thrown (and caught into Sentry.io)

On the second page load, and on every single page load after the first page load the whole app is exception free and working fine, including the lines in the code that raise this initial exception - it all works perfectly in PHP 8.2 - once that first page load/cache/container compile is complete.

It also did not raise any exceptions using PHP 7/8/8.1 - this part of my codebase is untouched throughout the PHP cycles. With the exception of adding readonly to the constructor property I guess.

Their exception messages are truncated and incomplete - but are the full message.

"Cannot instantiate interface from"

and sometimes

"Error: Cannot instantiate trait from"

https://sentry.io/share/issue/de89a5060617453f9e660714e5cb5b9e/

Error: Cannot instantiate interface from
#6 /src/MyJoomla/Controller/UpdatesController.php(615): MyJoomla\Controller\UpdatesController::doExtensionUpgrade
#5 /vendor/symfony/http-kernel/HttpKernel.php(153): Symfony\Component\HttpKernel\HttpKernel::handleRaw
#4 /vendor/symfony/http-kernel/HttpKernel.php(75): Symfony\Component\HttpKernel\HttpKernel::handle
#3 /vendor/symfony/http-kernel/Kernel.php(202): Symfony\Component\HttpKernel\Kernel::handle
#2 /vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php(35): Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner::run
#1 /vendor/autoload_runtime.php(29): require_once
#0 /public/index.php(15): null

Now, when inspecting my own code, I see that Im instantiating a Message and then dispatching it in the bus.

Screenshot 2022-09-21 at 16 29 29

My message class is simple:

<?php
namespace App\Message;

class RemoteLogMessage extends AbstractAsyncMessage
{
}

which extends the abstract class

<?php
namespace App\Message;

abstract class AbstractAsyncMessage
{
    public function __construct(
        private readonly array $data = []
    ) {
    }

    public function getData(): array
    {
        return $this->data;
    }
}

Possible Solution

No idea what the root cause or solution is.

One guess is that an abstract class must need one or more abstract methods? or not? its valid without else it would not work?

This error cannot be replicated on demand - but it has happened the last few times I have deployed to production - within seconds. (Production is a docker container in a docker swarm service)

Additional Context

Please no lectures on running PHP 8.2 RC2 in production ... someone has to find the bugs in the real world right :) hehe.

First :)
Screenshot 2022-09-21 at 16 37 14

Hello,

There are some missing translation for Norwegian Nynorsk (nn). These should be added in branch 4.4.
See #38710 for details and this page for an example.

These are the files that should be updated:

NOTE: If you want to work on this issue, add a comment to assign it to yourself and let others know that this is already taken.

Symfony version(s) affected

6.1.4, 6.2

Description

In some cases method resolveCommands of Dotenv.php may try to create an instance of Process with a string as first argument, but constructor of Process requires an array.

I didn't run into any error messages, only noticed it after VS Code reported this problem. Might worth to take a deeper look?

How to reproduce

Because I didn't run into any problems, I have no example code. Based on the code from https://github.com/symfony/symfony/blob/6.1/src/Symfony/Component/Dotenv/Dotenv.php#L436 it could be triggered with commands in an ENV file, but I am not sure. I never use such functionality.

In my opinion its a clear case, because argument types don't match and PHP will throw an exception, most likely.

Possible Solution

No response

Additional Context

No response

Symfony version(s) affected

6.1.5 (version of symfony/http-foundation)

Description

this was the sintax we used to use.

Note $headers

public function showPdf($id)
{
    $headers = [
        'Content-Type: application/pdf',
    ];

  ... cutted ..

    return response()->file($pathToFile,$headers);
}

This will not work anymore since 6.1.5 of this package

Now this works , but we must fix EVERY SINGLE LARAVEL PROJECT

    $headers = [
        'Content-Type' => 'application/pdf',
    ];

How to reproduce

I am able to reproduce only in a laravel project

Possible Solution

I ask for a revert

Additional Context

No response

Description

I would use Mutation Testing to see if all tests cover all eventualities. This also helps us to increase the code quality of Symfony.

What are your thoughts on this topic?

Example

No response

Symfony version(s) affected

6.1

Description

I have fresh project set up in symfony. For the few first hours everything was workings, then suddenly my commands in terminal in test environment started hanging(ONLY IN TEST ENVIRONMENT), in 30 minutes I got any response. For example I have used commands like:
`bin/console --env test' etc.. and 'phpunit' every one in test env hangs. I don't know the reason why, like I said this issue has happened unexpectedly. I hadn't install any new bundle that could affect on this

I am sorry If I submitted this issue in a bad place, this is my first time here. I couldn't also find any connected problem to main.

There are my configurations:

php: 8.1.8

.env.test
KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=disabled

composer.json

{
    "type": "project",
    "license": "proprietary",
    "minimum-stability": "stable",
    "prefer-stable": true,
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "api-platform/core": "^3.0",
        "doctrine/annotations": "^1.0",
        "doctrine/doctrine-bundle": "^2.7",
        "doctrine/doctrine-migrations-bundle": "^3.2",
        "doctrine/orm": "^2.13",
        "easycorp/easyadmin-bundle": "^4.3",
        "gedmo/doctrine-extensions": "^3.8",
        "gesdinet/jwt-refresh-token-bundle": "^1.1",
        "lexik/jwt-authentication-bundle": "^2.16",
        "nelmio/cors-bundle": "^2.2",
        "phpdocumentor/reflection-docblock": "^5.3",
        "phpstan/phpdoc-parser": "^1.8",
        "ramsey/uuid": "^4.5",
        "sensio/framework-extra-bundle": "^6.2",
        "symfony/asset": "6.1.*",
        "symfony/console": "6.1.*",
        "symfony/dotenv": "6.1.*",
        "symfony/expression-language": "6.1.*",
        "symfony/flex": "^2",
        "symfony/framework-bundle": "6.1.*",
        "symfony/mailer": "6.1.*",
        "symfony/property-access": "6.1.*",
        "symfony/property-info": "6.1.*",
        "symfony/proxy-manager-bridge": "6.1.*",
        "symfony/runtime": "6.1.*",
        "symfony/security-bundle": "6.1.*",
        "symfony/serializer": "6.1.*",
        "symfony/twig-bundle": "6.1.*",
        "symfony/validator": "6.1.*",
        "symfony/yaml": "6.1.*",
        "symfonycasts/verify-email-bundle": "^1.11"
    },
    "config": {
        "allow-plugins": {
            "composer/package-versions-deprecated": true,
            "symfony/flex": true,
            "symfony/runtime": true
        },
        "optimize-autoloader": true,
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "replace": {
        "symfony/polyfill-ctype": "*",
        "symfony/polyfill-iconv": "*",
        "symfony/polyfill-php72": "*",
        "symfony/polyfill-php73": "*",
        "symfony/polyfill-php74": "*",
        "symfony/polyfill-php80": "*",
        "symfony/polyfill-php81": "*"
    },
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    },
    "conflict": {
        "symfony/symfony": "*"
    },
    "extra": {
        "symfony": {
            "allow-contrib": false,
            "require": "6.1.*"
        }
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4",
        "hautelook/alice-bundle": "^2.11",
        "phpunit/phpunit": "^9.5",
        "symfony/browser-kit": "6.1.*",
        "symfony/css-selector": "6.1.*",
        "symfony/http-client": "6.1.*",
        "symfony/maker-bundle": "^1.45",
        "symfony/phpunit-bridge": "^6.1",
        "symfony/stopwatch": "6.1.*",
        "symfony/web-profiler-bundle": "6.1.*"
    }
}

phpunit:

<?xml version="1.0" encoding="UTF-8"?>

<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
         backupGlobals="false"
         colors="true"
         bootstrap="tests/bootstrap.php"
         convertDeprecationsToExceptions="false"
>
    <php>
        <ini name="display_errors" value="1" />
        <ini name="error_reporting" value="-1" />
        <server name="APP_ENV" value="test" force="true" />
        <server name="SHELL_VERBOSITY" value="-1" />
        <server name="SYMFONY_PHPUNIT_REMOVE" value="" />
        <server name="SYMFONY_PHPUNIT_VERSION" value="9.5" />
    </php>

    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>

    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">src</directory>
        </include>
    </coverage>

    <listeners>
        <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
    </listeners>

    <!-- Run `composer require symfony/panther` before enabling this extension -->
    <!--
    <extensions>
        <extension class="Symfony\Component\Panther\ServerExtension" />
    </extensions>
    -->
</phpunit>

How to reproduce

I don't know, this happen unexpectedly like I said

Possible Solution

No response

Additional Context

No response

Symfony version(s) affected

5.4

Description

When a class have a property annotated with class-string<> or string&class-string<> serializer throws an exception:

Uncaught Symfony\Component\Serializer\Exception\NotNormalizableValueException: The type of the "..." attribute for class "..." must be one of "class-string<...>" ("string" given).

How to reproduce

<?php
require_once __DIR__.'/vendor/autoload.php';

use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;

interface SomeInterface {
    public function get(): void;
}
class SomeClass implements SomeInterface {
    public function get(): void {}
}
class FooBar {
    /**
     * @var class-string<SomeInterface>
     */
    private $foo;

    /**
     * @param class-string<SomeInterface> $foo
     */
    public function __construct(string $foo) {
        $this->foo = $foo;
    }

    /**
     * @return class-string<SomeInterface>
     */
    public function getFoo(): string
    {
        return $this->foo;
    }
}

$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$serializer = new Serializer([
    new DateTimeNormalizer(),
    new ArrayDenormalizer(),
    new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor()),
], [new JsonEncoder()]);

$serializer->deserialize('{"foo": "'.SomeClass::class.'"}', FooBar::class, 'json', [AbstractObjectNormalizer::SKIP_NULL_VALUES => true]);

Possible Solution

No response

Additional Context

No response

Discussed in #44329

Originally posted by php4fan November 28, 2021

Symfony version(s) affected

5.4.0

Description

Say you have an application deployed to https://somedomain.com/my/path, as opposed to just https://somedomain.com/.
I think you usually call that an application that "lives under a subdirectory" (or directory, or folder).

I expect EVERYTHING in the framework to work out of the box with ZERO configuration in that scenario. Generally, Symfony does know how to handle that.

Out-of-the-box login authentication however seems to be one of those things that do not work as expected in the under-a-directory scenario.

I think that's due to the AbstractLoginFormAuthenticator::supports() method whose current implementation is:

    return $request->isMethod('POST') && $this->getLoginUrl($request) === $request->getPathInfo();

In this scenario, $this->getLoginUrl($request) returns /my/path/login, while $request->getPathInfo() returns just /login when the url being requested is /my/path/info.

How to reproduce

Deploy a Symfony application under a directory.
Make a LoginFormAuthenticator with make:auth
Try to log in.

Possible Solution

No response

Additional Context

No response

Symfony version(s) affected

6.1.*

Description

When using der MailJet Mailer component using the MailJet API in conjunction with template variables, the MailJet component only allows for a max depth of two (2), thus we're getting the following error while trying to send emails:

JsonException
in vendor/symfony/mailjet-mailer/Transport/MailjetApiTransport.php (line 204)

199    private function castCustomHeader(string $value, string $type)
200   {
201        return match ($type) {
202            'bool' => filter_var($value, \FILTER_VALIDATE_BOOLEAN),
203            'int' => (int) $value,
204            'json' => json_decode($value, true, 2, \JSON_THROW_ON_ERROR), <--
205            'string' => $value,
206       };
207    }
208 }

When using the MailJet PHP API (https://github.com/mailjet/mailjet-apiv3-php) there's no limitation to the depth of the variable template payload.

How to reproduce

  1. Create a free MailJet account for using the MailJet API
  2. Create a new Symfony app
  3. Require both symfony/mailer and symfony/mailjet-mailer using composer
  4. Configure the MAILER_DSN to use the MailJet API transport as described in the documentation https://symfony.com/doc/current/mailer.html#using-a-3rd-party-transport
  5. Try to send an email that uses MailJet templates and add a multi-dimensional array for template variables

Example:

$templateId = 1337;

$templateVars = [
    'foo' => [
        'bar' => 'baz',
    ],
];

$email = (new Symfony\Component\Mime\Email())
    ->from('foo@localhost')
    ->to('bar@localhost')
    ->subject('Test email');
    
$email->text('Ignored, because using MailJet templates');

$email
    ->getHeaders()
    ->addTextHeader('X-MJ-TemplateLanguage', 'true')
    ->addTextHeader('X-MJ-TemplateID', $templateId)
    ->addTextHeader('X-MJ-Vars', \json_encode($templateVars));
    
$this->mailer->send($email);

Possible Solution

Remove the limitation that allows for only a max depth of 2 levels here: https://github.com/symfony/mailjet-mailer/blob/6.1/Transport/MailjetApiTransport.php#L204

Additional Context

No response

Symfony version(s) affected

6.1.4

Description

UUIDs and ULIDs have identical methods for converting to string and each method returns the same format for both UUIDs and ULIDs, however, when typecast as a string, UUIDs return RFC4122 and ULIDs return Base 32. Not sure whether this should be considered a bug or a feature request, however, regardless believe they should return the same format (probably RFC4122).

How to reproduce

use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;

$uid = $context['filters']['uid'];
$uuid = Uuid::fromString($uid);
$ulid = Ulid::fromString($uid);

printf('%-20s %s'.PHP_EOL.PHP_EOL, 'Provided', $uid);

printf('%-20s %-50s %s'.PHP_EOL, 'Format', 'UUID', 'ULID');
printf('%-20s %-50s %s'.PHP_EOL, 'toBinary()', bin2hex($uuid->toBinary()), bin2hex($ulid->toBinary()));
printf('%-20s %-50s %s'.PHP_EOL, 'toBase32()', $uuid->toBase32(), $ulid->toBase32());
printf('%-20s %-50s %s'.PHP_EOL, 'toBase58()', $uuid->toBase58(), $ulid->toBase58());
printf('%-20s %-50s %s'.PHP_EOL, 'toRfc4122()', $uuid->toRfc4122(), $ulid->toRfc4122());
printf('%-20s %-50s %s'.PHP_EOL, '(string)', (string) $uuid, (string) $ulid);
Provided             01GE2EV7Y39WWQ6HEPCHGHCDHX

Format               UUID                                               ULID
toBinary()           018384ed9fc34f397345d6646116363d                   018384ed9fc34f397345d6646116363d
toBase32()           01GE2EV7Y39WWQ6HEPCHGHCDHX                         01GE2EV7Y39WWQ6HEPCHGHCDHX
toBase58()           1Bqp73W7R7b34PWenSQnSx                             1Bqp73W7R7b34PWenSQnSx
toRfc4122()          018384ed-9fc3-4f39-7345-d6646116363d               018384ed-9fc3-4f39-7345-d6646116363d
(string)             018384ed-9fc3-4f39-7345-d6646116363d               01GE2EV7Y39WWQ6HEPCHGHCDHX

Possible Solution

No response

Additional Context

No response

Symfony version(s) affected

5.4

Description

SQS has a limit of 262,144 bytes (256 KB) message size.

When there is an error during message handling, the ErrorDetailsStamp adds a stacktrace that can lead to a message bigger than this limit.

How to reproduce

  • Dispatch messages with SQS with a redelivery policy that makes it retry a few times
  • Throw an exception with a super big stack trace
  • See it fails

Possible Solution

Not sure, maybe an option to remove stack trace from ErrorDetailsStamp

Additional Context

No response

Description

I need to configure json encoding options (in my case JSON_PRESERVE_ZERO_FRACTION). but the configuration for the serializer section does not allow to set options.

It would be nice to allow to configure options for the encoder and decoder in the configuration.

Example

it would be nice if i could do something like this:

serializer:
    encoder: 
        options: JSON_PRESERVE_ZERO_FRACTION
    decoder: 
        options: JSON_THROW_ON_ERROR

my workaround is this compiler pass:

/**
 * Symfony serializer does not offer to configure options.
 */
class FloatSerializerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        $serializer = $container->getDefinition('serializer.encoder.json');
        $encode = new Definition(JsonEncode::class);
        $encode->setArgument(0, [JsonEncode::OPTIONS => \JSON_PRESERVE_ZERO_FRACTION]);
        $container->setDefinition('zero-encoder', $encode);
        $serializer->setArgument('$encodingImpl', new Reference('zero-encoder'));
    }
}

Symfony version(s) affected

5,6, possibly others

Description

Currently, if a form field does not have an equivalent setter or adder and does not use the ['mapped' => false] option, we get a NoSuchPropertyException that complains about a lack of setters or adders when submitting the form.

(This is Symfony\Component\PropertyAccess\PropertyAccessor::getReadAccessInfo(), in the method's final else branch.)

That's fine, I guess, but it can be a little bit confusing. Would it be safe for me to open a pull request adding a reference to ['mapped' => false] as a possible fix in the text of the exception? Or is this method used in non-form contexts?

How to reproduce

Create a form field in a form type that doesn't have a setter or adder associated with it in the equivalent Doctrine entity, and don't pass any options to the field. Then submit the form. You should get a nice NoSuchPropertyException talking about the missing methods, but it won't mention anything about how to solve the issue if you don't want to add those methods.

Possible Solution

I'm thinking about opening a pull request to change this part of Symfony\Component\PropertyAccess\PropertyAccessor::getReadAccessInfo() ...

$access[self::ACCESS_NAME] = sprintf(
    'Neither the property "%s" nor one of the methods "%s()" '.
-    'exist and have public access in class "%s".',
+    'exist and have public access in class "%s".' Consider adding one of those methods, or if you don't want a direct mapping, use ['mapped' => false] as a form field option.', 
    $property,
    implode('()", "', $methods),
    $reflClass->name
);

... but I first need to know that it's safe for me to do so without accidentally adding misleading instructions about form options to contexts that don't involve forms.

Please comment!

Additional Context

No response

Symfony version(s) affected

5.4

Description

I have this code:
https://github.com/abelardolg/ipglobal

When I run it in local, this message is showed:
image

I don't understand why it is showed when my controller (BlogListController) is placed under the rigth directory.

A clue: when I click here:
image
PHPStorm shows this class

How to reproduce

Please, git clone my above repo and follow the steps indicated in the README.md file.

Possible Solution

No response

Additional Context

Screenshots are included inside the explanation section along with the text to give you more context about this issue.

Description

This is the main issue to list and track all the efforts planned or done to modernize Symfony code to the lowest php version required (currently 8.1 on 6.2) using automated tools.

The scope is to upgrade the current code base. Not to introduce an automated way to check or upgrade new code through CI, this could be discussed in another issue.

This is also a way to start a discussion on whether symfony should use this modern code or not and make new conventions around those.

Each modernization suggested must be focused on a single type of change (e.g. switch case to match expression) and have their related PRs. ⚠️ Please motivate your modernization in the PR, let's not overwhelm maintainers with bogus changes, there has to be a positive net value to your modifications.

Discussion whether a listed modernization is relevant and should be considered are meant to be held in the PR. This is because it's mostly an automated process, so closing a PR because the modernization is eventually deemed irrelevant is OK. No significant amount of effort will be wasted because the relevance wasn't discussed in an issue before. However having actual code to argue about can contribute to a more thoughtful decision.

I'm planning to tackle all of them at some point but if you would like to help, feel free to ping me here with the modernization you would like to be in charge of or new ones you find appropriate.

Rector

Symfony version(s) affected

5.4.0, 6.0.0

How to reproduce

I have MessengerHandler which makes http requests (with only one parallel consumer):

messenger.yaml:

transports:
  test:
    dsn: '%env(MESSENGER_TRANSPORT_DSN)%/test'
    options:
      delete_after_ack: true
      consumer: '%env(MESSENGER_CONSUMER_NAME)%'
    retry_strategy:
      max_retries: 0

routing:
     'TestMessage': test

TestMessageHandler.php:

<?php
class TestMessageHandler implements MessageHandlerInterface, BatchHandlerInterface
{
    use BatchHandlerTrait;

    public function __construct(
        private HttpClientInterface $client
    ) { }

    public function __invoke(TestMessage $message, Acknowledger &$ack = null)
    {        
        return $this->handle($message, $ack);
    }
    
    private function shouldFlush(): bool
    {
        return 5 <= \count($this->jobs);
    }

    private function process(array $jobs): void
    {
        $responses = [];
        
        foreach ($jobs as [$job, $ack]) {          
            try {
                [$headers, $content] = prepareRequest();
                
                $responses[] = $this->client->request('POST', $job->getEndpoint(), [
                    'headers' => $headers,
                    'body' => $content
                ]);

                $ack->ack($job);
            } catch (\Exception $e) {
                $ack->nack($e);
            }
        }
        
        if(0 === count($responses)) {
          return;
        }

        foreach ($this->client->stream($responses) as $response => $chunk) {
            if ($chunk->isFirst()) {
                var_dump($response->getStatusCode());
            } else if ($chunk->isLast()) {
            }
        }
    }
}

cli:

MESSENGER_CONSUMER_NAME=test php bin/console messenger:consume test

Code works okay, but when i hit ctrl+c before script finished and start it again, it throws me an error:

In Connection.php line 441:

  Could not acknowledge redis message "1638374074049-0".

I noticed that after consumer crashes or i hit ctrl+c, same message comes to __invoke a few times. When removing BatchHandlerInterface it starts to work as excepected without any issue.

Possible Solution 1 (a bad one)

  1. Add uuid to every Message
  2. Destroy Acknowledger and create replacement for it (HandleMessageMiddleware.php:88)

Test.php:

class Test
{
  public function isAcknowledged()
  {
    return false;
  }
}

TestMessageHandler.php:

public function __invoke(SendPushMessage $message, Acknowledger &$ack = null)
{
    $uid = $message->getUuid();
    
    if(isset($this->jobs[$uid])) {
      $this->flush(true);
      
      try {
        $ack = null;
        unset($ack);
      } catch(\Exception) { }
      
      $ack = new Test();

      return 0;
    }
    
    return $this->handle($message, $ack);
}

private function handle(object $message, ?Acknowledger $ack)
{
    $uid = $message->getUuid();

    if (null === $ack) {
        $ack = new Acknowledger(get_debug_type($this));
        $this->jobs[$uid] = [$message, $ack];
        $this->flush(true);

        return $ack->getResult();
    }

    $this->jobs[$uid] = [$message, $ack];
    if (!$this->shouldFlush()) {
        return \count($this->jobs);
    }

    $this->flush(true);

    return 0;
}

Possible Solution 2

Comment __destruct in Symfony\Component\Messenger\Handler\Acknowledger.php

Handler.php:

public function __invoke(SendPushMessage $message, Acknowledger $ack = null)
{
    $uid = $message->getUuid();
    
    if(isset($this->jobs[$uid])) {
      $this->flush(true);
    
      return 0;
    }
    
    return $this->handle($message, $ack);
}

private function handle(object $message, ?Acknowledger $ack)
{
    $uid = $message->getUuid();

    if (null === $ack) {
        $ack = new Acknowledger(get_debug_type($this));
        $this->jobs[$uid] = [$message, $ack];
        $this->flush(true);

        return $ack->getResult();
    }

    $this->jobs[$uid] = [$message, $ack];
    if (!$this->shouldFlush()) {
        return \count($this->jobs);
    }

    $this->flush(true);

    return 0;
}

Additional Context

No response

Symfony version(s) affected

6.1.2 - 6.13

Description

The Q&A sums it up perfectly: #46117

I noticed it as I was trying to set the below, but noticed it wasn't being honored by the serializer or it's friends:

framework:
    serializer:
        default_context:
            skip_null_values: true

Problem:

I have been learning Symfony 6 and I got stuck on a weird behaviour of the Serializer component.

Default instance of Serializer service seems to be ignoring default context set in config file. I am not sure if this is a bug in the framework or rather my misunderstanding how the component and the framework work, but the situation can be easily reproduced in a fresh project.

How to reproduce

Steps to reproduce:

Environment: PHP 8.1.4, Symfony CLI 5.4.7, Symfony 6.0.7.

  1. Create a fresh project by executing symfony local:new --webapp demo.
  2. Generate a skeleton console command by executing bin/console make:command app:demo.
  3. Open the generated config/packages/framework.yaml and configure Serializer to pretty-print JSON:
framework:
    # ...
    serializer:
        default_context:
            json_encode_options: 128  # value of JSON_PRETTY_PRINT
  1. Open the generated App\Command\DemoCommand class and request dependency on Serializer in constructor:
public function __construct(
    private \Symfony\Component\Serializer\SerializerInterface $serializer,
) {
    parent::__construct();
}
  1. Modify command's execute method to demonstrate the bug:
protected function execute(InputInterface $input, OutputInterface $output): int
{
    $io = new SymfonyStyle($input, $output);

    $data = [
        'foo' => 'bar',
        'baz' => ['a' => 'b'],
    ];
    $context = [
        // exactly what was configured in default context
        'json_encode_options' => JSON_PRETTY_PRINT,
    ];
    $io->info($this->serializer->serialize($data, 'json')); // this should use default context
    $io->info($this->serializer->serialize($data, 'json', $context)); // this uses manually configured context

    return Command::SUCCESS;
}
  1. Execute the command to see the bug:
$ bin/console -vvv app:wat 

                                                                                                                        
 [INFO] {"foo":"bar","baz":{"a":"b"}}                                                                                   
                                                                                                                        

                                                                                                                        
 [INFO] {                                                                                                               
            "foo": "bar",                                                                                               
            "baz": {                                                                                                    
                "a": "b"                                                                                                
            }                                                                                                           
        }                                                                                                               

If my understanding of Symfony's documentation is correct, both calls to serialize should return the same output. Is this really a bug or did I misunderstood something?

Possible Solution

No response

Additional Context

No response

Description

RFC 8631 - Link Relation Types for Web Services introduces service-doc, service-desc, service-meta, status rel types, which could be added as constants to the Link class.

Example

service-desc, for instance, is useful for providing a link to the OpenAPI documentation of a web service.

Symfony version(s) affected

5.3.99

Description

The translation commands scan the same files multiple times. In a large project with multiple locales this process takes more than 30 minutes to complete

How to reproduce

I created a reproducer that simply consists of a controller action that has the Translator component autowired
https://github.com/E-M-P-I-R-E/bug-symfony-container-reproducer

Both of the two translation commands are affected

bin/console translation:update en --force
bin/console debug:translation en

When adding a dump() statement on line 142 in vendor\symfony\translation\Extractor\PhpExtractor.php I see that the controller is parsed twice

filename: "ContainerTestController.php"
...
filename: "ContainerTestController.php"

Possible Solution

It appears that (since translator is injected) the controller is being selected to be parsed by this class that populates the commands' constructor $codePaths argument: vendor\symfony\translation\DependencyInjection\TranslatorPathsPass.php

The commands also add the src directory to the $codePaths to be parsed. There was some discussion in #40229 about whether that should be hardcoded. This seems to be the reason it's scanned twice. I don't understand the need for scanning the entire src directory when the TranslatorPathsPass already selects all classes that include TranslatorInterface

Perhaps @yceruto or @natewiebe13 have some insight about this behavior

Additional Context

As a work around to skip parsing source files entirely and only scan templates it is possible to provide a path to the bundle argument ex.

bin/console translation:update en /path/to/project --force

Symfony version(s) affected: 5.3.2

Description
a combination of json_login_ldap and json_login will not work when the new authentication manager is enabled. They both
on their own work properly but not in combination. When new authentication manager is disabled they work properly together
in a chain.

How to reproduce
see attached repository with 4 different configuration cases to reproduce:
https://github.com/oliverreese/symfony-security-ldap-login

Possible Solution

Additional context