|
| 1 | +# Migration guide from Foundry 2.6 to 2.7 |
| 2 | + |
| 3 | +Foundry 2.7 provides a new way to auto-refresh entities, which leverages new [PHP 8.4 lazy objects](https://www.php.net/manual/en/language.oop5.lazy-objects.php)! |
| 4 | + |
| 5 | +This means that the [`Proxy` mechanism](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#object-proxy) |
| 6 | +and all related classes and functions are deprecated. This change was made to fix a lot of quirks involved by the proxy mechanism, |
| 7 | +and to reduce the maintenance burden of this feature. |
| 8 | + |
| 9 | +## How to |
| 10 | + |
| 11 | +> [!IMPORTANT] |
| 12 | +> The new auto-refresh mechanism only applies for PHP 8.4, |
| 13 | +> if you're still not using PHP 8.4, there is nothing to do (yet!) |
| 14 | +
|
| 15 | +First, you need to configure whether you want to use the new auto-refresh mechanism: |
| 16 | + |
| 17 | +```yaml |
| 18 | +zenstruck_foundry: |
| 19 | + # from Foundry 2.7, with PHP >=8.4, not setting this configuration is deprecated |
| 20 | + enable_auto_refresh_with_lazy_objects: true |
| 21 | +``` |
| 22 | +
|
| 23 | +In both cases, you'll need to migrate your factories and code to remove all the `Proxy`-related code: |
| 24 | +- remove all `_real()` calls |
| 25 | +- more generally, replace all proxy methods, by their [function equivalent](https://github.com/zenstruck/foundry/blob/2.x/src/Persistence/functions.php) |
| 26 | +- replace `PersistentProxyObjectFactory` to `PersistentObjectFactory` |
| 27 | +- remove all types and PHPDoc related to proxies |
| 28 | + |
| 29 | +Every modification needed for the migration is covered by a deprecation. |
| 30 | +You'll need to upgrade to the 2.7 version, run the tests, and fix all the deprecations reported. |
| 31 | + |
| 32 | +## Rector rules |
| 33 | + |
| 34 | +This could be a lot of work in big projects, so we provide a [Rector rule set](https://getrector.org/) to help you with this migration. |
| 35 | + |
| 36 | +First, you'll need to install `rector/rector`: |
| 37 | +```shell |
| 38 | +composer require --dev rector/rector |
| 39 | +``` |
| 40 | + |
| 41 | +Then, create a `rector.php` file: |
| 42 | + |
| 43 | +```php |
| 44 | +<?php |
| 45 | +
|
| 46 | +use Rector\Config\RectorConfig; |
| 47 | +use Zenstruck\Foundry\Utils\Rector\FoundrySetList; |
| 48 | +
|
| 49 | +return RectorConfig::configure() |
| 50 | + ->withPaths([ |
| 51 | + // add all paths where your factories are defined and where Foundry is used |
| 52 | + 'src', |
| 53 | + 'tests' |
| 54 | + ]) |
| 55 | + ->withSets([FoundrySetList::REMOVE_PROXIES]) |
| 56 | +; |
| 57 | +``` |
| 58 | + |
| 59 | +And finally, run Rector: |
| 60 | +```shell |
| 61 | +# you can run Rector in "dry run" mode, in order to see which files will be modified |
| 62 | +vendor/bin/rector process --dry-run |
| 63 | +
|
| 64 | +# actually modify files |
| 65 | +vendor/bin/rector process |
| 66 | +``` |
| 67 | + |
| 68 | +> [!IMPORTANT] |
| 69 | +> Rector rules may not totally cover all deprecations (some complex cases may not be handled) |
| 70 | +> You'd still need to run the tests to ensure everything is fixed and no more deprecation are reported. |
| 71 | + |
| 72 | +> [!TIP] |
| 73 | +> You can try to run these rules twice with `--clear-cache` option. Sometimes, the second run will find differences |
| 74 | +> that it could not spot on the first run. |
| 75 | + |
| 76 | +> [!NOTE] |
| 77 | +> Once you've finished the migration to 2.7, it is not necessary to keep the Foundry rule set in your Rector |
| 78 | +> config. |
| 79 | + |
| 80 | +## Deprecations list |
| 81 | + |
| 82 | +Here is the full list of modifications needed: |
| 83 | + |
| 84 | +- Change the base class of your factories from `PersistentProxyObjectFactory` to `PersistentObjectFactory` |
| 85 | +You'll also need to update the PHPDoc `@extends` annotation to use the new class (covered by `ChangeFactoryBaseClassRector`). |
| 86 | +- Remove all `_real()`, `_enableAutoRefresh()` and `_disableAutoRefresh()` calls (covered by `RemoveMethodCallRector`). |
| 87 | +- Remove all `\Zenstruck\Foundry\Persistence\proxy()` and `\Zenstruck\Foundry\Persistence\proxy()` calls (covered by `RemoveFunctionCallRector`). |
| 88 | +- Remove all `_withoutAutoRefresh()` calls (covered by `RemoveWithoutAutorefreshCallRector`). |
| 89 | +- Replace some method calls on `Proxy` class with their function equivalent (covered by `MethodCallToFuncCallWIthObjectAsFirstParameterRector`): |
| 90 | + - `_get()` => `\Zenstruck\Foundry\Persistence\get()` |
| 91 | + - `_set()` => `\Zenstruck\Foundry\Persistence\set()` |
| 92 | + - `_save()` => `\Zenstruck\Foundry\Persistence\save()` |
| 93 | + - `_refresh()` => `\Zenstruck\Foundry\Persistence\refresh()` |
| 94 | + - `_delete()` => `\Zenstruck\Foundry\Persistence\delete()` |
| 95 | + - `_assertPersisted()` => `\Zenstruck\Foundry\Persistence\assert_persisted()` |
| 96 | + - `_assertNotPersisted()` => `\Zenstruck\Foundry\Persistence\assert_not_persisted()` |
| 97 | + |
| 98 | +- Remove `Proxy` type for parameters in the prototype in methods and functions (covered by `ChangeProxyParamTypesRector`). |
| 99 | +- Remove `Proxy` return type in methods and functions (covered by `ChangeProxyReturnTypesRector`). |
| 100 | +- Remove all `Proxy` type hints in PHPDoc (covered by `RemovePhpDocProxyTypeHintRector`). |
| 101 | + |
| 102 | +## Troubleshooting |
| 103 | + |
| 104 | +After enabling the new auto-refresh mechanism and removing all proxy-related code, you may encounter some issues. |
| 105 | +Most of the time, these can be resolved by calling the `\Zenstruck\Foundry\Persistence\refresh()` function on the affected entity, |
| 106 | +which mimics the behavior of the former proxy mechanism. |
0 commit comments