ModelRuleHelper
class ModelRuleHelper
Share how the model rules read models, including the model a call on a model, builder or relation queries.
Unlike upstream, the queried model comes from the named Builder or Relation template, so custom builders with other type parameters, and non-generic builders whose ancestor fixes the model, resolve too.
Constants
| private QUERY_METHODS |
The model methods that build its queries. |
Methods
Create a new model rule helper instance.
Return the type the method is called on, with a class-string receiver as its object type.
Get the exact classes a static call runs on, or null when a subclass could be called instead.
Return the model a builder, relation or model queries.
Determine whether a concrete model builds its queries as the base Model does: through Model's query methods and the base builder, without any global scope.
Determine whether the model runs Model's own implementation of each method, which a subclass or trait may override.
Determine whether reading the property runs a get accessor or a class cast, which can compute it from other attributes, as HasAttributes::transformModelValue() and mutateAttributeForArray() read it.
Get the default a class declares for one of its own properties, from its source.
Determine whether a parent class or interface declares the method, whose name and visibility the model keeps.
Determine whether a model method is a legacy scope: Model::hasNamedScope() finds it by its name, and its first parameter takes the builder, unlike a helper whose name only starts with "scope", such as scopeExistsIn().
Return the name of the attributed scope that can replace a legacy scope method.
Track the files a model's property defaults and method bodies come from, for a rule checking the model's class.
Details
at line 75
__construct(ReflectionProvider $reflectionProvider, BuilderHelper $builderHelper, ModelPropertyHelper $modelPropertyHelper, ModelCastHelper $modelCastHelper)
Create a new model rule helper instance.
at line 86
Type
callerType(MethodCall|StaticCall $node, Scope $scope)
Return the type the method is called on, with a class-string receiver as its object type.
at line 100
array|null
exactCalledClasses(StaticCall $call, Scope $scope)
Get the exact classes a static call runs on, or null when a subclass could be called instead.
at line 144
Type|null
queriedModel(ClassReflection $callerClass, Type $callerType)
Return the model a builder, relation or model queries.
at line 162
bool
buildsPlainQueries(ClassReflection $modelClass)
Determine whether a concrete model builds its queries as the base Model does: through Model's query methods and the base builder, without any global scope.
Global scopes may add any clause, and boot code can register them, so a model with boot or initialize hooks below Model (found as bootTraits() finds them), #[ScopedBy], a scope in the booted registry or a boot listener is not plain.
at line 226
bool
usesModelMethods(ClassReflection $modelClass, array $methods)
Determine whether the model runs Model's own implementation of each method, which a subclass or trait may override.
at line 238
bool
isComputedProperty(ClassReflection $modelClass, string $name)
Determine whether reading the property runs a get accessor or a class cast, which can compute it from other attributes, as HasAttributes::transformModelValue() and mutateAttributeForArray() read it.
at line 267
Expr|null
declaredPropertyDefault(ClassLike $class, string $name)
Get the default a class declares for one of its own properties, from its source.
Reflection reparses defaults without their positions, and one declaration can hold several properties.
at line 281
bool
declaresInheritedMethod(ClassReflection $modelClass, string $methodName)
Determine whether a parent class or interface declares the method, whose name and visibility the model keeps.
at line 296
bool
isLegacyScopeMethod(ExtendedMethodReflection $method)
Determine whether a model method is a legacy scope: Model::hasNamedScope() finds it by its name, and its first parameter takes the builder, unlike a helper whose name only starts with "scope", such as scopeExistsIn().
at line 311
string|null
attributedScopeName(ClassReflection $modelClass, ExtendedMethodReflection $method)
Return the name of the attributed scope that can replace a legacy scope method.
A model method already using that name keeps the legacy scope, which is then the only way to keep the scope's name, as DatabaseNotification's scopeRead() sits beside read().
at line 329
void
trackModelSources(ClassReflection $modelClass, Scope $scope)
Track the files a model's property defaults and method bodies come from, for a rule checking the model's class.
They are not declarations, whose changes alone reanalyze the model's file.