Skip to main content
1 of 3

How to avoid code duplication and optimize code?

I have custom code where I check request params for existing and make query to database with model

public function search(Request $request)
{
    $position = $request->get("position") ?? null;
    $location = $request->get("location") ?? null;
    $employment = $request->get("employment") ?? null;

    $jobsBy = null;
    $jobs = null;
    if($position) {
        $jobs = Job::where('title', 'LIKE', '%'.$position.'%');

        if($location) {
            $locations = [];
            if(is_array($location)) {
                foreach ($location as $name) {
                    $locations[] = $name;
                }
            } else $locations[] = $location;
            $jobs = $jobs->whereMetaIn("location", $locations);
        }

        if($employment) {
            $employments = [];
            if(is_array($employment)) {
                foreach ($employment as $name) {
                    $employments[] = $name;
                }
            } else $employments[] = $employment;
            $jobs = $jobs->withAnyTag($employments);
        }

        if($jobs->get()->count()) $jobsBy = "position";
    }
    if($location && $jobsBy === null) {
        $locations = [];
        if(is_array($location)) {
            foreach ($location as $name) {
                $locations[] = $name;
            }
        } else $locations[] = $location;
        $jobs = Job::whereMetaIn('location', $locations);

        if($employment) {
            $employments = [];
            if(is_array($employment)) {
                foreach ($employment as $name) {
                    $employments[] = $name;
                }
            } else $employments[] = $employment;
            $jobs = $jobs->withAnyTag($employments);
        }

        if($jobs->get()->count()) $jobsBy = "location";
    }
    if($employment && $jobsBy === null) {
        $employments = [];
        if(is_array($employment)) {
            foreach ($employment as $name) {
                $employments[] = $name;
            }
        } else $employments[] = $employment;
        $jobs = Job::withAnyTag($employments);

        if($jobs->get()->count()) $jobsBy = "employment";
    }

    if($jobs == null || !$jobs->get()->count()) {
        $jobs = Job::where("status", '<', 2);
        $jobsBy = "latest";
    }

    if(isset($jobs) && $jobs instanceof \Illuminate\Database\Eloquent\Builder && $jobsBy != null) {
        $IDS = $jobs->where('status', '<', 2)->pluck('id');

        $partnerCompanyJobs = Job::with(['user' => function($user) {
            $user->without('roles', 'companies')
                 ->select('id', 'name');
        }])->withCount('views')->where('type', 0)
                               ->whereIn('id', $IDS)
                               ->where('status', 1)
                               ->orderBy('updated_at', 'DESC')
                               ->get();

        $companyJobs = Job::with(['user' => function($user) {
            $user->without('roles', 'companies')
                 ->select('id', 'name');
        }])->withCount('views')->where('type', 1)
                               ->where('status', 1)
                               ->whereIn('id', $IDS)
                               ->orderBy('updated_at', 'DESC')
                               ->get();

        $sampleJobs = Job::with(['user' => function($user) {
            $user->without('roles', 'companies')
                 ->select('id', 'name');
        }])->withCount('views')->where('type', 2)
                               ->where('status', 1)
                               ->whereIn('id', $IDS)
                               ->orderBy('updated_at', 'DESC')
                               ->get();

        $somonJobs = Job::withCount('views')->whereIn('type', [3,4])
                               ->whereIn('id', $IDS)
                               ->where('status', 1)
                               ->orderBy('updated_at', 'DESC')
                               ->get();

        $jobs = $partnerCompanyJobs->merge($companyJobs)
                               ->merge($sampleJobs)
                               ->merge($somonJobs);

        if(count($jobs)) {
            $page = $request->page ?? 1;
            $items = $jobs->forPage($page, 5);
            return response()->json([          
                'data' => JobResource::collection($items),
                'total' => count($jobs),
                'jobsBy' => $jobsBy
            ]);
        }
    }

    return response()->json([          
        'data' => [],
        'total' => 0,
        'jobsBy' => ""
    ]);
}

How can I avoid duplication of code here and create an optimal database query in my case? I have a problem processing request parameters. Because of this, much is duplicated in my code. How can I fix such a case?