Skip to content

Conversation

nikophil
Copy link
Member

@nikophil nikophil commented May 4, 2025

fixes #890

Here is a fix when using Symfony 7.3 AND PHP 8.4

since symfony/symfony#59890 there was some changes in var-exporter, to support new php proxy system.

and because we're doing weird things, which deals with extra internal stuff with proxy system, things was failing 🤷

I think this is a very short term fix, since it won't be possible to rely on Symfony's ProxyHelper for Foundry's proxyh system. We'd need to find another way to do this

@nikophil nikophil changed the base branch from 2.x to 2.5.x May 4, 2025 14:52
@nikophil nikophil force-pushed the chore/test-sf-73 branch from 36af243 to beaf596 Compare May 4, 2025 14:59
@nikophil nikophil changed the base branch from 2.5.x to 2.x May 4, 2025 14:59
@nikophil nikophil changed the title chore/test sf 73 chore: add symfony 7.3 to the ci matrix May 4, 2025
@nikophil nikophil changed the title chore: add symfony 7.3 to the ci matrix chore: add symfony 7.3 to the CI matrix May 4, 2025
@nikophil nikophil force-pushed the chore/test-sf-73 branch 2 times, most recently from 512581c to 74a577b Compare May 4, 2025 15:06
@nikophil nikophil force-pushed the chore/test-sf-73 branch from 74a577b to d696f42 Compare May 4, 2025 16:41
Comment on lines +117 to 118
'use \Symfony\Component\VarExporter\Internal\LazyDecoratorTrait' => \sprintf("use \\%s;\n use \\%s", IsProxy::class, LazyProxyTrait::class),
'use \Symfony\Component\VarExporter\LazyProxyTrait' => \sprintf("use \\%s;\n use \\%s", IsProxy::class, LazyProxyTrait::class),
Copy link
Member Author

@nikophil nikophil May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

symfony/var-exporter used to generate code like this:

