-
-
Save redati/49afe9ec47d89aa7864b4cf7a6b7801f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Models\Concerns; | |
| trait SearchBuilder | |
| { | |
| public function scopeSearchBuilder($query) | |
| { | |
| if (request()->filled('searchBuilder') && request()->query('searchBuilder') !== 'false') { | |
| $query->where(function ($query) { | |
| $this->searchBuilderCondition($query, request()->query('searchBuilder')); | |
| }); | |
| } | |
| } | |
| protected function searchBuilderCondition($query, $data) | |
| { | |
| $first = true; | |
| if (!isset($data['criteria'])) { | |
| return; | |
| } | |
| // Iterate over every group or criteria in the current group | |
| foreach ($data['criteria'] as $crit) { | |
| // If criteria is defined then this must be a group | |
| if (isset($crit['criteria'])) { | |
| // Check if this is the first, or if it is and logic | |
| if ($data['logic'] === 'AND' || $first) { | |
| // Call the function for the next group | |
| $query->where(function ($q) use ($crit) { | |
| $this->searchBuilderCondition($q, $crit); | |
| }); | |
| // Set first to false so that in future only the logic is checked | |
| $first = false; | |
| } else { | |
| $query->orWhere(function ($q) use ($crit) { | |
| $this->searchBuilderCondition($q, $crit); | |
| }); | |
| } | |
| } else if (isset($crit['condition']) && (isset($crit['value1']) || $crit['condition'] === 'null' || $crit['condition'] === '!null')) { | |
| // Sometimes the structure of the object that is passed across is named in a strange way. | |
| // This conditional assignment solves that issue | |
| $val1 = isset($crit['value1']) ? $crit['value1'] : ''; | |
| $val2 = isset($crit['value2']) ? $crit['value2'] : ''; | |
| if (strlen($val1) === 0 && $crit['condition'] !== 'null' && $crit['condition'] !== '!null') { | |
| continue; | |
| } | |
| if (strlen($val2) === 0 && ($crit['condition'] === 'between' || $crit['condition'] === '!between')) { | |
| continue; | |
| } | |
| // Switch on the condition that has been passed in | |
| switch ($crit['condition']) { | |
| case '=': | |
| // Check if this is the first, or if it is and logic | |
| if ($data['logic'] === 'AND' || $first) { | |
| // Call the where function for this condition | |
| $query->where($crit['origData'], '=', $val1); | |
| // Set first to false so that in future only the logic is checked | |
| $first = false; | |
| } else { | |
| // Call the orWhere function - has to be or logic in this block | |
| $query->orWhere($crit['origData'], '=', $val1); | |
| } | |
| break; | |
| case '!=': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where($crit['origData'], '!=', $val1); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], '!=', $val1); | |
| } | |
| break; | |
| case 'contains': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where($crit['origData'], 'LIKE', '%' . $val1 . '%'); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], 'LIKE', '%' . $val1 . '%'); | |
| } | |
| break; | |
| case 'starts': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where($crit['origData'], 'LIKE', $val1 . '%'); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], 'LIKE', $val1 . '%'); | |
| } | |
| break; | |
| case 'ends': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where($crit['origData'], 'LIKE', '%' . $val1); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], 'LIKE', '%' . $val1); | |
| } | |
| break; | |
| case '<': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where($crit['origData'], '<', $val1); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], '<', $val1); | |
| } | |
| break; | |
| case '<=': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where($crit['origData'], '<=, $val1'); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], '<=, $val1'); | |
| } | |
| break; | |
| case '>=': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where($crit['origData'], '>=, $val1'); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], '>=, $val1'); | |
| } | |
| break; | |
| case '>': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where($crit['origData'], '>', $val1); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], '>', $val1); | |
| } | |
| break; | |
| case 'between': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where(function ($q) use ($crit, $val1, $val2) { | |
| $q->where($crit['origData'], '>', is_numeric($val1) ? intval($val1) : $val1)->where($crit['origData'], is_numeric($val2) ? intval($val2) : $val2, '<'); | |
| }); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], '>', is_numeric($val1) ? intval($val1) : $val1)->where($crit['origData'], is_numeric($val2) ? intval($val2) : $val2, '<'); | |
| } | |
| break; | |
| case '!between': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where(function ($q) use ($crit, $val1, $val2) { | |
| $q->where($crit['origData'], '<', is_numeric($val1) ? intval($val1) : $val1)->orWhere($crit['origData'], is_numeric($val2) ? intval($val2) : $val2, '>'); | |
| }); | |
| $first = false; | |
| } else { | |
| $query->orWhere($crit['origData'], '<', is_numeric($val1) ? intval($val1) : $val1)->orWhere($crit['origData'], is_numeric($val2) ? intval($val2) : $val2, '>'); | |
| } | |
| break; | |
| case 'null': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where(function ($q) use ($crit) { | |
| $q->where($crit['origData'], "=", null); | |
| if (strpos($crit['type'], 'date') === false && strpos($crit['type'], 'moment') === false && strpos($crit['type'], 'luxon') === false) { | |
| $q->orWhere($crit['origData'], "=", ""); | |
| } | |
| }); | |
| $first = false; | |
| } else { | |
| $query->orWhere(function ($q) use ($crit) { | |
| $q->where($crit['origData'], "=", null); | |
| if (strpos($crit['type'], 'date') === false && strpos($crit['type'], 'moment') === false && strpos($crit['type'], 'luxon') === false) { | |
| $q->orWhere($crit['origData'], "=", ""); | |
| } | |
| }); | |
| } | |
| break; | |
| case '!null': | |
| if ($data['logic'] === 'AND' || $first) { | |
| $query->where(function ($q) use ($crit) { | |
| $q->where($crit['origData'], "!=", null); | |
| if (strpos($crit['type'], 'date') === false && strpos($crit['type'], 'moment') === false && strpos($crit['type'], 'luxon') === false) { | |
| $q->where($crit['origData'], "!=", ""); | |
| } | |
| }); | |
| $first = false; | |
| } else { | |
| $query->orWhere(function ($q) use ($crit) { | |
| $q->where($crit['origData'], "!=", null); | |
| if (strpos($crit['type'], 'date') === false && strpos($crit['type'], 'moment') === false && strpos($crit['type'], 'luxon') === false) { | |
| $q->where($crit['origData'], "!=", ""); | |
| } | |
| }); | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment