Laravel 5 awesomeness

This commit is contained in:
Tom Lingham
2015-06-14 16:44:11 +10:00
parent 0a065c9731
commit 1e346baf59
9 changed files with 121 additions and 99 deletions

View File

@ -2,12 +2,11 @@
interface SearchDriverInterface
{
/**
* Execute the query on the Driver
*
* @param $searchString
* @return mixed
*/
public function query( $searchString );
public function select( /* $columns */ );
public function get();
}

View File

@ -22,6 +22,7 @@ class AcronymMatcher extends BaseMatcher
*/
public function formatSearchString( $searchString )
{
$searchString = preg_replace('/[^0-9a-zA-Z]/', '', $searchString);
return implode( '% ', str_split(strtoupper( $searchString ))) . '%';
}
}

View File

@ -22,6 +22,7 @@ class ConsecutiveCharactersMatcher extends BaseMatcher
*/
public function formatSearchString( $searchString )
{
$searchString = preg_replace('/[^0-9a-zA-Z]/', '', $searchString);
return '%'.implode('%', str_split( $searchString )).'%';
}

View File

@ -23,7 +23,7 @@ class StudlyCaseMatcher extends BaseMatcher
*/
public function formatSearchString( $searchString )
{
$searchString = preg_replace('/[^0-9a-zA-Z]/', '', $searchString);
return implode( '%', str_split(strtoupper( $searchString ))) . '%';
}

View File

@ -25,21 +25,28 @@ class SearchBuilder {
*/
private $driverName;
/**
* @var
*/
private $config;
public function __construct( Repository $config )
{
$this->config = $config;
}
/**
* @param $table
* @param $searchable
* @return $this
*/
public function search( $table )
public function search( $searchable )
{
$this->table = $table;
if (is_object( $searchable ) && method_exists($searchable, 'getTable')) {
$this->table = $searchable->getTable();
} else {
$this->table = $searchable;
}
return $this;
}
@ -49,13 +56,9 @@ class SearchBuilder {
*/
public function fields( /* $fields */ )
{
$searchFields = func_get_args();
$this->searchFields = $searchFields;
$this->searchFields = func_get_args();
return $this->makeDriver();
}
/**
@ -76,9 +79,7 @@ class SearchBuilder {
*/
public function __call( $table, $searchFields )
{
return call_user_func_array([$this->search( $table ), 'fields'], $searchFields);
}
/**
@ -86,6 +87,7 @@ class SearchBuilder {
*/
private function makeDriver()
{
$relevanceFieldName = $this->config->get('searchy.fieldName');
// Check if default driver is being overridden, otherwise
// load the default
@ -96,11 +98,12 @@ class SearchBuilder {
}
// Gets the details for the selected driver from the configuration file
$driverMap = $this->config->get("searchy.drivers.$driverName");
$driver = $this->config->get("searchy.drivers.$driverName")['class'];
// Create a new instance of the selected drivers 'class' and pass
// through table and fields to search
return new $driverMap['class']( $this->table, $this->searchFields );
$driverInstance = new $driver( $this->table, $this->searchFields, $relevanceFieldName );
return $driverInstance;
}

View File

@ -2,60 +2,98 @@
use TomLingham\Searchy\Interfaces\SearchDriverInterface;
/**
* @property mixed methods
* @property mixed matchers
*/
abstract class BaseSearchDriver implements SearchDriverInterface {
/**
* @var array
*/
protected $searchFields;
/**
* @var
*/
protected $searchString;
/**
* @var null
*/
protected $table;
protected $columns;
protected $searchFields;
protected $searchString;
protected $relevanceFieldName;
protected $query;
/**
* @param null $table
* @param array $searchFields
* @param $relevanceFieldName
* @param array $columns
* @internal param $relevanceField
*/
public function __construct( $table = null, $searchFields = [], $columns = ['*'] )
public function __construct( $table = null, $searchFields = [], $relevanceFieldName, $columns = ['*'] )
{
$this->searchFields = $searchFields;
$this->table = $table;
$this->columns = $columns;
$this->relevanceFieldName = $relevanceFieldName;
}
/**
* Specify which columns to return
*
* @return $this
*/
public function select()
{
$this->columns = func_get_args();
return $this;
}
/**
* Specify the string that is is being searched for
*
* @param $searchString
* @return \Illuminate\Database\Query\Builder|mixed|static
*/
public function query( $searchString )
{
$this->searchString = trim(\DB::connection()->getPdo()->quote( $searchString ), "'");
return $this;
}
if(\Config::get('searchy.sanitize'))
$this->searchString = $this->sanitize($searchString);
/**
* Get the results of the search as an Array
*
* @return array
*/
public function get()
{
return $this->run()->get();
}
$results = \DB::table($this->table)
->select( implode($this->columns, ', ') )
->addSelect($this->buildSelectQuery( $this->searchFields ))
->orderBy(\Config::get('searchy.fieldName'), 'desc')
->having(\Config::get('searchy.fieldName'),'>', 0);
/**
* Returns an instance of the Laravel Fluent Database Query Object with the search
* queries applied
*
* @return array
*/
public function getQuery()
{
return $this->run();
}
die($results->toSQL());
/**
* Runs the 'having' method directly on the Laravel Fluent Database Query Object
* and returns the instance of the object
*
* @return mixed
*/
public function having()
{
return call_user_func_array([$this->run(), 'having'], func_get_args());
}
return $results;
/**
* @return $this
*/
protected function run()
{
$this->query = \DB::table( $this->table )
->select( $this->columns )
->addSelect( $this->buildSelectQuery( $this->searchFields ) )
->orderBy( $this->relevanceFieldName, 'desc' )
->having( $this->relevanceFieldName, '>', 0 );
return $this->query;
}
/**
@ -64,20 +102,18 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
*/
protected function buildSelectQuery( array $searchFields )
{
$query = [];
foreach ($searchFields as $searchField) {
if (strpos($searchField, '::')){
$concatString = explode('::', $searchField);
$query[] = $this->buildSelectCriteria( "CONCAT({$concatString[0]}, ' ', {$concatString[1]})");
$concatString = str_replace('::', ", ' ', ", $searchField);
$query[] = $this->buildSelectCriteria( "CONCAT({$concatString})");
} else {
$query[] = $this->buildSelectCriteria( $searchField );
}
}
return \DB::raw(implode(' + ', $query) . ' AS ' . \Config::get('searchy.fieldName'));
return \DB::raw(implode(' + ', $query) . ' AS ' . $this->relevanceFieldName);
}
/**
@ -86,7 +122,6 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
*/
protected function buildSelectCriteria( $searchField = null )
{
$criteria = [];
foreach( $this->matchers as $matcher => $multiplier){
@ -105,20 +140,8 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
*/
protected function makeMatcher( $searchField, $matcherClass, $multiplier )
{
$matcher = new $matcherClass( $multiplier );
return $matcher->buildQueryString( $searchField, $this->searchString );
}
/**
* @param $searchString
* @return mixed
*/
private function sanitize( $searchString )
{
return preg_replace(\Config::get('searchy.sanitizeRegEx'), '', $searchString );
}
}

View File

@ -23,6 +23,10 @@ class SearchyServiceProvider extends ServiceProvider {
{
return new SearchBuilder( $app['config'] );
});
$this->mergeConfigFrom(
__DIR__ . '/../../config/config.php', 'searchy'
);
}
/**

View File

@ -4,10 +4,6 @@ return [
'default' => 'fuzzy',
'sanitize' => true,
'sanitizeRegEx' => '/[%\']+/i',
'fieldName' => 'relevance',
'drivers' => [