0
\$\begingroup\$

Order class - stores data, validates it, saves relations data, returns search data:

<?php

namespace App\Models\Android;

use App\Models\OrderDestination;
use App\Models\OrderSeat;
use App\Models\Origin;
use App\Models\Settings;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Input;

/**
 * @property int $id
 * @property string $label
 * @property integer $blocked
 * @property string $created_at
 * @property string $updated_at
 */
class Order extends \App\Models\Order
{
    protected $table = 'orders';
    protected $fillable = [
        'id',
        'departure_time',
        'origin',
        'passengers_count',
        'baggage_count',
        'conditioner',
        'payment_type',
        'client_id',
        'car_id',
        'driver_id',
        'comment',
        'status',
        'lat',
        'lng'
    ];

    protected static function boot()
    {
        parent::boot(); // TODO: Change the autogenerated stub
        self::creating(function ($model) {
            $model->setAttribute('status', '0');
            $model->setAttribute('client_id', Auth::user()->id);
        });
    }

    public function rules(Request $request)
    {
        if ($request->isMethod('post')) {
            return [
                'id' => 'sometimes|numeric|nullable',
                'departure_time' => ['required', function ($attribute, $value, $fail) {
                    $now = Carbon::now();
                    $datetime = new Carbon($value);
                    $settings = Settings::where('id', 1)->first();
                    if (!$datetime) {
                        return $fail('Неправильная дата');
                    }
                    if ($datetime->diffInHours($now) < $settings->order_time) {
                        $fail('На указанное время нельзя создать заказ');
                    }
                }],
                'passengers_count' => 'required|digits_between:1,10',
                'baggage_count' => 'required|numeric',
                'conditioner' => 'required|boolean',
                'payment_type' => 'required|numeric',
                'status' => 'sometimes|numeric|between:1,13',
                'client_id' => ['sometimes', 'exists:clients,id', function ($attribute, $value, $fail) {
                    if (Auth::guard('api')) {
                        return $fail('Заполните клиента');
                    }
                }], 'origin' => ['required', 'min:3', 'max:64', function ($attribute, $value, $fail) use ($request) {
                    $origin = new Origin();
                    $result = $origin->validate($request);
                    if ($result['status'] == false) {
                        return $fail($result['messages'][0]);
                    }
                }],
                'comment' => ['max:64'],
            ];
        } else {
            return [
                'id' => 'required|nullable',
                'departure_time' => ['required', function ($attribute, $value, $fail) {
                    $now = Carbon::now();
                    $datetime = new Carbon($value);
                    $settings = Settings::where('id', 1)->first();
                    if (!$datetime) {
                        return $fail('Неправильная дата');
                    }
                }],
                'origin' => ['required', 'min:3', 'max:64', function ($attribute, $value, $fail) use ($request) {
                    $origin = new Origin();
                    $result = $origin->validate($request);
                    if ($result['status'] == false) {
                        return $fail($result['messages'][0]);
                    }
                }],
                'passengers_count' => 'required|digits_between:1,10',
                'baggage_count' => 'required|numeric',
                'conditioner' => 'required|boolean',
                'payment_type' => 'required|numeric',
                'status' => 'sometimes|numeric|between:1,13',
                'client_id' => ['sometimes', 'exists:clients,id', function ($attribute, $value, $fail) {
                    if (Auth::guard('api')) {
                        return $fail('Заполните клиента');
                    }
                }],
                'comment' => ['max:64'],
            ];
        }
    }

    public static function search(Request $request)
    {
        $perpage = $request->get('pagination')['perpage'] ?? 10;
        $page = $request->get('pagination')['page'] ?? 1;
        $field = $request->get('sort')['field'] ? $request->get('sort')['field'] : 'id';
        $sort = $request->get('sort')['sort'] ?? 'desc';
        $models = self
            ::when($request->get('orderBy'), function ($models) use ($request) {
                return $models
                    ->orderBy($request->get('orderBy'), $request->get('desc') == 'true' ? 'desc' : 'asc');
            })
            ->with('destinations')
            ->with('car')
            ->with('driver')
            ->with('bid.driver')
            ->select('*')
            ->when(!$request->get('orderBy'), function ($models) use ($request, $field, $sort) {
                return $models
                    ->orderBy($field, $sort);
            });

        if (isset($request->get('query')['generalSearch'])) {
            $globalSearch = $request->get('query')['generalSearch'];
            $models
                ->orWhere('services.label', 'LIKE', "%{$globalSearch}%")
                ->orWhere('services.id', '=', $globalSearch);
        }

        if (Auth::guard('client')->check()) {
            $models->where('orders.client_id', Auth::user()->id);
        }
        if (Auth::guard('driver')->check()) {
            $models->whereNull('orders.driver_id');
        }

        $count = $models->get()->count();
        $models = $models
            ->when($request->get('page') >= 0 && !$request->get('all'), function ($users) use ($request, $perpage, $page) {
                return $users->skip(($page - 1) * $perpage)->take($perpage);
            })
            ->get();
        return response()->json([
            'models' => $models,
            'meta' => [
                'page' => $page,
                'pages' => ceil($count / 10),
                'perpage' => $perpage,
                'total' => $count,
            ]
        ]);
    }

