-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add Factories::define() to explicitly override a class #7733
Conversation
1294ee7
to
4716098
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you give an example of how this would affect an existing workflow? For example right now Myth:Auth controller might use:
$user = model('UserModel')->find($userId);
... and a developer would supply app/Models/UserModel.php to override. With this update, would the developer need to add something to boot like:
use App\Models\UserModel;
Factories::define('models', 'UserModel', UserModel::class);
?
system/Config/Factories.php
Outdated
* @param string $name Classname. The first parameter of Factories magic method | ||
* @param string $classname FQCN to load |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can get mixed up very easily. Let's stick to something like "shortname" for the unqualified version.
* @param string $name Classname. The first parameter of Factories magic method | |
* @param string $classname FQCN to load | |
* @param string $name Class shortname. The first parameter of Factories magic method | |
* @param string $classname FQCN to load |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or I see I called it "basename" below. Doesn't matter as long as we are consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I introduced a new term "class alias".
system/Config/Factories.php
Outdated
if ($options['preferApp'] && class_exists($appname) && self::verifyInstanceOf($options, $name)) { | ||
if ( | ||
// preferApp is used only for no namespace class. | ||
strpos($name, '\\') === false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the only breaking change? It seems like the rest of this PR could be rolled out separately without as big an impact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps.
And it is what I want to change. Also it is Paul's opinion. See #7694 (comment)
@MGatner No. But if there is code like |
891be8d
to
1de7e3d
Compare
1de7e3d
to
e0db315
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
Except for Config, if FQCN is specified, preferApp is ignored and that class is loaded.
…instance as `Config\Validation` When you call `Factories::injectMock('config', 'Validation', $config)`, but if the production code calls `config(\Config\Validation::class)`, the mock instance will not be used and fail the test: CodeIgniter\Database\ModelFactoryTest::testBasenameReturnsExistingNamespaceInstance
aa25ccc
to
244c5fb
Compare
preferApp should work only for no namespaced (Config) classname.
Rebased and added commits from a3c768a |
Description
Fixes #7694
Factories::define()
to explicitly override a classpreferApp
works only for no namespaced classnameFactories::$basenames
to$aliases
I would like to deprecate
preferApp
option.Changes
Property structure:
basename is a short classname, or short classname with sub-directories.
alias is a FQCN, short classname, or short classname with sub-directories.
Factories::define()
sets$aliases
.Behavior:
model(\Myth\Auth\Models\UserModel::class)
ormodel('Myth\Auth\Models\UserModel')
App\Models\UserModel
if exists andpreferApp
is trueMyth\Auth\Models\UserModel
if exists andpreferApp
is falseMyth\Auth\Models\UserModel
even ifpreferApp
is trueApp\Models\UserModel
if you defineFactories::define('models', 'Myth\Auth\Models\UserModel', 'App\Models\UserModel')
before the first call of themodel()
Checklist: