Skip to content

Commit

Permalink
latest eloquent search, error handling inmproved
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Blake committed Feb 12, 2016
1 parent 5421a48 commit f4f296f
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 13 deletions.
13 changes: 12 additions & 1 deletion assemble/eloquentsearch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,19 @@ Add this line to your `aliases` array:
``` php
'EloquentSearch' => Assemble\EloquentSearch\Facades\EloquentSearcher::class,
```

You will need to run `php artisan vendor:publish` to publish the config file to your instalation,
Once run, you can find it in `config/eloquenet_search.php`.
This config file is used to controll which models are used to search/return entities of.

### Additional Feature:

Implement the method 'isSearchable' in your models for the searcher to determine if it is allowed to search/return that model.
``` php
public function isSearchable(){
// Do your checks to determine if the model may be searched by the user
return true;
}
```
This feature lets you restrict user searches to only the models they are allowed to see.


Empty file modified assemble/eloquentsearch/composer.json
100644 → 100755
Empty file.
Empty file modified assemble/eloquentsearch/config/eloquent_search.php
100644 → 100755
Empty file.
Empty file modified assemble/eloquentsearch/src/EloquentSearchServiceProvider.php
100644 → 100755
Empty file.
Empty file modified assemble/eloquentsearch/src/Facades/Searcher.php
100644 → 100755
Empty file.
48 changes: 36 additions & 12 deletions assemble/eloquentsearch/src/Searcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Searcher
* The class entities in the system.
*/
private $_ENTITIES;

private $subJoined = false;

/**
* Create a new Searcher instance.
Expand Down Expand Up @@ -164,17 +164,17 @@ private function genRules($search) {
* @var Array
* @return \Illuminate\Database\Query\Builder[]|array
*/
public function getSearch($search, $order = null)
public function getSearch($search, $orderBy = null, $orderAs = null)
{
//check if order set properly
if($order == null || !isset($order['col']) || !isset($order['dir']) )
if( ( $orderBy == null || empty($orderBy) ) || ( $orderAs == null || empty($orderAs) ) )
{
$order = null;
}
else
{
$orderDir = $order['dir'];
$order = explode('.', $order['col']);
$orderDir = $orderAs;
$order = explode('.', $orderBy);
$orderField = array_pop($order);
$orderLast = end($order);
}
Expand Down Expand Up @@ -229,8 +229,20 @@ public function getSearch($search, $order = null)
]);
}


$query = (new $used_entity);//create new instance of the element, we need something to query on, so here it is

if(!(method_exists($query, 'isSearchable') && $query->isSearchable()))
{
return new MessageBag([
'code' => 401,
'messages' => [
//@TODO: lets add more clarity here later, for now this will do.
'You do not have permission to view this resource.'
]
]);
}

//Ok, not broken yet? good, lets continue and start building our query. First we just need to make sure theres something there.
if(is_array($criteria) && count($criteria) >= 1)
foreach($criteria as $criteria_item) {
Expand Down Expand Up @@ -310,21 +322,21 @@ public function getSearch($search, $order = null)
// $results->add($item);
// });
// }

if(!$this->subJoined){

if($order != null){

if(count($order) == 0)
if(isset($orderField) && isset($orderDir))
{
$query = $query->orderBy($orderField, $orderDir);
}
else
elseif(count($order) > 0)
{
foreach($order as $curOrder)
{
$query = $query->join($curOrder, $query->getModel()->getTable().'.'.$curOrder.'_id', '=', $curOrder.'.id')->orderBy($curOrder.'.'.$orderField, $orderDir);
}
}

$this->subJoined = false;
}

$results = $query;
Expand Down Expand Up @@ -368,12 +380,17 @@ private function whereHasBuilder(&$query, &$relations, &$field, &$where, &$value
if(count($order) > 0 && $rel == $order[0])
{
$curOrder = array_shift($order);
Log::info($curOrder.' - '.$orderDir.' -l- '.$orderLast);
}

$runComplex = true;
if(method_exists($rel, 'isSearchable'))
{
$runComplex = $rel->isSearchable();
}
//return a built query segment based on the criteria sent through
if($runComplex)
$query = $query->whereHas($rel,
function ($inner) use($field, $where, $value, $rel, $relations, $last, $curOrder, $order, $orderField, $orderLast, $orderDir) {
function ($inner) use($field, $where, $value, $rel, $relations, $last, $curOrder, $order, &$orderField, $orderLast, $orderDir) {
//make sure that the relation is not the last one in the list.
if($rel == $last) {
/**
Expand Down Expand Up @@ -402,8 +419,15 @@ function ($inner) use($field, $where, $value, $rel, $relations, $last, $curOrder
}
);

/*
* This is a workaround for ordering a result set by an associated value in another table,
* since the way we construct the query is not compatible with an orderby sub table, that needs a join,
* so we join here based on the standardisation assumption...
* which is needing to me migrated to configurations within models and use this as a fallback.
*/
if(!empty($curOrder)){
$query = $query->join($curOrder, $query->getModel()->getTable().'.'.$curOrder.'_id', '=', $curOrder.'.id')->orderBy($curOrder.'.'.$orderField, $orderDir);
$this->subJoined = true;
}
return $query;
}
Expand Down

0 comments on commit f4f296f

Please sign in to comment.