    public static function driverOrders(Request $request)
    {
        $perpage = $request->get('pagination')['perpage'] ?? 10;
        $page = $request->get('pagination')['page'] ?? 1;
        $field = $request->get('sort')['field'] ? $request->get('sort')['field'] : 'id';
        $sort = $request->get('sort')['sort'] ?? 'desc';
        $models = self
            ::when($request->get('orderBy'), function ($models) use ($request) {
                return $models
                    ->orderBy($request->get('orderBy'), $request->get('desc') == 'true' ? 'desc' : 'asc');
            })
            ->with('destinations')
            ->with('car')
            ->with('driver')
            ->with('bid')
            ->with('bid.driver')
            ->select('*')
            ->when(!$request->get('orderBy'), function ($models) use ($request, $field, $sort) {
                return $models
                    ->orderBy($field, $sort);
            });

        if (Auth::guard('driver')) {
            $models
                ->where('orders.driver_id', Auth::user()->id)
                ->orWhere('orders.driver_id', null);
        }

        $count = $models->get()->count();
        $models = $models
            ->when($request->get('page') >= 0 && !$request->get('all'), function ($users) use ($request, $perpage, $page) {
                return $users->skip(($page - 1) * $perpage)->take($perpage);
            })
            ->get();
        return response()->json([
            'models' => $models,
            'meta' => [
                'page' => $page,
                'pages' => ceil($count / 10),
                'perpage' => $perpage,
                'total' => $count,
            ]
        ]);
    }

    public function store(Request $request = null)
    {
        if ($request == null) {
            $validator = Validator::make($this->attributes, $this->rules($request));
            if ($validator->fails()) {
                return response()->json($validator->messages()->all(), 403);
            } else {
                $this->fill($request->all());
                if ($result = $this->save()) {
                    return response()->json($this, 200);
                } else
                    return response()->json($result, 403);
            }
        }
        $validator = Validator::make(Input::all(), $this->rules($request));
        if ($validator->fails()) {
            return response()->json($validator->messages()->all(), 403);
        } else {
            $this->fill($request->all());
            if ($result = $this->save()) {
                $this->saveDestinations($request);
                $this->saveSeats($request);
                return response()->json($this, 200);
            } else
                return response()->json($result, 403);
        }
    }

    public function saveSeats(Request $request)
    {
        if ($this->id) {
            OrderSeat::where('order_id', $this->id)->delete();
        }
        if ($request->get('seat')) {
            $seats = $request->get('seat');
            foreach ($seats as $item) {
                $item = (array)$item;
                $model = new OrderSeat([
                    'order_id' => $this->id,
                    'age' => $item['age'],
                    'weight' => isset($item['weight']) ? $item['weight'] : ''
                ]);
                try {
                    $model->save();
                } catch (\Exception $e) {

                }
            }
        }
    }

    public function saveDestinations(Request $request)
    {
        if ($this->id) {
            OrderDestination::where('order_id', $this->id)->delete();
        }
        if ($request->get('destination')) {
            $destinations = $request->get('destination');
            foreach ($destinations as $item) {
                $item = (array)$item;
                $model = new OrderDestination([
                    'order_id' => $this->id,
                    'address' => $item['value'],
                    'lat' => isset($item['lat']) ? $item['lat'] : '',
                    'lng' => isset($item['lng']) ? $item['lng'] : ''
                ]);
                try {
                    $model->save();
                } catch (\Exception $e) {

                }
            }
        }
    }
}

Controller (typical controller, nothing special):

<?php

namespace App\Http\Controllers\ApiControllers;

use App\Http\Controllers\Controller;
use App\Models\Android\Order as BaseModel;
use Illuminate\Http\Request;

class AndroidOrderController extends Controller
{
    public function index(Request $request)
    {
        return BaseModel::search($request);
    }

    public function get($id)
    {
        $model = BaseModel::find($id);
        $model->seats;
        $model->destinations;
        return response()->json($model);
    }

    public function driverOrders(Request $request)
    {
        return BaseModel::driverOrders($request);
    }

    public function store(Request $request)
    {
        return (new BaseModel())->store($request);
    }

    public function update(Request $request)
    {
        $model = BaseModel::find($request->get('id'));
        if (!$model) {
            return response()->json([
                'error' => 'Не найден такой заказ'
            ], 403);
        }
        $model->status = $request->get('status');
        if ($model->save()) {
            return $model;
        } else {
            return response()->json([
                'error' => 'Не удалось обновить'
            ], 403);
        }
    }
}

How can I improve the code? Make it more readable, extensible.

\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review! Please add some mor context to your question. \$\endgroup\$ – Heslacher Dec 10 '19 at 8:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.