I've been working towards packaging my domain logic at my current job so I can reuse it in multiple implementations. The code snippets below were an abandoned experiment for a php Laravel project. I have recently put together a simple way to build a query from an array.
So, instead of something like this:
$post = Post::isPublished()
->where('id', $id)
->firstOrFail();
I create an array ['isPublished', 'id' => $id]
that is passed to a function defined in a trait.
protected function buildQuery(array $attributes)
{
if (count($attributes) == 0) {
app()->abort(404);
}
$query = (new $this->model);
foreach ($attributes as $key => $value) {
$method_name = camel_case(!is_numeric($key) ? $key : $value);
$scope_method_name = camel_case('scope'.$method_name);
// Call a local scope method on the model or resume
// with normal where equals clause.
if (method_exists($this->model, $scope_method_name)) {
$query = call_user_func([$query, $method_name], $value);
} else {
$query = $query->where($key, $value);
}
}
return $query;
}
This then allows me to call local scopes and also have a default functionality of $query->where('column', $value)
if not using a local scope. The resulting call could look something like...
$attributes = [
'isPublished',
'id' => $id
];
$post = $this->posts
->buildQuery($attributes)
->firstOrFail();
At the end of the day, an ORM is your friend. So in this case, I still end up using Eloquent over this.