Improves exception handling for invalid model resolver

A more specific error message is now shown when trying to resolve a model from an invalid source (eg: an array)
Fixes #2354
This commit is contained in:
Samuel Georges 2016-09-18 13:44:13 +10:00
parent cc2973e148
commit 9b5851fbd5
4 changed files with 37 additions and 14 deletions

View File

@ -6,6 +6,7 @@ return [
],
'field' => [
'invalid_type' => 'Invalid field type used :type.',
'options_method_invalid_model' => "The attribute ':field' does not resolve to a valid model. Try specifying the options method for model class :model explicitly.",
'options_method_not_exists' => "The model class :model must define a method :method() returning options for the ':field' form field."
],
'widget' => [

View File

@ -2,6 +2,7 @@
use Lang;
use ApplicationException;
use Exception;
/**
* Form Model Widget Trait
@ -24,7 +25,15 @@ trait FormModelWidget
*/
public function resolveModelAttribute($attribute)
{
return $this->formField->resolveModelAttribute($this->model, $attribute);
try {
return $this->formField->resolveModelAttribute($this->model, $attribute);
}
catch (Exception $ex) {
throw new ApplicationException(Lang::get('backend::lang.model.missing_relation', [
'class' => get_class($this->model),
'relation' => $attribute
]));
}
}
/**

View File

@ -333,10 +333,11 @@ class Filter extends WidgetBase
$methodName = $options;
if (!$model->methodExists($methodName)) {
throw new ApplicationException(Lang::get(
'backend::lang.filter.options_method_not_exists',
['model'=>get_class($model), 'method'=>$methodName, 'filter'=>$scope->scopeName]
));
throw new ApplicationException(Lang::get('backend::lang.filter.options_method_not_exists', [
'model' => get_class($model),
'method' => $methodName,
'filter' => $scope->scopeName
]));
}
$options = $model->$methodName();

View File

@ -11,6 +11,7 @@ use Backend\Classes\FormWidgetBase;
use October\Rain\Database\Model;
use October\Rain\Html\Helper as HtmlHelper;
use ApplicationException;
use Exception;
/**
* Form Widget
@ -1027,17 +1028,27 @@ class Form extends WidgetBase
* Refer to the model method or any of its behaviors
*/
if (!is_array($fieldOptions) && !$fieldOptions) {
list($model, $attribute) = $field->resolveModelAttribute($this->model, $field->fieldName);
try {
list($model, $attribute) = $field->resolveModelAttribute($this->model, $field->fieldName);
}
catch (Exception $ex) {
throw new ApplicationException(Lang::get('backend::lang.field.options_method_invalid_model', [
'model' => get_class($this->model),
'field' => $field->fieldName
]));
}
$methodName = 'get'.studly_case($attribute).'Options';
if (
!$this->objectMethodExists($model, $methodName) &&
!$this->objectMethodExists($model, 'getDropdownOptions')
) {
throw new ApplicationException(Lang::get(
'backend::lang.field.options_method_not_exists',
['model'=>get_class($model), 'method'=>$methodName, 'field'=>$field->fieldName]
));
throw new ApplicationException(Lang::get('backend::lang.field.options_method_not_exists', [
'model' => get_class($model),
'method' => $methodName,
'field' => $field->fieldName
]));
}
if ($this->objectMethodExists($model, $methodName)) {
@ -1052,10 +1063,11 @@ class Form extends WidgetBase
*/
elseif (is_string($fieldOptions)) {
if (!$this->objectMethodExists($this->model, $fieldOptions)) {
throw new ApplicationException(Lang::get(
'backend::lang.field.options_method_not_exists',
['model'=>get_class($this->model), 'method'=>$fieldOptions, 'field'=>$field->fieldName]
));
throw new ApplicationException(Lang::get('backend::lang.field.options_method_not_exists', [
'model' => get_class($this->model),
'method' => $fieldOptions,
'field' => $field->fieldName
]));
}
$fieldOptions = $this->model->$fieldOptions($field->value, $field->fieldName);