oscer-io /
oscer
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Oscer\Cms\Backend\Resources\Fields; |
||
| 4 | |||
| 5 | use Closure; |
||
| 6 | use Illuminate\Database\Eloquent\Model; |
||
| 7 | use Illuminate\Http\Request; |
||
| 8 | use JsonSerializable; |
||
| 9 | |||
| 10 | abstract class Field implements JsonSerializable |
||
| 11 | { |
||
| 12 | public string $name; |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 13 | |||
| 14 | public string $label; |
||
| 15 | |||
| 16 | public bool $active = true; |
||
| 17 | |||
| 18 | public array $dependency = []; |
||
| 19 | |||
| 20 | public string $component; |
||
| 21 | |||
| 22 | public $value; |
||
| 23 | |||
| 24 | public array $rules = []; |
||
| 25 | |||
| 26 | protected array $rulesForCreate = []; |
||
| 27 | |||
| 28 | protected array $rulesForUpdate = []; |
||
| 29 | |||
| 30 | public Model $model; |
||
| 31 | |||
| 32 | protected array $with = []; |
||
| 33 | |||
| 34 | protected Closure $resolveValueCallback; |
||
| 35 | |||
| 36 | protected Closure $fillResourceCallback; |
||
| 37 | |||
| 38 | protected bool $showOnIndex = true; |
||
| 39 | |||
| 40 | public $card = false; |
||
| 41 | |||
| 42 | public function __construct( |
||
| 43 | string $name, |
||
| 44 | ?string $label = null, |
||
| 45 | ?Closure $resolveValueCallback = null, |
||
| 46 | ?Closure $fillResourceCallback = null |
||
| 47 | ) { |
||
| 48 | $this->name = $name; |
||
| 49 | $this->label = $label ?: ucfirst($name); |
||
| 50 | $this->resolveValueCallback = $resolveValueCallback ?: function (self $field) { |
||
| 51 | $property = $this->name; |
||
| 52 | |||
| 53 | return $field->model->$property; |
||
| 54 | }; |
||
| 55 | |||
| 56 | $this->fillResourceCallback = $fillResourceCallback ?: function (Model $model, Request $request) { |
||
| 57 | $property = $this->name; |
||
| 58 | $value = $request->input($property); |
||
| 59 | $model->$property = $value; |
||
| 60 | }; |
||
| 61 | } |
||
| 62 | |||
| 63 | /** |
||
| 64 | * Returns a new field which is chainable. |
||
| 65 | */ |
||
| 66 | public static function make(...$arguments) |
||
| 67 | { |
||
| 68 | return new static(...$arguments); |
||
| 69 | } |
||
| 70 | |||
| 71 | /** |
||
| 72 | * This method is called when a form will be instantiated. It sets |
||
| 73 | * the resource on the field as well as the info if it is a |
||
| 74 | * create or update form. |
||
| 75 | */ |
||
| 76 | public function resolve(Model $model) |
||
| 77 | { |
||
| 78 | $this->model = $model; |
||
| 79 | |||
| 80 | $this->value = $this->resolveValue(); |
||
| 81 | |||
| 82 | return $this->value; |
||
| 83 | } |
||
| 84 | |||
| 85 | /** |
||
| 86 | * This method resolves the fields value depending on the "resolveValueCallback". |
||
| 87 | */ |
||
| 88 | protected function resolveValue() |
||
| 89 | { |
||
| 90 | return call_user_func($this->resolveValueCallback, $this); |
||
| 91 | } |
||
| 92 | |||
| 93 | /** |
||
| 94 | * This method fills the resource with the updated value from the Form. |
||
| 95 | */ |
||
| 96 | public function fill(Model $model, Request $request) |
||
| 97 | { |
||
| 98 | call_user_func($this->fillResourceCallback, $model, $request); |
||
| 99 | } |
||
| 100 | |||
| 101 | /** |
||
| 102 | * Define the validation rules. |
||
| 103 | */ |
||
| 104 | public function rules(array $rules) |
||
| 105 | { |
||
| 106 | $this->rules = $rules; |
||
| 107 | |||
| 108 | return $this; |
||
| 109 | } |
||
| 110 | |||
| 111 | public function rulesForCreate(array $rules) |
||
| 112 | { |
||
| 113 | $this->rulesForCreate = $rules; |
||
| 114 | |||
| 115 | return $this; |
||
| 116 | } |
||
| 117 | |||
| 118 | public function rulesForUpdate(array $rules) |
||
| 119 | { |
||
| 120 | $this->rulesForUpdate = $rules; |
||
| 121 | |||
| 122 | return $this; |
||
| 123 | } |
||
| 124 | |||
| 125 | public function getCreationRules(): array |
||
| 126 | { |
||
| 127 | return array_merge($this->rules, $this->rulesForCreate); |
||
| 128 | } |
||
| 129 | |||
| 130 | public function getUpdateRules(): array |
||
| 131 | { |
||
| 132 | return array_merge($this->rules, $this->rulesForUpdate); |
||
| 133 | } |
||
| 134 | |||
| 135 | public function hideOnIndex() |
||
| 136 | { |
||
| 137 | $this->showOnIndex = false; |
||
| 138 | |||
| 139 | return $this; |
||
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * We use this to check if a field should be removed from the submit process |
||
| 144 | * based on the request. If a field has a "filled" rule and is not |
||
| 145 | * present In the request we determine is must be removed. |
||
| 146 | * Moreover if the current field has a dependency but is |
||
| 147 | * not present (not activated in the view), we |
||
| 148 | * determine is must be removed as well. |
||
| 149 | */ |
||
| 150 | public function shouldBeRemoved(Request $request) |
||
| 151 | { |
||
| 152 | if ($request->input($this->name) === null) { |
||
| 153 | if ($this->hasDependency() && ($dependency = $request->input($this->dependency['field']))) { |
||
| 154 | //check whether this field is active & therefore must be validated or should be skipped |
||
| 155 | return ! $this->isDependencyMatched($dependency); |
||
| 156 | } |
||
| 157 | |||
| 158 | if (in_array('filled', $this->rules) |
||
| 159 | && $request->input($this->name) === null) { |
||
| 160 | return true; |
||
| 161 | } |
||
| 162 | } |
||
| 163 | |||
| 164 | return false; |
||
| 165 | } |
||
| 166 | |||
| 167 | /** |
||
| 168 | * Check whether the current field has a dependency. |
||
| 169 | */ |
||
| 170 | public function hasDependency() |
||
| 171 | { |
||
| 172 | return ! empty($this->dependency); |
||
| 173 | } |
||
| 174 | |||
| 175 | /** |
||
| 176 | * Check whether the given $value matches the value that has been set in the dependency. |
||
| 177 | */ |
||
| 178 | protected function isDependencyMatched(string $value) |
||
| 179 | { |
||
| 180 | $dependency = $this->dependency['value'] ?? null; |
||
| 181 | |||
| 182 | return $value === $dependency; |
||
| 183 | } |
||
| 184 | |||
| 185 | /** |
||
| 186 | * Set the fields initial active state to false. This is useful when using field dependencies. |
||
| 187 | */ |
||
| 188 | public function disable() |
||
| 189 | { |
||
| 190 | $this->active = false; |
||
| 191 | |||
| 192 | return $this; |
||
| 193 | } |
||
| 194 | |||
| 195 | /** |
||
| 196 | * Set a dependency to another field. Whenever the dependency field value changes |
||
| 197 | * it will be checked against $value. If both match this field will be |
||
| 198 | * shown, else it will be hidden. $value can be omitted, this |
||
| 199 | * fields name will be used instead. |
||
| 200 | */ |
||
| 201 | public function dependsOn(string $field, ?string $value = null) |
||
| 202 | { |
||
| 203 | $this->dependency = [ |
||
| 204 | 'field' => $field, |
||
| 205 | 'value' => $value ?? $this->name, |
||
| 206 | ]; |
||
| 207 | |||
| 208 | return $this; |
||
| 209 | } |
||
| 210 | |||
| 211 | public function jsonSerialize() |
||
| 212 | { |
||
| 213 | $data = [ |
||
| 214 | 'component' => $this->component, |
||
| 215 | 'card' => $this->card, |
||
| 216 | 'name' => $this->name, |
||
| 217 | 'label' => $this->label, |
||
| 218 | 'value' => $this->resolveValue(), |
||
| 219 | 'showOnIndex' => $this->showOnIndex, |
||
| 220 | 'active' => $this->active, |
||
| 221 | 'dependency' => $this->dependency, |
||
| 222 | ]; |
||
| 223 | |||
| 224 | collect($this->with)->each(function (string $property) use (&$data) { |
||
| 225 | $data[$property] = $this->$property; |
||
| 226 | }); |
||
| 227 | |||
| 228 | return $data; |
||
| 229 | } |
||
| 230 | } |
||
| 231 |