design pattern for multiple search criteria

781 Views Asked by At

I have this function that searches for jobs based on the search criteria provided. There are five different search criteria that can be met when searching for a job. For example: the search can just contain the name of a company alone or the name of the company, job title, industry etc. So they are multiple different combinations of those five things that can be searched for. My issue is that i don't want to manually code the different combinations for the search. Is there a programming pattern methodology I can use to achieve this. This is the code I currently have

  $app->post('/search', function () use ($app) {

// reading post params
$company = $app->request()->post('company');
$jobTitle = $app->request()->post('jobTitle');
$parish = $app->request()->post('parish');
$industry = $app->request()->post('industry');
$type = $app->request()->post('type');
$response = array();
$argsArray = array();
$result = '';

if ($company != NULL) {
    $argsArray['company'] = $company;
}

if ($jobTitle != NULL) {
    $argsArray['jobTitle'] = $jobTitle;
}
if ($parish != NULL) {
    $argsArray['parish'] = $parish;
}
if ($industry != NULL) {
    $argsArray['industry'] = $industry;
}
if ($type != NULL) {
    $argsArray['type'] = $type;
}

$db = new DbHandler();

if (count($argsArray) == 0) {
    $result = $db->search();
}
else if (count($argsArray) == 1) {
    if (array_key_exists('company', $argsArray)) {
        $result = $db->search($company);
    }
    else if (array_key_exists('jobTitle', $argsArray)) {
        $result = $db->search($jobTitle);
    }
    else if (array_key_exists('parish', $argsArray)) {
        $result = $db->search($parish);
    }
    else if (array_key_exists('industry', $argsArray)) {
        $result = $db->search($industry);
    }
    else if (array_key_exists('type', $argsArray)) {
        $result = $db->search($type);
    }


} else if (count($argsArray) == 2) {
    if (array_key_exists('company', $argsArray) && array_key_exists('jobTitle', $argsArray)) {
        $result = $db->search($company, $jobTitle);
    }
    else if (array_key_exists('parish', $argsArray) && array_key_exists('jobTitle', $argsArray)) {
        $result = $db->search($jobTitle, $parish);
    }
    else if (array_key_exists('company', $argsArray) && array_key_exists('parish', $argsArray)) {
        $result = $db->search($parish, $company);
    }
    else if (array_key_exists('company', $argsArray) && array_key_exists('industry', $argsArray)) {
        $result = $db->search($industry, $company);
    }
    else if (array_key_exists('company', $argsArray) && array_key_exists('type', $argsArray)) {
        $result = $db->search($type, $company);
    }
    else if (array_key_exists('industry', $argsArray) && array_key_exists('type', $argsArray)) {
        $result = $db->search($industry, $type);
    }
    else if (array_key_exists('jobTitle', $argsArray) && array_key_exists('industry', $argsArray)) {
        $result = $db->search($jobTitle, $industry);
    }
    else if (array_key_exists('parish', $argsArray) && array_key_exists('type', $argsArray)) {
        $result = $db->search($parish, $type);
    }
    else if (array_key_exists('industry', $argsArray) && array_key_exists('parish', $argsArray)) {
        $result = $db->search($industry, $parish);
    }
    else if (array_key_exists('type', $argsArray) && array_key_exists('jobTitle', $argsArray)) {
        $result = $db->search($type, $jobTitle);
    }
} else if (count($argsArray) == 3) {

} else if (count($argsArray) == 4) {

} else if (count($argsArray) == 5) {
    $result = $db->search($type, $jobTitle, $parish, $industry, $company);
}

As you see if I were to do this for the five different combinations it would be cumbersome and not very efficient. How I can I tackle such as issue.

2

There are 2 best solutions below

0
On BEST ANSWER

This is how i solved the problem using variable length parameter lists.

public function search(...$args)
{
    //only searches for jobs that are open
    $status = "open";
    $wild_card = "%";
    //Loops through the array of search variables
    foreach ($args as $a) {

        //checks if no search criteria was set if not it searches for all available jobs
        if (count($a) == 0) {
            return $this->noCriteria($status);
        } //searches when one search criteria was set
        else if (count($a) == 1) {
            return $this->oneCriteria($status, $wild_card, $a);
        } // searches jobs with two criteria set
        else if (count($a) == 2) {
            return $this->twoCriteria($status, $wild_card, $a);

        } // searches jobs with THREE criteria set
        else if (count($a) == 3) {

            return $this->threeCriteria($status, $wild_card, $a);

        } // searches jobs with four criteria set
        else if (count($a) == 4) {

            return $this->fourCriteria($status, $wild_card, $a);

        } // searches jobs with five criteria set
        else if (count($a) == 5) {

            return $this->allCriteria($status, $wild_card, $a);

        }
    }
    return NULL;
} 
5
On

You can try a decorator pattern,if the order doesn't matter, i.e. the search is only logical "and" with the others. With pattern its a bit cleaner but it depends on the data.