| Conditions | 35 |
| Paths | 1 |
| Total Lines | 237 |
| Code Lines | 70 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php namespace App\Modules\V1\Core\AbstractRepositories; |
||
| 203 | public function save(array $data) |
||
| 204 | { |
||
| 205 | $model = false; |
||
| 206 | $modelClass = $this->model; |
||
| 207 | $relations = []; |
||
| 208 | |||
| 209 | \DB::transaction(function () use (&$model, &$relations, $data, $modelClass) { |
||
| 210 | /** |
||
| 211 | * If the id is present in the data then select the model for updating, |
||
| 212 | * else create new model. |
||
| 213 | * @var array |
||
| 214 | */ |
||
| 215 | $model = array_key_exists('id', $data) ? $modelClass->lockForUpdate()->find($data['id']) : new $modelClass; |
||
| 216 | if ( ! $model) |
||
| 217 | { |
||
| 218 | \ErrorHandler::notFound(class_basename($modelClass) . ' with id : ' . $data['id']); |
||
| 219 | } |
||
| 220 | |||
| 221 | /** |
||
| 222 | * Construct the model object with the given data, |
||
| 223 | * and if there is a relation add it to relations array, |
||
| 224 | * then save the model. |
||
| 225 | */ |
||
| 226 | foreach ($data as $key => $value) |
||
| 227 | { |
||
| 228 | /** |
||
| 229 | * If the attribute is a relation. |
||
| 230 | */ |
||
| 231 | $relation = camel_case($key); |
||
| 232 | if (method_exists($model, $relation) && \Core::$relation()) |
||
| 233 | { |
||
| 234 | /** |
||
| 235 | * Check if the relation is a collection. |
||
| 236 | */ |
||
| 237 | if (class_basename($model->$relation) == 'Collection') |
||
| 238 | { |
||
| 239 | /** |
||
| 240 | * If the relation has no value then marke the relation data |
||
| 241 | * related to the model to be deleted. |
||
| 242 | */ |
||
| 243 | if ( ! $value || ! count($value)) |
||
| 244 | { |
||
| 245 | $relations[$relation] = 'delete'; |
||
| 246 | } |
||
| 247 | } |
||
| 248 | if (is_array($value)) |
||
| 249 | { |
||
| 250 | /** |
||
| 251 | * Loop through the relation data. |
||
| 252 | */ |
||
| 253 | foreach ($value as $attr => $val) |
||
| 254 | { |
||
| 255 | /** |
||
| 256 | * Get the relation model. |
||
| 257 | */ |
||
| 258 | $relationBaseModel = \Core::$relation()->model; |
||
| 259 | |||
| 260 | /** |
||
| 261 | * Check if the relation is a collection. |
||
| 262 | */ |
||
| 263 | if (class_basename($model->$relation) == 'Collection') |
||
| 264 | { |
||
| 265 | /** |
||
| 266 | * If the id is present in the data then select the relation model for updating, |
||
| 267 | * else create new model. |
||
| 268 | */ |
||
| 269 | $relationModel = array_key_exists('id', $val) ? $relationBaseModel->lockForUpdate()->find($val['id']) : new $relationBaseModel; |
||
| 270 | |||
| 271 | /** |
||
| 272 | * If model doesn't exists. |
||
| 273 | */ |
||
| 274 | if ( ! $relationModel) |
||
| 275 | { |
||
| 276 | \ErrorHandler::notFound(class_basename($relationBaseModel) . ' with id : ' . $val['id']); |
||
| 277 | } |
||
| 278 | |||
| 279 | /** |
||
| 280 | * Loop through the relation attributes. |
||
| 281 | */ |
||
| 282 | foreach ($val as $attr => $val) |
||
| 283 | { |
||
| 284 | /** |
||
| 285 | * Prevent the sub relations or attributes not in the fillable. |
||
| 286 | */ |
||
| 287 | if (gettype($val) !== 'object' && gettype($val) !== 'array' && array_search($attr, $relationModel->getFillable(), true) !== false) |
||
| 288 | { |
||
| 289 | $relationModel->$attr = $val; |
||
| 290 | } |
||
| 291 | } |
||
| 292 | |||
| 293 | $relations[$relation][] = $relationModel; |
||
| 294 | } |
||
| 295 | /** |
||
| 296 | * If not collection. |
||
| 297 | */ |
||
| 298 | else |
||
| 299 | { |
||
| 300 | /** |
||
| 301 | * Prevent the sub relations. |
||
| 302 | */ |
||
| 303 | if (gettype($val) !== 'object' && gettype($val) !== 'array') |
||
| 304 | { |
||
| 305 | |||
| 306 | /** |
||
| 307 | * If the id is present in the data then select the relation model for updating, |
||
| 308 | * else create new model. |
||
| 309 | */ |
||
| 310 | $relationModel = array_key_exists('id', $value) ? $relationBaseModel->lockForUpdate()->find($value['id']) : new $relationBaseModel; |
||
| 311 | |||
| 312 | /** |
||
| 313 | * If model doesn't exists. |
||
| 314 | */ |
||
| 315 | if ( ! $relationModel) |
||
| 316 | { |
||
| 317 | \ErrorHandler::notFound(class_basename($relationBaseModel) . ' with id : ' . $value['id']); |
||
| 318 | } |
||
| 319 | |||
| 320 | foreach ($value as $relationAttribute => $relationValue) |
||
| 321 | { |
||
| 322 | /** |
||
| 323 | * Prevent attributes not in the fillable. |
||
| 324 | */ |
||
| 325 | if (array_search($relationAttribute, $relationModel->getFillable(), true) !== false) |
||
| 326 | { |
||
| 327 | $relationModel->$relationAttribute = $relationValue; |
||
| 328 | } |
||
| 329 | } |
||
| 330 | |||
| 331 | $relations[$relation] = $relationModel; |
||
| 332 | } |
||
| 333 | } |
||
| 334 | } |
||
| 335 | } |
||
| 336 | } |
||
| 337 | /** |
||
| 338 | * If the attribute isn't a relation and prevent attributes not in the fillable. |
||
| 339 | */ |
||
| 340 | else if (array_search($key, $model->getFillable(), true) !== false) |
||
| 341 | { |
||
| 342 | $model->$key = $value; |
||
| 343 | } |
||
| 344 | } |
||
| 345 | /** |
||
| 346 | * Save the model. |
||
| 347 | */ |
||
| 348 | $model->save(); |
||
| 349 | |||
| 350 | /** |
||
| 351 | * Loop through the relations array. |
||
| 352 | */ |
||
| 353 | foreach ($relations as $key => $value) |
||
| 354 | { |
||
| 355 | /** |
||
| 356 | * If the relation is marked for delete then delete it. |
||
| 357 | */ |
||
| 358 | if ($value == 'delete' && $model->$key()->count()) |
||
| 359 | { |
||
| 360 | $model->$key()->delete(); |
||
| 361 | } |
||
| 362 | /** |
||
| 363 | * If the relation is an array. |
||
| 364 | */ |
||
| 365 | else if (gettype($value) == 'array') |
||
| 366 | { |
||
| 367 | $ids = []; |
||
| 368 | /** |
||
| 369 | * Loop through the relations. |
||
| 370 | */ |
||
| 371 | foreach ($value as $val) |
||
| 372 | { |
||
| 373 | switch (class_basename($model->$key())) |
||
| 374 | { |
||
| 375 | /** |
||
| 376 | * If the relation is one to many then update it's foreign key with |
||
| 377 | * the model id and save it then add its id to ids array to delete all |
||
| 378 | * relations who's id isn't in the ids array. |
||
| 379 | */ |
||
| 380 | case 'HasMany': |
||
| 381 | $foreignKeyName = $model->$key()->getForeignKeyName(); |
||
| 382 | $val->$foreignKeyName = $model->id; |
||
| 383 | $val->save(); |
||
| 384 | $ids[] = $val->id; |
||
| 385 | break; |
||
| 386 | |||
| 387 | /** |
||
| 388 | * If the relation is many to many then add it's id to the ids array to |
||
| 389 | * attache these ids to the model. |
||
| 390 | */ |
||
| 391 | case 'BelongsToMany': |
||
| 392 | $val->save(); |
||
| 393 | $ids[] = $val->id; |
||
| 394 | break; |
||
| 395 | } |
||
| 396 | } |
||
| 397 | switch (class_basename($model->$key())) |
||
| 398 | { |
||
| 399 | /** |
||
| 400 | * If the relation is one to many then delete all |
||
| 401 | * relations who's id isn't in the ids array. |
||
| 402 | */ |
||
| 403 | case 'HasMany': |
||
| 404 | $model->$key()->whereNotIn('id', $ids)->delete(); |
||
| 405 | break; |
||
| 406 | |||
| 407 | /** |
||
| 408 | * If the relation is many to many then |
||
| 409 | * detach the previous data and attach |
||
| 410 | * the ids array to the model. |
||
| 411 | */ |
||
| 412 | case 'BelongsToMany': |
||
| 413 | $model->$key()->detach(); |
||
| 414 | $model->$key()->attach($ids); |
||
| 415 | break; |
||
| 416 | } |
||
| 417 | } |
||
| 418 | /** |
||
| 419 | * If the relation isn't array. |
||
| 420 | */ |
||
| 421 | else |
||
| 422 | { |
||
| 423 | switch (class_basename($model->$key())) |
||
| 424 | { |
||
| 425 | /** |
||
| 426 | * If the relation is one to many or one to one. |
||
| 427 | */ |
||
| 428 | case 'HasOne': |
||
| 429 | $foreignKeyName = $model->$key()->getForeignKeyName(); |
||
| 430 | $value->$foreignKeyName = $model->id; |
||
| 431 | $value->save(); |
||
| 432 | break; |
||
| 433 | } |
||
| 434 | } |
||
| 435 | } |
||
| 436 | }); |
||
| 437 | |||
| 438 | return $model->id; |
||
| 439 | } |
||
| 440 | |||
| 702 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.