Skip to content

feat(IAppConfig): Add rector to migrate IConfig calls to IAppConfig#78

Merged
nickvergessen merged 1 commit intomainfrom
feat/noid/iappconfig
Apr 27, 2026
Merged

feat(IAppConfig): Add rector to migrate IConfig calls to IAppConfig#78
nickvergessen merged 1 commit intomainfrom
feat/noid/iappconfig

Conversation

@nickvergessen
Copy link
Copy Markdown
Contributor

@nickvergessen nickvergessen commented Apr 25, 2026

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

Description

Added a rector to replace all IConfig::App() calls with their respective IAppConfig counterpart

Motivation and context

Cleaner code

How has this been tested?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

PR checklist

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING.md document.
  • I have added tests to cover my changes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Joas Schilling <coding@schilljs.com>
@nickvergessen nickvergessen self-assigned this Apr 25, 2026
@nickvergessen nickvergessen added the enhancement New feature or request label Apr 25, 2026
@nickvergessen nickvergessen requested review from CarlSchwan, ChristophWurst and come-nc and removed request for CarlSchwan April 25, 2026 17:11
@nickvergessen nickvergessen merged commit 94f0bc2 into main Apr 27, 2026
22 checks passed
@nickvergessen nickvergessen deleted the feat/noid/iappconfig branch April 27, 2026 14:01
Copy link
Copy Markdown
Collaborator

@come-nc come-nc left a comment

Choose a reason for hiding this comment

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

  • How does that behave when IAppConfig is already injected in the class?
  • Does it removes IConfig injection if it is unused afterwards? Or do we have another rector that removes unused injected services?
  • I have a preference for the scoped IAppConfig but I suppose this is way harder to automate with rector.

Comment on lines +191 to +192
foreach ($propertyNames as $propertyName) {
if ($this->isName($propertyFetch->name, $propertyName)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

isNames should be used instead, like above?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right, not sure how I missed that

Comment on lines +225 to +243
private function makeUniquePropertyName(ClassMethod $constructor, string $desired): string
{
$taken = [];
foreach ($constructor->getParams() as $param) {
$name = $this->getName($param->var);
if (is_string($name)) {
$taken[$name] = true;
}
}
if (!isset($taken[$desired])) {
return $desired;
}
$i = 2;
while (isset($taken[$desired . $i])) {
$i++;
}

return $desired . $i;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks like it will inject the same class a second time rather than re-using the same property.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

well only when referencing another class, in case that was not clear to you.
When its already there it's used. I added new tests in #81 to show that

@provokateurin
Copy link
Copy Markdown
Contributor

Does it removes IConfig injection if it is unused afterwards? Or do we have another rector that removes unused injected services?

And what happens if IConfig is also used for reading system values and not just app values?

@CarlSchwan
Copy link
Copy Markdown
Contributor

Does it removes IConfig injection if it is unused afterwards? Or do we have another rector that removes unused injected services?

And what happens if IConfig is also used for reading system values and not just app values?

According to the getRuleDefinition, the IConfig is not removed only IAppConfig is added. There is a bit of risk that we get some straight unused IConfig after running rector, but I think that's still better than the status quo of having so many deprecated IConfig usage

@nickvergessen
Copy link
Copy Markdown
Contributor Author

Does it removes IConfig injection if it is unused afterwards?

No, because it could be used with other direct methods that are not replacable or with IUserConfig which is not rectored yet.

There is a bit of risk that we get some straight unused IConfig after running rector, but I think that's still better than the status quo of having so many deprecated IConfig usage

That was basically exactly my thought.

Looks like it will inject the same class a second time rather than re-using the same property.

I also did not use the IAppConfig from AppFramework which I personally prefer as it is limited to your own app and avoids mistakes. But that would be more breaking and I don't think rector rules should have a risk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants