diff --git a/assemble/eloquentsearch/README.md b/assemble/eloquentsearch/README.md index af32c7f..5f4ea51 100755 --- a/assemble/eloquentsearch/README.md +++ b/assemble/eloquentsearch/README.md @@ -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. + + diff --git a/assemble/eloquentsearch/composer.json b/assemble/eloquentsearch/composer.json old mode 100644 new mode 100755 diff --git a/assemble/eloquentsearch/config/eloquent_search.php b/assemble/eloquentsearch/config/eloquent_search.php old mode 100644 new mode 100755 diff --git a/assemble/eloquentsearch/src/EloquentSearchServiceProvider.php b/assemble/eloquentsearch/src/EloquentSearchServiceProvider.php old mode 100644 new mode 100755 diff --git a/assemble/eloquentsearch/src/Facades/Searcher.php b/assemble/eloquentsearch/src/Facades/Searcher.php old mode 100644 new mode 100755 diff --git a/assemble/eloquentsearch/src/Searcher.php b/assemble/eloquentsearch/src/Searcher.php index 8c8d0d4..5cf3917 100755 --- a/assemble/eloquentsearch/src/Searcher.php +++ b/assemble/eloquentsearch/src/Searcher.php @@ -17,7 +17,7 @@ class Searcher * The class entities in the system. */ private $_ENTITIES; - + private $subJoined = false; /** * Create a new Searcher instance. @@ -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); } @@ -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) { @@ -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; @@ -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) { /** @@ -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; }