class ZenstruckFoundryTestsFixtureEntityAddressProxy extends \Zenstruck\Foundry\Tests\Fixture\Entity\Address implements \Zenstruck\Foundry\Persistence\Proxy, \Symfony\Component\VarExporter\LazyObjectInterface
{
    use \Symfony\Component\VarExporter\LazyProxyTrait;

and then, we were replacing use \Symfony\Component\VarExporter\LazyProxyTrait by

use \Symfony\Component\VarExporter\LazyProxyTrait;
use IsProxy;

but now, with php 8.4 + sf 7.3 (and only for this "combo"), it generates:

class ZenstruckFoundryTestsFixtureEntityAddressProxy extends \Zenstruck\Foundry\Tests\Fixture\Entity\Address implements \Zenstruck\Foundry\Persistence\Proxy, \Symfony\Component\VarExporter\LazyObjectInterface
{
    use \Symfony\Component\VarExporter\Internal\LazyDecoratorTrait;

so let's replace both occurrences

public function it_can_generate_proxy_for_class_with_self_return_type(): void
{
$proxyfiedObj = ProxyGenerator::wrap($obj = new ClassWithSelfReturnType());
self::assertSame($obj, $proxyfiedObj->returnsSelf()->_real()); // @phpstan-ignore method.notFound
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a change in sf 7.3: now methods which returns self/$this/static can now return a proxy

I think this is kinda nice, but I'm expecting some issues with subtle bugs poping because of this 🤷

@nikophil nikophil force-pushed the chore/test-sf-73 branch from d696f42 to aaa0114 Compare May 4, 2025 16:54
@nikophil nikophil changed the title chore: add symfony 7.3 to the CI matrix fix: enable compatibility with symfony 7.3 and PHP 8.4 May 4, 2025
@nikophil nikophil force-pushed the chore/test-sf-73 branch from aaa0114 to 862cc88 Compare May 4, 2025 17:00
Comment on lines +123 to +141
/**
* Add `$this->_autoRefresh();` after every method declaration.
*
* (\s* # 1. Optional indentation
* (?:public|protected|private)?\s* # 2. Optional visibility
* function\s+ # 3. The "function" keyword followed by space
* (?!__) # 4. Negative lookahead to exclude magic methods (like __serialize)
* \w+ # 5. Method name
* \s*\([^\)]*\)\s* # 6. Parameters inside parentheses (not captured)
* ):?\s*\??[\w\\\\]* # 7. Optional return type, can be nullable (starts with `?`), supports namespaced types (`\Foo\Bar`)
* \s*\{\s*$ # 8. Opening brace `{` at the end of the line, with optional spaces before
*/
$proxyCode = preg_replace_callback(
'/^(\s*(?:public|protected|private)?\s*function\s+(?!__)\w+\s*\([^\)]*\)\s*):?\s*\??[\w\\\\]*\s*\{\s*$/m',
function ($matches) {
return rtrim($matches[0]) . "\n \$this->_autoRefresh();";
},
$proxyCode
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to rework how we introduce the call to _autoRefresh()

symfony/var-exporter used to generate code like this for any method:

    public function getContact(): ?\Zenstruck\Foundry\Tests\Fixture\Entity\Contact
    {
        if (isset($this->lazyObjectReal)) {
            return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getContact(...$this->unproxyArgs(\func_get_args()));
        }

        return parent::getContact(...$this->unproxyArgs(\func_get_args()));
    }

so we were relying on the if() to introduce the call. But now, with php 8.4 + sf 7.3 (again, only for this combo), there is no more if, so I changed how it worked to use a regex which looks for any method declaration

Sorry for the complex regex, but I asked the AI to help me here

@nikophil nikophil requested a review from kbond May 4, 2025 17:04
@nikophil nikophil changed the title fix: enable compatibility with symfony 7.3 and PHP 8.4 fix: enable compatibility with symfony 7.3 + PHP 8.4 May 4, 2025
@nikophil nikophil merged commit 2b31429 into zenstruck:2.x May 5, 2025
68 checks passed
@nikophil nikophil deleted the chore/test-sf-73 branch May 5, 2025 16:06
Kocal added a commit to symfony/ux that referenced this pull request Aug 6, 2025
…yImage][LiveComponent][Map][Notify][React][StimulusBundle][Svelte][Swup][TogglePassword][Toolkit][Translator][Turbo][TwigComponent][Typed][Vue] Add support for Symfony 8 (Kocal)

This PR was merged into the 2.x branch.

Discussion
----------

[Autocomplete][Chartjs][Cropperjs][Dropzone][Icons][LazyImage][LiveComponent][Map][Notify][React][StimulusBundle][Svelte][Swup][TogglePassword][Toolkit][Translator][Turbo][TwigComponent][Typed][Vue] Add support for Symfony 8

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes <!-- please update src/**/CHANGELOG.md files -->
| Docs?         | no <!-- required for new features -->
| Issues        | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT

<!--
Replace this notice by a description of your feature/bugfix.
This will help reviewers and should be a good start for the documentation.

Additionally (see https://symfony.com/releases):
 - Always add tests and ensure they pass.
 - For new features, provide some code snippets to help understand usage.
 - Features and deprecations must be submitted against branch main.
 - Update/add documentation as required (we can help!)
 - Changelog entry should follow https://symfony.com/doc/current/contributing/code/conventions.html#writing-a-changelog-entry
 - Never break backward compatibility (see https://symfony.com/bc).
-->

As suggested in symfony/webpack-encore-bundle#248, I added new jobs for testing explicit Symfony version.

The Symfony 8.0.x-dev job is failing because it needs zenstruck/foundry#891, which is not possible to use because Foundry is not compatible with Symfony 8 yet (opened zenstruck/foundry#960)

There is a lot of changes, but these are only small modifications (composer.json, CHANGELOG.md, and fixing method typings)

I also updated the deprecated packages, that's fine, it makes things easier for us to handle

Commits
-------

998de8d Add support for Symfony 8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Symfony 7.3 error: Proxy contains 13 abstract methods (e.g. Zenstruck\Foundry\Persistence\Proxy::_enableAutoRefresh)
2 participants