Skip to content
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

Added a check for configured field name conflict with inherited methods #9549

Open
wants to merge 2 commits into
base: 4
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/ORM/DataObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use SilverStripe\Core\Resettable;
use SilverStripe\Dev\Debug;
use SilverStripe\Dev\Deprecation;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FormField;
use SilverStripe\Forms\FormScaffolder;
Expand Down Expand Up @@ -3451,6 +3452,17 @@ public function requireTable()
);
}

// Sanity check for fields that conflict with parent
foreach (array_keys($fields) as $fieldName) {
if (method_exists(get_parent_class($this), $fieldName) && !($this instanceof TestOnly)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we use singleton(get_parent_class($this))->hasMethod($fieldName)) so that we can check for methods added by extensions?

this does also pose the question of how we handle extensions that are added after the model has been defined. eg: adding an extension as a feature request on top of a pre-existing site

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤔 True that. And maybe reduce the interrupt to a warning (similar to DBSchemaManager::requireTable()?) and add something like a $ignore_conflicting_fields = [] config to give users the ability to suppress the warning?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dhensby any thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

The fact that there's a need to block this on test classes is a bit of a code smell: why is that needed and why would it never be needed in a non-test case?

Copy link
Member

Choose a reason for hiding this comment

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

Also what about the "get$fieldName" method?

Copy link
Member

Choose a reason for hiding this comment

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

Should there be similar checks for relations?

Copy link
Member

Choose a reason for hiding this comment

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

+1 for reducing the error to a warning. With that in place I think we can avoid the need for a suppression filter.

This does also pose the question of how we handle extensions that are added after the model has been defined.

You're going to have a conflicting situation. Right now the system blindly lets you build a corrupt, inconsistent app. Warning that you're doing this but leaving behaviour otherwise unchanged seems fine. In such a case a developer would be advised to refactor their site to avoid conflicts, which would be the best way to get rid of the warning message. Otherwise they can suppress warnings application-wide if they're that much of a cowboy ;)

throw new LogicException(sprintf(
'\'%s\' has a $db field named "%s" that coincides with an inherited method of the same name.',
static::class,
$fieldName
));
}
}

if ($fields) {
$hasAutoIncPK = get_parent_class($this) === self::class;
DB::require_table(
Expand Down