/** * @param array $queries { * * @type string $relation Optional. The MySQL keyword used to join the clauses of the query. Accepts 'AND', Or * 'OR'. Default 'AND'. * * @type array { * @type string $key Meta key to filter by. * @type string $value Meta value to filter by. * @type string $compare MySQL operator used for comparing the $value. Accepts '=', * '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', * 'BETWEEN', 'NOT BETWEEN', 'REGEXP', 'NOT REGEXP', or 'RLIKE'. * Default is '=' * } * } * * @param Builder $q * @param int $depth */ public function metaQueryClause($queries, &$q, $depth = 0) { $i = 0; foreach ($queries as $key => $query) { if ('relation' === $key) { //if relation were found we shall skip to the next iteration continue; } else { if (isset($query['key'])) { // That happens when a non-nested query found on the first iteration // in that case we the clause should be AND $relation = 0 === $i ? 'AND' : $queries['relation']; $q->where(function ($q) use($query) { if (isset($query['key'])) { $q->where('meta_key', '=', $query['key']); } if (isset($query['value'])) { if (isset($query['compare'])) { switch (strtolower($query['compare'])) { case 'between': $q->whereBetween('meta_value', $query['value']); break; case 'not between': $q->whereNotBetween('meta_value', $query['value']); break; case 'in': $q->whereIn('meta_value', $query['value']); break; case 'not in': $q->whereNotIn('meta_value', $query['value']); break; case 'is null': $q->whereIsNull('meta_value'); break; case 'is not null': $q->whereIsNotNull('meta_value'); break; default: $q->where('meta_value', $query['compare'], $query['value']); } } else { $q->where('meta_value', '=', $query['value']); } } }, null, null, $relation); } else { if (is_array($query)) { $depth = $depth + 1; // If we're going recursive for the first iterate we shall make the relation AND by default // else we should use the provided relation $relation = 1 === $depth && 0 === $i ? 'AND' : $queries['relation']; $q->where(function ($q) use($query, $depth) { $this->metaQueryClause($query, $q, $depth); }, null, null, $relation); } else { continue; } } } $i++; } }
/** * Exclude IDs from query * @param Builder $query * @param array $ids * @return void */ public function scopeExceptIds($query, array $ids) { $query->whereNotIn($this->getKeyName(), $ids); }