laravel-6 support
This commit is contained in:
		| @@ -1,37 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable\Columns; | ||||
|  | ||||
| /** | ||||
|  * Class BaseColumn | ||||
|  * @package Chumper\Datatable\Columns | ||||
|  */ | ||||
| abstract class BaseColumn { | ||||
|  | ||||
|     /** | ||||
|      * @var String name of the column | ||||
|      */ | ||||
|     protected $name; | ||||
|  | ||||
|     /** | ||||
|      * @param $name | ||||
|      */ | ||||
|     function __construct($name) | ||||
|     { | ||||
|         $this->name = $name; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param mixed $model The data to pass to the column, | ||||
|      *              could be a model or an array | ||||
|      * @return mixed the return value of the implementation, | ||||
|      *              should be text in most of the cases | ||||
|      */ | ||||
|     public abstract function run($model); | ||||
|  | ||||
|     /** | ||||
|      * @return String The name of the column | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return $this->name; | ||||
|     } | ||||
| } | ||||
| @@ -1,69 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable\Columns; | ||||
|  | ||||
| class DateColumn extends BaseColumn { | ||||
|  | ||||
|     /** | ||||
|      * Constants for the time representation | ||||
|      */ | ||||
|     const DATE = 0; | ||||
|     const TIME = 1; | ||||
|     const DATE_TIME = 2; | ||||
|     const CUSTOM = 4; | ||||
|     const FORMATTED_DATE = 5; | ||||
|     const DAY_DATE = 6; | ||||
|  | ||||
|     /** | ||||
|      * @var int The format to show | ||||
|      */ | ||||
|     private $format; | ||||
|  | ||||
|     /** | ||||
|      * @var string custom show string if chosen | ||||
|      */ | ||||
|     private $custom; | ||||
|  | ||||
|     function __construct($name, $format = 2, $custom = "") | ||||
|     { | ||||
|         parent::__construct($name); | ||||
|         $this->format = $format; | ||||
|         $this->custom = $custom; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param mixed $model The data to pass to the column, | ||||
|      *              could be a model or an array | ||||
|      * @return mixed the return value of the implementation, | ||||
|      *              should be text in most of the cases | ||||
|      */ | ||||
|     public function run($model) | ||||
|     { | ||||
|  | ||||
|         if(is_string(is_array($model) ? $model[$this->name]: $model->{$this->name})) | ||||
|         { | ||||
|             return is_array($model) ? $model[$this->name]: $model->{$this->name}; | ||||
|         } | ||||
|  | ||||
|         switch($this->format) | ||||
|         { | ||||
|             case DateColumn::DATE: | ||||
|                 return is_array($model) ? $model[$this->name]->toDateString(): $model->{$this->name}->toDateString(); | ||||
|                 break; | ||||
|             case DateColumn::TIME: | ||||
|                 return is_array($model) ? $model[$this->name]->toTimeString(): $model->{$this->name}->toTimeString(); | ||||
|                 break; | ||||
|             case DateColumn::DATE_TIME: | ||||
|                 return is_array($model) ? $model[$this->name]->toDateTimeString(): $model->{$this->name}->toDateTimeString(); | ||||
|                 break; | ||||
|             case DateColumn::CUSTOM: | ||||
|                 return is_array($model) ? $model[$this->name]->format($this->custom): $model->{$this->name}->format($this->custom); | ||||
|                 break; | ||||
|             case DateColumn::FORMATTED_DATE: | ||||
|                 return is_array($model) ? $model[$this->name]->toFormattedDateString(): $model->{$this->name}->toFormattedDateString(); | ||||
|                 break; | ||||
|             case DateColumn::DAY_DATE: | ||||
|                 return is_array($model) ? $model[$this->name]->toDayDateTimeString(): $model->{$this->name}->toDayDateTimeString(); | ||||
|                 break; | ||||
|  | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,17 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable\Columns; | ||||
|  | ||||
| class FunctionColumn extends BaseColumn { | ||||
|  | ||||
|     private $callable; | ||||
|  | ||||
|     function __construct($name, $callable) | ||||
|     { | ||||
|         parent::__construct($name); | ||||
|         $this->callable = $callable; | ||||
|     } | ||||
|  | ||||
|     public function run($model) | ||||
|     { | ||||
|         return call_user_func($this->callable,$model); | ||||
|     } | ||||
| } | ||||
| @@ -1,17 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable\Columns; | ||||
|  | ||||
| class TextColumn extends BaseColumn { | ||||
|  | ||||
|     private $text; | ||||
|  | ||||
|     function __construct($name, $text) | ||||
|     { | ||||
|         parent::__construct($name); | ||||
|         $this->text = $text; | ||||
|     } | ||||
|  | ||||
|     public function run($model) | ||||
|     { | ||||
|         return $this->text; | ||||
|     } | ||||
| } | ||||
| @@ -1,57 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable; | ||||
|  | ||||
| use Chumper\Datatable\Engines\CollectionEngine; | ||||
| use Chumper\Datatable\Engines\QueryEngine; | ||||
| use Input; | ||||
| use Request; | ||||
|  | ||||
| /** | ||||
|  * Class Datatable | ||||
|  * @package Chumper\Datatable | ||||
|  */ | ||||
| class Datatable { | ||||
|  | ||||
|     private $columnNames = array(); | ||||
|  | ||||
|     /** | ||||
|      * @param $query | ||||
|      * @return \Chumper\Datatable\Engines\QueryEngine | ||||
|      */ | ||||
|     public function query($query) | ||||
|     { | ||||
|         $class = config('chumper.datatable.classmap.QueryEngine'); | ||||
|         return new $class($query); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $collection | ||||
|      * @return \Chumper\Datatable\Engines\CollectionEngine | ||||
|      */ | ||||
|     public function collection($collection) | ||||
|     { | ||||
|         $class = config('chumper.datatable.classmap.CollectionEngine'); | ||||
|         return new $class($collection); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Chumper\Datatable\Table | ||||
|      */ | ||||
|     public function table() | ||||
|     { | ||||
|         $class = config('chumper.datatable.classmap.Table'); | ||||
|         return new $class(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return bool True if the plugin should handle this request, false otherwise | ||||
|      */ | ||||
|     public function shouldHandle() | ||||
|     { | ||||
|         $echo = Input::get('sEcho',null); | ||||
|         if(/*Request::ajax() && */!is_null($echo) && is_numeric($echo)) | ||||
|         { | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @@ -1,58 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable; | ||||
|  | ||||
| use Illuminate\Support\ServiceProvider; | ||||
| use View; | ||||
|  | ||||
| class DatatableServiceProvider extends ServiceProvider { | ||||
|  | ||||
| 	/** | ||||
| 	 * Indicates if loading of the provider is deferred. | ||||
| 	 * | ||||
| 	 * @var bool | ||||
| 	 */ | ||||
| 	protected $defer = false; | ||||
|  | ||||
|     /** | ||||
|      * Bootstrap the application events. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function boot() | ||||
|     { | ||||
|         $this->publishes([ | ||||
|             __DIR__.'/../../config/config.php' => config_path('chumper.datatable.php'), | ||||
|             __DIR__.'/../../views' => base_path('resources/views/vendor/chumper.datatable'), | ||||
|         ]); | ||||
|  | ||||
|         $this->loadViewsFrom(__DIR__ . '/../../views', 'chumper.datatable'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| 	 * Register the service provider. | ||||
| 	 * | ||||
| 	 * @return void | ||||
| 	 */ | ||||
|     public function register() | ||||
|     { | ||||
|  | ||||
|         $this->mergeConfigFrom(__DIR__.'/../../config/config.php', 'chumper.datatable'); | ||||
|  | ||||
|         $this->app->singleton('datatable', function($app) | ||||
|         { | ||||
|             return new Datatable; | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the services provided by the provider. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function provides() | ||||
|     { | ||||
|         return array('datatable'); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,553 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable\Engines; | ||||
|  | ||||
| use Exception; | ||||
| use Assetic\Extension\Twig\AsseticFilterFunction; | ||||
| use Chumper\Datatable\Columns\DateColumn; | ||||
| use Chumper\Datatable\Columns\FunctionColumn; | ||||
| use Chumper\Datatable\Columns\TextColumn; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Input; | ||||
| use Illuminate\Support\Facades\Response; | ||||
| use Illuminate\Support\Facades\Config; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class BaseEngine | ||||
|  * @package Chumper\Datatable\Engines | ||||
|  */ | ||||
| abstract class BaseEngine { | ||||
|  | ||||
|     const ORDER_ASC = 'asc'; | ||||
|     const ORDER_DESC = 'desc'; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $config = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var mixed | ||||
|      */ | ||||
|     protected $rowClass = null; | ||||
|  | ||||
|     /** | ||||
|      * @var mixed | ||||
|      */ | ||||
|     protected $rowId = null; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $rowData = null; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $columnSearches = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      * support for DB::raw fields on where | ||||
|      */ | ||||
|     protected $fieldSearches = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      * support for DB::raw fields on where | ||||
|      * sburkett - added for column-based exact matching                                                                                                             | ||||
|      */                                                                                                                                                             | ||||
|     protected $columnSearchExact = array();  | ||||
|  | ||||
|     /** | ||||
|      * @var | ||||
|      */ | ||||
|     protected  $sEcho; | ||||
|  | ||||
|     /** | ||||
|      * @var \Illuminate\Support\Collection | ||||
|      */ | ||||
|     protected $columns; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     protected  $searchColumns = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $showColumns = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     protected  $orderColumns = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var int | ||||
|      */ | ||||
|     protected $skip = 0; | ||||
|  | ||||
|     /** | ||||
|      * @var null | ||||
|      */ | ||||
|     protected $limit = null; | ||||
|  | ||||
|     /** | ||||
|      * @var null | ||||
|      */ | ||||
|     protected $search = null; | ||||
|  | ||||
|     /** | ||||
|      * @var null | ||||
|      * Will be an array if order is set | ||||
|      * array( | ||||
|      *  0 => column | ||||
|      *  1 => name:cast:length | ||||
|      * ) | ||||
|      */ | ||||
|     protected $orderColumn = null; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $orderDirection = BaseEngine::ORDER_ASC; | ||||
|  | ||||
|     /** | ||||
|      * @var boolean If the return should be alias mapped | ||||
|      */ | ||||
|     protected $aliasMapping = false; | ||||
|  | ||||
|     /** | ||||
|      * @var bool If the search should be done with exact matching | ||||
|      */ | ||||
|     protected $exactWordSearch = false; | ||||
|  | ||||
|  | ||||
|     function __construct() | ||||
|     { | ||||
|         $this->columns = new Collection(); | ||||
|         $this->config = Config::get('chumper.datatable.engine'); | ||||
|         $this->setExactWordSearch( $this->config['exactWordSearch'] ); | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function addColumn() | ||||
|     { | ||||
|         if(func_num_args() != 2 && func_num_args() != 1) | ||||
|             throw new Exception('Invalid number of arguments'); | ||||
|  | ||||
|         if(func_num_args() == 1) | ||||
|         { | ||||
|             //add a predefined column | ||||
|             $this->columns->put(func_get_arg(0)->getName(), func_get_arg(0)); | ||||
|         } | ||||
|         else if(is_callable(func_get_arg(1))) | ||||
|         { | ||||
|             $this->columns->put(func_get_arg(0), new FunctionColumn(func_get_arg(0), func_get_arg(1))); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             $this->columns->put(func_get_arg(0), new TextColumn(func_get_arg(0),func_get_arg(1))); | ||||
|         } | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $name | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function getColumn($name) | ||||
|     { | ||||
|         return $this->columns->get($name,null); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getOrder() | ||||
|     { | ||||
|         return array_keys($this->columns->toArray()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getOrderingColumns() | ||||
|     { | ||||
|         return $this->orderColumns; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getSearchingColumns() | ||||
|     { | ||||
|         return $this->searchColumns; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function clearColumns() | ||||
|     { | ||||
|         $this->columns = new Collection(); | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $cols | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function showColumns($cols) | ||||
|     { | ||||
|         if ( ! is_array($cols)) { | ||||
|             $cols = func_get_args(); | ||||
|         } | ||||
|  | ||||
|         foreach ($cols as $property) { | ||||
|             //quick fix for created_at and updated_at columns | ||||
|             if(in_array($property, array('created_at', 'updated_at'))) | ||||
|             { | ||||
|                 $this->columns->put($property, new DateColumn($property, DateColumn::DAY_DATE)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 $this->columns->put($property, new FunctionColumn($property, function($model) use($property){ | ||||
|                     try{return is_array($model)?$model[$property]:$model->$property;}catch(Exception $e){return null;}     | ||||
|                 })); | ||||
|             } | ||||
|             $this->showColumns[] = $property; | ||||
|         } | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function make() | ||||
|     { | ||||
|         //TODO Handle all inputs | ||||
|         $this->handleInputs(); | ||||
|         $this->prepareSearchColumns(); | ||||
|  | ||||
|         $output = array( | ||||
|             "aaData" => $this->internalMake($this->columns, $this->searchColumns)->toArray(), | ||||
|             "sEcho" => intval($this->sEcho), | ||||
|             "iTotalRecords" => $this->totalCount(), | ||||
|             "iTotalDisplayRecords" => $this->count(), | ||||
|         ); | ||||
|         return Response::json($output); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $cols | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function searchColumns($cols) | ||||
|     { | ||||
|         if ( ! is_array($cols)) { | ||||
|             $cols = func_get_args(); | ||||
|         } | ||||
|  | ||||
|         $this->searchColumns = $cols; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $cols | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function orderColumns($cols) | ||||
|     { | ||||
|         if ( ! is_array($cols)) { | ||||
|             $cols = func_get_args(); | ||||
|         } | ||||
|  | ||||
|         if (count($cols) == 1 && $cols[0] == '*') | ||||
|             $cols = $this->showColumns; | ||||
|  | ||||
|         $this->orderColumns = $cols; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $function Set a function for a dynamic row class | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setRowClass($function) | ||||
|     { | ||||
|         $this->rowClass = $function; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $function Set a function for a dynamic row id | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setRowId($function) | ||||
|     { | ||||
|         $this->rowId = $function; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $function Set a function for dynamic html5 data attributes | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setRowData($function) | ||||
|     { | ||||
|         $this->rowData = $function; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setAliasMapping($value = true) | ||||
|     { | ||||
|         $this->aliasMapping = $value; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setExactWordSearch($value = true) | ||||
|     { | ||||
|         $this->exactWordSearch = $value; | ||||
|         return $this; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * @param $columnNames Sets up a lookup table for which columns should use exact matching -sburkett | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setExactMatchColumns($columnNames) | ||||
|     { | ||||
|       foreach($columnNames as $columnIndex) | ||||
|         $this->columnSearchExact[ $columnIndex ] = true; | ||||
|  | ||||
|       return $this; | ||||
|     } | ||||
|  | ||||
|     public function getRowClass() | ||||
|     { | ||||
|         return $this->rowClass; | ||||
|     } | ||||
|  | ||||
|     public function getRowId() | ||||
|     { | ||||
|         return $this->rowId; | ||||
|     } | ||||
|  | ||||
|     public function getRowData() | ||||
|     { | ||||
|         return $this->rowData; | ||||
|     } | ||||
|  | ||||
|     public function getAliasMapping() | ||||
|     { | ||||
|         return $this->aliasMapping; | ||||
|     } | ||||
|     //-------------protected functionS------------------- | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     protected function handleiDisplayStart($value) | ||||
|     { | ||||
|         //skip | ||||
|         $this->skip($value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     protected function handleiDisplayLength($value) | ||||
|     { | ||||
|         //limit nicht am query, sondern den ganzen | ||||
|         //holen und dann dynamisch in der Collection taken und skippen | ||||
|         $this->take($value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     protected function handlesEcho($value) | ||||
|     { | ||||
|         $this->sEcho = $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     protected function handlesSearch($value) | ||||
|     { | ||||
|         //handle search on columns sSearch, bRegex | ||||
|         $this->search($value); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     protected function handleiSortCol_0($value) | ||||
|     { | ||||
|         if(Input::get('sSortDir_0') == 'desc') | ||||
|             $direction = BaseEngine::ORDER_DESC; | ||||
|         else | ||||
|             $direction = BaseEngine::ORDER_ASC; | ||||
|  | ||||
|         //check if order is allowed | ||||
|         if(empty($this->orderColumns)) | ||||
|         { | ||||
|             $this->order(array(0 => $value, 1 => $this->getNameByIndex($value)), $direction); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         //prepare order array | ||||
|         $cleanNames = array(); | ||||
|         foreach($this->orderColumns as $c) | ||||
|         { | ||||
|             if(strpos($c,':') !== FALSE) | ||||
|             { | ||||
|                 $cleanNames[] = substr($c, 0, strpos($c,':')); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 $cleanNames[] = $c; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $i = 0; | ||||
|         foreach($this->columns as $name => $column) | ||||
|         { | ||||
|             if($i == $value && in_array($name, $cleanNames)) | ||||
|             { | ||||
|                 $this->order(array(0 => $value, 1 => $this->orderColumns[array_search($name,$cleanNames)]), $direction); | ||||
|                 return; | ||||
|             } | ||||
|             $i++; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param int $columnIndex | ||||
|      * @param string $searchValue | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function handleSingleColumnSearch($columnIndex, $searchValue) | ||||
|     { | ||||
|         //dd($columnIndex, $searchValue, $this->searchColumns); | ||||
|         if (!isset($this->searchColumns[$columnIndex])) return; | ||||
|         if (empty($searchValue) && $searchValue !== '0') return; | ||||
|  | ||||
|         $columnName = $this->searchColumns[$columnIndex]; | ||||
|         $this->searchOnColumn($columnName, $searchValue); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     protected function handleInputs() | ||||
|     { | ||||
|         //Handle all inputs magically | ||||
|         foreach (Input::all() as $key => $input) { | ||||
|  | ||||
|             // handle single column search | ||||
|             if ($this->isParameterForSingleColumnSearch($key)) | ||||
|             { | ||||
|                 $columnIndex = str_replace('sSearch_','',$key); | ||||
|                 $this->handleSingleColumnSearch($columnIndex, $input); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if(method_exists($this, $function = 'handle'.$key)) | ||||
|                 $this->$function($input); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $parameterName | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function isParameterForSingleColumnSearch($parameterName) | ||||
|     { | ||||
|         static $parameterNamePrefix = 'sSearch_'; | ||||
|         return str_contains($parameterName, $parameterNamePrefix); | ||||
|     } | ||||
|  | ||||
|     protected function prepareSearchColumns() | ||||
|     { | ||||
|         if(count($this->searchColumns) == 0 || empty($this->searchColumns)) | ||||
|             $this->searchColumns = $this->showColumns; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $column | ||||
|      * @param $order | ||||
|      */ | ||||
|     protected function order($column, $order = BaseEngine::ORDER_ASC) | ||||
|     { | ||||
|         $this->orderColumn = $column; | ||||
|         $this->orderDirection = $order; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     protected function search($value) | ||||
|     { | ||||
|         $this->search = $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $columnName | ||||
|      * @param mixed $value | ||||
|      */ | ||||
|     protected function searchOnColumn($columnName, $value) | ||||
|     { | ||||
|         $this->fieldSearches[] = $columnName; | ||||
|         $this->columnSearches[] = $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     protected function skip($value) | ||||
|     { | ||||
|         $this->skip = $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $value | ||||
|      */ | ||||
|     protected function take($value) | ||||
|     { | ||||
|         $this->limit = $value; | ||||
|     } | ||||
|  | ||||
|     public function getNameByIndex($index) | ||||
|     { | ||||
|         $i = 0; | ||||
|         foreach($this->columns as $name => $col) | ||||
|         { | ||||
|             if($index == $i) | ||||
|             { | ||||
|                 return $name; | ||||
|             } | ||||
|             $i++; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function getExactWordSearch() | ||||
|     { | ||||
|         return $this->exactWordSearch; | ||||
|     } | ||||
|  | ||||
|     abstract protected function totalCount(); | ||||
|     abstract protected function count(); | ||||
|     abstract protected function internalMake(Collection $columns, array $searchColumns = array()); | ||||
| } | ||||
| @@ -1,324 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable\Engines; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * This handles the collections, | ||||
|  * it needs to compile first, so we wait for the make command and then | ||||
|  * do all the operations | ||||
|  * | ||||
|  * Class CollectionEngine | ||||
|  * @package Chumper\Datatable\Engines | ||||
|  */ | ||||
| class CollectionEngine extends BaseEngine { | ||||
|  | ||||
|     /** | ||||
|      * Constant for OR queries in internal search | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     const OR_CONDITION = 'OR'; | ||||
|     /** | ||||
|      * Constant for AND queries in internal search | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     const AND_CONDITION = 'AND'; | ||||
|  | ||||
|     /** | ||||
|      * @var \Illuminate\Support\Collection | ||||
|      */ | ||||
|     private $workingCollection; | ||||
|  | ||||
|     /** | ||||
|      * @var \Illuminate\Support\Collection | ||||
|      */ | ||||
|     private $collection; | ||||
|  | ||||
|     /** | ||||
|      * @var array Different options | ||||
|      */ | ||||
|     private $options = array( | ||||
|         'sortFlags'         => SORT_NATURAL, | ||||
|         'stripOrder'        => false, | ||||
|         'stripSearch'       => false, | ||||
|         'caseSensitive'     => false, | ||||
|     ); | ||||
|  | ||||
|     /** | ||||
|      * @param Collection $collection | ||||
|      */ | ||||
|     function __construct(Collection $collection) | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->collection = $collection; | ||||
|         $this->workingCollection = $collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return int | ||||
|      */ | ||||
|     public function count() | ||||
|     { | ||||
|         return $this->workingCollection->count(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return int | ||||
|      */ | ||||
|     public function totalCount() | ||||
|     { | ||||
|         return $this->collection->count(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getArray() | ||||
|     { | ||||
|         $this->handleInputs(); | ||||
|         $this->compileArray($this->columns); | ||||
|         $this->doInternalSearch(new Collection(), array()); | ||||
|         $this->doInternalOrder(); | ||||
|  | ||||
|         return array_values($this->workingCollection | ||||
|             ->slice($this->skip,$this->limit) | ||||
|             ->toArray() | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Resets all operations performed on the collection | ||||
|      */ | ||||
|     public function reset() | ||||
|     { | ||||
|         $this->workingCollection = $this->collection; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function stripSearch() | ||||
|     { | ||||
|         $this->options['stripSearch'] = true; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function stripOrder($callback = true) | ||||
|     { | ||||
|         $this->options['stripOrder'] = $callback; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setSearchStrip() | ||||
|     { | ||||
|         $this->options['stripSearch'] = true; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setOrderStrip($callback = true) | ||||
|     { | ||||
|         return $this->stripOrder($callback); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the sort behaviour of the doInternalOrder() function. | ||||
|      * | ||||
|      * @param int $sort_flags For details see: http://php.net/manual/en/function.sort.php | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setOrderFlags($sort_flags = SORT_NATURAL) | ||||
|     { | ||||
|         $this->options['sortFlags'] = $sort_flags; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setCaseSensitive($value) | ||||
|     { | ||||
|         $this->options['caseSensitive'] = $value; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getOption($value) | ||||
|     { | ||||
|         return $this->options[$value]; | ||||
|     } | ||||
|     //--------------PRIVATE FUNCTIONS----------------- | ||||
|  | ||||
|     protected function internalMake(Collection $columns, array $searchColumns = array()) | ||||
|     { | ||||
|         $this->compileArray($columns); | ||||
|         $this->doInternalSearch($columns, $searchColumns); | ||||
|         $this->doInternalOrder(); | ||||
|  | ||||
|         return $this->workingCollection->slice($this->skip,$this->limit)->values(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Filter a collection based on the DataTables search parameters (sSearch_0 etc) | ||||
|      * See http://legacy.datatables.net/usage/server-side | ||||
|      * | ||||
|      * @param Collection $columns       All the columns in the DataTable | ||||
|      * @param array      $searchColumns Columns to search on - values are case-sensitive (must match definition from $columns) | ||||
|      */ | ||||
|     private function doInternalSearch(Collection $columns, array $searchColumns) | ||||
|     { | ||||
|         if((is_null($this->search) || empty($this->search)) && empty($this->fieldSearches)) | ||||
|             return; | ||||
|  | ||||
|         $value = $this->search; | ||||
|         $caseSensitive = $this->options['caseSensitive']; | ||||
|  | ||||
|         $toSearch = array(); | ||||
|         $searchType = self::AND_CONDITION; | ||||
|         // Map the searchColumns to the real columns | ||||
|         $ii = 0; | ||||
|         foreach($columns as $i => $col) | ||||
|         { | ||||
|             if(in_array($columns->get($i)->getName(), $searchColumns) || in_array($columns->get($i)->getName(), $this->fieldSearches)) | ||||
|             { | ||||
|                 // map values to columns, where there is no value use the global value | ||||
|                 if(($field = array_search($columns->get($i)->getName(), $this->fieldSearches)) !== FALSE) | ||||
|                 { | ||||
|                     $toSearch[$ii] = $this->columnSearches[$field]; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if($value) | ||||
|                         $searchType = self::OR_CONDITION; | ||||
|                     $toSearch[$ii] = $value; | ||||
|                 } | ||||
|             } | ||||
|             $ii++; | ||||
|         } | ||||
|  | ||||
|         $self = $this; | ||||
|         $this->workingCollection = $this->workingCollection->filter(function($row) use ($toSearch, $caseSensitive, $self, $searchType) | ||||
|         { | ||||
|             for($i=0, $stack=array(), $nb=count($row); $i<$nb; $i++) | ||||
|             { | ||||
|                 if(!array_key_exists($i, $toSearch)) | ||||
|                     continue; | ||||
|  | ||||
|                 $column = $i; | ||||
|                 if($self->getAliasMapping()) | ||||
|                 { | ||||
|                     $column = $self->getNameByIndex($i); | ||||
|                 } | ||||
|  | ||||
|                 if($self->getOption('stripSearch')) | ||||
|                 { | ||||
|                     $search = strip_tags($row[$column]); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     $search = $row[$column]; | ||||
|                 } | ||||
|                 if($caseSensitive) | ||||
|                 { | ||||
|                     if($self->exactWordSearch) | ||||
|                     { | ||||
|                         if($toSearch[$i] === $search) | ||||
|                             $stack[$i] = true; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         if(str_contains($search,$toSearch[$i])) | ||||
|                             $stack[$i] = true; | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if($self->getExactWordSearch()) | ||||
|                     { | ||||
|                         if(mb_strtolower($toSearch[$i]) === mb_strtolower($search)) | ||||
|                             $stack[$i] = true; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         if(str_contains(mb_strtolower($search),mb_strtolower($toSearch[$i]))) | ||||
|                             $stack[$i] = true; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if($searchType == $self::AND_CONDITION) | ||||
|             { | ||||
|                 $result = array_diff_key(array_filter($toSearch), $stack); | ||||
|                 if(empty($result)) | ||||
|                     return true; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if(!empty($stack)) | ||||
|                     return true; | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private function doInternalOrder() | ||||
|     { | ||||
|         if(is_null($this->orderColumn)) | ||||
|             return; | ||||
|  | ||||
|         $column = $this->orderColumn[0]; | ||||
|         $stripOrder = $this->options['stripOrder']; | ||||
|         $self = $this; | ||||
|         $this->workingCollection = $this->workingCollection->sortBy(function($row) use ($column,$stripOrder,$self) { | ||||
|  | ||||
|             if($self->getAliasMapping()) | ||||
|             { | ||||
|                 $column = $self->getNameByIndex($column); | ||||
|             } | ||||
|             if($stripOrder) | ||||
|             { | ||||
|                 if(is_callable($stripOrder)){ | ||||
|                     return $stripOrder($row, $column); | ||||
|                 }else{ | ||||
|                     return strip_tags($row[$column]); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return $row[$column]; | ||||
|             } | ||||
|         }, $this->options['sortFlags']); | ||||
|  | ||||
|         if($this->orderDirection == BaseEngine::ORDER_DESC) | ||||
|             $this->workingCollection = $this->workingCollection->reverse(); | ||||
|     } | ||||
|  | ||||
|     private function compileArray($columns) | ||||
|     { | ||||
|         $self = $this; | ||||
|         $this->workingCollection = $this->collection->map(function($row) use ($columns, $self) { | ||||
|             $entry = array(); | ||||
|  | ||||
|             // add class and id if needed | ||||
|             if(!is_null($self->getRowClass()) && is_callable($self->getRowClass())) | ||||
|             { | ||||
|                 $entry['DT_RowClass'] = call_user_func($self->getRowClass(),$row); | ||||
|             } | ||||
|             if(!is_null($self->getRowId()) && is_callable($self->getRowId())) | ||||
|             { | ||||
|                 $entry['DT_RowId'] = call_user_func($self->getRowId(),$row); | ||||
|             } | ||||
|             if(!is_null($self->getRowData()) && is_callable($self->getRowData())) | ||||
|             { | ||||
|                 $entry['DT_RowData'] = call_user_func($self->getRowData(),$row); | ||||
|             } | ||||
|             $i=0; | ||||
|             foreach ($columns as $col) | ||||
|             { | ||||
|                 if($self->getAliasMapping()) | ||||
|                 { | ||||
|                     $entry[$col->getName()] =  $col->run($row); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     $entry[$i] =  $col->run($row); | ||||
|                 } | ||||
|  | ||||
|                 $i++; | ||||
|             } | ||||
|             return $entry; | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| @@ -1,306 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable\Engines; | ||||
|  | ||||
| use Chumper\Datatable\Datatable; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Database\Query\Builder as QueryBuilder; | ||||
| use Illuminate\Database\Eloquent\Relations\Relation; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| class QueryEngine extends BaseEngine { | ||||
|  | ||||
|     /** | ||||
|      * @var Builder | ||||
|      */ | ||||
|     public $builder; | ||||
|     /** | ||||
|      * @var Builder | ||||
|      */ | ||||
|     public $originalBuilder; | ||||
|  | ||||
|     /** | ||||
|      * @var array single column searches | ||||
|      */ | ||||
|     public $columnSearches = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var Collection the returning collection | ||||
|      */ | ||||
|     private $resultCollection; | ||||
|  | ||||
|     /** | ||||
|      * @var Collection the resulting collection | ||||
|      */ | ||||
|     private $collection = null; | ||||
|  | ||||
|     /** | ||||
|      * @var array Different options | ||||
|      */ | ||||
|     protected $options = array( | ||||
|         'searchOperator'    =>  'LIKE', | ||||
|         'searchWithAlias'   =>  false, | ||||
|         'orderOrder'        =>  null, | ||||
|         'counter'           =>  0, | ||||
|         'noGroupByOnCount'  =>  false, | ||||
|     ); | ||||
|  | ||||
|     function __construct($builder) | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         if($builder instanceof Relation) | ||||
|         { | ||||
|             $this->builder = $builder->getBaseQuery(); | ||||
|             $this->originalBuilder = clone $builder->getBaseQuery(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             $this->builder = $builder; | ||||
|             $this->originalBuilder = clone $builder; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function count() | ||||
|     { | ||||
|         return $this->options['counter']; | ||||
|     } | ||||
|  | ||||
|     public function totalCount() | ||||
|     { | ||||
|         // Store temporary copy as we may modify it, we'd be stupid to modify | ||||
|         // the actual "original" copy... | ||||
|         $originalBuilder = $this->originalBuilder; | ||||
|  | ||||
|         if ($this->options['noGroupByOnCount']) { | ||||
|             $originalBuilder = $this->removeGroupBy($originalBuilder); | ||||
|         } | ||||
|  | ||||
|         return $originalBuilder->count(); | ||||
|     } | ||||
|  | ||||
|     public function getArray() | ||||
|     { | ||||
|        return $this->getCollection($this->builder)->toArray(); | ||||
|     } | ||||
|  | ||||
|     public function reset() | ||||
|     { | ||||
|         $this->builder = $this->originalBuilder; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public function setSearchOperator($value = "LIKE") | ||||
|     { | ||||
|         $this->options['searchOperator'] = $value; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setSearchWithAlias() | ||||
|     { | ||||
|         $this->options['searchWithAlias'] = true; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setNoGroupByOnCount() | ||||
|     { | ||||
|         $this->options['noGroupByOnCount'] = true; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     //--------PRIVATE FUNCTIONS | ||||
|  | ||||
|     protected function internalMake(Collection $columns, array $searchColumns = array()) | ||||
|     { | ||||
|         $builder = clone $this->builder; | ||||
|         $countBuilder = clone $this->builder; | ||||
|  | ||||
|         $builder = $this->doInternalSearch($builder, $searchColumns); | ||||
|         $countBuilder = $this->doInternalSearch($countBuilder, $searchColumns); | ||||
|  | ||||
|         if($this->options['searchWithAlias']) | ||||
|         { | ||||
|             $this->options['counter'] = count($countBuilder->get()); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // Remove the GROUP BY clause for the count | ||||
|             if ($this->options['noGroupByOnCount']) { | ||||
|                 $countBuilder = $this->removeGroupBy($countBuilder); | ||||
|             } | ||||
|             $this->options['counter'] = $countBuilder->count(); | ||||
|         } | ||||
|  | ||||
|         $builder = $this->doInternalOrder($builder, $columns); | ||||
|         $collection = $this->compile($builder, $columns); | ||||
|  | ||||
|         return $collection; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove the GROUP BY clause from a builder. | ||||
|      * | ||||
|      * @param Builder|QueryBuilder $builder | ||||
|      * @return Builder|QueryBuilder $builder with the groups property set to null. | ||||
|      */ | ||||
|     private function removeGroupBy($builder) | ||||
|     { | ||||
|         // Handle \Illuminate\Database\Eloquent\Builder | ||||
|         if ($builder instanceof Builder) { | ||||
|             $query = $builder->getQuery(); | ||||
|             $query->groups = null; | ||||
|             $builder->setQuery($query); | ||||
|         } | ||||
|         // Handle \Illuminate\Database\Query\Builder | ||||
|         else { | ||||
|             $builder->groups = null; | ||||
|         } | ||||
|  | ||||
|         return $builder; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $builder | ||||
|      * @return Collection | ||||
|      */ | ||||
|     private function getCollection($builder) | ||||
|     { | ||||
|         if($this->collection == null) | ||||
|         { | ||||
|             if($this->skip > 0) | ||||
|             { | ||||
|                 $builder = $builder->skip($this->skip); | ||||
|             } | ||||
|             if($this->limit > 0) | ||||
|             { | ||||
|                 $builder = $builder->take($this->limit); | ||||
|             } | ||||
|             //dd($this->builder->toSql()); | ||||
|             $this->collection = $builder->get(); | ||||
|  | ||||
|             if(is_array($this->collection)) | ||||
|                 $this->collection = new Collection($this->collection); | ||||
|         } | ||||
|         return $this->collection; | ||||
|     } | ||||
|  | ||||
|     private function doInternalSearch($builder, $columns) | ||||
|     { | ||||
|         if (!empty($this->search)) { | ||||
|             $this->buildSearchQuery($builder, $columns); | ||||
|         } | ||||
|  | ||||
|         if (!empty($this->columnSearches)) { | ||||
|             $this->buildSingleColumnSearches($builder); | ||||
|         } | ||||
|  | ||||
|         return $builder; | ||||
|     } | ||||
|     protected function buildSearchQuery($builder, $columns) | ||||
|     { | ||||
|         $like = $this->options['searchOperator']; | ||||
|         $search = $this->search; | ||||
|         $exact = $this->exactWordSearch; | ||||
|         $builder = $builder->where(function($query) use ($columns, $search, $like, $exact) { | ||||
|             foreach ($columns as $c) { | ||||
|                 //column to search within relationships : relatedModel::column | ||||
|                 if(strrpos($c, '::')) { | ||||
|                     $c = explode('::', $c); | ||||
|                     $query->orWhereHas($c[0], function($q) use($c, $like, $exact, $search){ | ||||
|                         $q->where($c[1], $like, $exact ? $search : '%' . $search . '%'); | ||||
|                     }); | ||||
|                 } | ||||
|                 //column to CAST following the pattern column:newType:[maxlength] | ||||
|                 elseif(strrpos($c, ':')){ | ||||
|                     $c = explode(':', $c); | ||||
|                     if(isset($c[2])) | ||||
|                         $c[1] .= "($c[2])"; | ||||
|                     $query->orWhereRaw("cast($c[0] as $c[1]) ".$like." ?", array($exact ? "$search" : "%$search%")); | ||||
|                 } | ||||
|                 else | ||||
|                     $query->orWhere($c, $like, $exact ? $search : '%' . $search . '%'); | ||||
|             } | ||||
|         }); | ||||
|         return $builder; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $builder | ||||
|      * Modified by sburkett to facilitate individual exact match searching on individual columns (rather than for all columns) | ||||
|      */ | ||||
|       | ||||
|     private function buildSingleColumnSearches($builder) | ||||
|     { | ||||
|       foreach ($this->columnSearches as $index => $searchValue) { | ||||
|         if(@$this->columnSearchExact[ $this->fieldSearches[$index] ] == 1) { | ||||
|           $builder->where($this->fieldSearches[$index], '=', $searchValue ); | ||||
|         } else { | ||||
|           $builder->where($this->fieldSearches[$index], $this->options['searchOperator'], '%' . $searchValue . '%'); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private function compile($builder, $columns) | ||||
|     { | ||||
|         $this->resultCollection = $this->getCollection($builder); | ||||
|  | ||||
|         $self = $this; | ||||
|         $this->resultCollection = $this->resultCollection->map(function($row) use ($columns,$self) { | ||||
|             $entry = array(); | ||||
|             // add class and id if needed | ||||
|             if(!is_null($self->getRowClass()) && is_callable($self->getRowClass())) | ||||
|             { | ||||
|                 $entry['DT_RowClass'] = call_user_func($self->getRowClass(),$row); | ||||
|             } | ||||
|             if(!is_null($self->getRowId()) && is_callable($self->getRowId())) | ||||
|             { | ||||
|                 $entry['DT_RowId'] = call_user_func($self->getRowId(),$row); | ||||
|             } | ||||
|             if(!is_null($self->getRowData()) && is_callable($self->getRowData())) | ||||
|             { | ||||
|                 $entry['DT_RowData'] = call_user_func($self->getRowData(),$row); | ||||
|             } | ||||
|             $i = 0; | ||||
|             foreach ($columns as $col) | ||||
|             { | ||||
|                 if($self->getAliasMapping()) | ||||
|                 { | ||||
|                     $entry[$col->getName()] =  $col->run($row); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     $entry[$i] =  $col->run($row); | ||||
|                 } | ||||
|                 $i++; | ||||
|             } | ||||
|             return $entry; | ||||
|         }); | ||||
|         return $this->resultCollection; | ||||
|     } | ||||
|  | ||||
|     private function doInternalOrder($builder, $columns) | ||||
|     { | ||||
|         //var_dump($this->orderColumn); | ||||
|         if(!is_null($this->orderColumn)) | ||||
|         { | ||||
|             $i = 0; | ||||
|             foreach($columns as $col) | ||||
|             { | ||||
|  | ||||
|                 if($i === (int) $this->orderColumn[0]) | ||||
|                 { | ||||
|                     if(strrpos($this->orderColumn[1], ':')){ | ||||
|                         $c = explode(':', $this->orderColumn[1]); | ||||
|                         if(isset($c[2])) | ||||
|                             $c[1] .= "($c[2])"; | ||||
|                         $builder = $builder->orderByRaw("cast($c[0] as $c[1]) ".$this->orderDirection); | ||||
|                     } | ||||
|                     else | ||||
|                         $builder = $builder->orderBy($col->getName(), $this->orderDirection); | ||||
|                     return $builder; | ||||
|                 } | ||||
|                 $i++; | ||||
|             } | ||||
|         } | ||||
|         return $builder; | ||||
|     } | ||||
| } | ||||
| @@ -1,14 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable\Facades; | ||||
|  | ||||
| use Illuminate\Support\Facades\Facade; | ||||
|  | ||||
| class DatatableFacade extends Facade { | ||||
|  | ||||
|     /** | ||||
|      * Get the registered name of the component. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected static function getFacadeAccessor() { return 'datatable'; } | ||||
|  | ||||
| } | ||||
| @@ -1,441 +0,0 @@ | ||||
| <?php namespace Chumper\Datatable; | ||||
|  | ||||
| use Exception; | ||||
| use Illuminate\Support\Facades\Request; | ||||
| use Illuminate\Support\Facades\View; | ||||
| use Illuminate\Support\Facades\Config; | ||||
|  | ||||
| /** | ||||
|  * Class Table | ||||
|  * @package Chumper\Datatable | ||||
|  */ | ||||
| class Table { | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     private $config = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     private $columns = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     private $options = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     private $callbacks = array(); | ||||
|  | ||||
|     /** | ||||
|      * Values to be sent to custom templates | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     private $customValues = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     private $data = array(); | ||||
|  | ||||
|     /** | ||||
|      * @var boolean Determines if the template should echo the javascript | ||||
|      */ | ||||
|     private $noScript = false; | ||||
|  | ||||
|     /** | ||||
|      * @var String The name of the id the table will have later | ||||
|      */ | ||||
|     protected $idName; | ||||
|  | ||||
|     /** | ||||
|      * @var String The name of the class the table will have later | ||||
|      */ | ||||
|     protected $className; | ||||
|  | ||||
|     /** | ||||
|      * @var String The view used to render the table | ||||
|      */ | ||||
|     protected $table_view; | ||||
|  | ||||
|     /** | ||||
|      * @var String The view used to render the javascript | ||||
|      */ | ||||
|     protected $script_view; | ||||
|  | ||||
|     /** | ||||
|      * @var boolean indicates if the mapping was already added to the options | ||||
|      */ | ||||
|     private $createdMapping = true; | ||||
|  | ||||
|     /** | ||||
|      * @var array name of mapped columns | ||||
|      */ | ||||
|     private $aliasColumns = array(); | ||||
|  | ||||
|     function __construct() | ||||
|     { | ||||
|         $this->config = Config::get('chumper.datatable.table'); | ||||
|  | ||||
|         $this->setId( $this->config['id'] ); | ||||
|         $this->setClass( $this->config['class'] ); | ||||
|         $this->setOptions( $this->config['options'] ); | ||||
|         $this->setCallbacks( $this->config['callbacks'] ); | ||||
|  | ||||
|         $this->noScript = $this->config['noScript']; | ||||
|         $this->table_view = $this->config['table_view']; | ||||
|         $this->script_view = $this->config['script_view']; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function addColumn() | ||||
|     { | ||||
|         foreach (func_get_args() as $title) | ||||
|         { | ||||
|             if(is_array($title)) | ||||
|             { | ||||
|                 foreach ($title as $mapping => $arrayTitle) | ||||
|                 { | ||||
|                     $this->columns[] = $arrayTitle; | ||||
|                     $this->aliasColumns[] = $mapping; | ||||
|                     if(is_string($mapping)) | ||||
|                     { | ||||
|                         $this->createdMapping = false; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 $this->columns[] = $title; | ||||
|                 $this->aliasColumns[] = count($this->aliasColumns)+1; | ||||
|             } | ||||
|         } | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return int | ||||
|      */ | ||||
|     public function countColumns() | ||||
|     { | ||||
|         return count($this->columns); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function removeOption($key) | ||||
|     { | ||||
|         if(isset($this->options[$key])) unset($this->options[$key]); | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function setOptions() | ||||
|     { | ||||
|         if(func_num_args() == 2) | ||||
|         { | ||||
|            $this->options[func_get_arg(0)] =func_get_arg(1); | ||||
|         } | ||||
|         else if(func_num_args() == 1 && is_array(func_get_arg(0))) | ||||
|         { | ||||
|             foreach (func_get_arg(0) as $key => $option) | ||||
|             { | ||||
|                 $this->options[$key] = $option; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|             throw new Exception('Invalid number of options provided for the method "setOptions"'); | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function setOrder($order = array()) | ||||
|     { | ||||
|         $_orders = array(); | ||||
|         foreach ($order as $number => $sort) | ||||
|         { | ||||
|             $_orders[] = [$number, $sort]; | ||||
|         } | ||||
|  | ||||
|         $this->callbacks['aaSorting'] = $_orders; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function setCallbacks() | ||||
|     { | ||||
|         if(func_num_args() == 2) | ||||
|         { | ||||
|             $this->callbacks[func_get_arg(0)] = func_get_arg(1); | ||||
|         } | ||||
|         else if(func_num_args() == 1 && is_array(func_get_arg(0))) | ||||
|         { | ||||
|             foreach (func_get_arg(0) as $key => $value) | ||||
|             { | ||||
|                 $this->callbacks[$key] = $value; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|             throw new Exception('Invalid number of callbacks provided for the method "setCallbacks"'); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function setCustomValues() | ||||
|     { | ||||
|         if(func_num_args() == 2) | ||||
|         { | ||||
|             $this->customValues[func_get_arg(0)] = func_get_arg(1); | ||||
|         } | ||||
|         else if(func_num_args() == 1 && is_array(func_get_arg(0))) | ||||
|         { | ||||
|             foreach (func_get_arg(0) as $key => $value) | ||||
|             { | ||||
|                 $this->customValues[$key] = $value; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|             throw new Exception('Invalid number of custom values provided for the method "setCustomValues"'); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setData(array $data) | ||||
|     { | ||||
|         $this->data = $data; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $url | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setUrl($url) | ||||
|     { | ||||
|         $this->options['sAjaxSource'] = $url; | ||||
|         $this->options['bServerSide'] = true; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getOptions() | ||||
|     { | ||||
|         return $this->options; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getCallbacks() | ||||
|     { | ||||
|         return $this->callbacks; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getCustomValues() | ||||
|     { | ||||
|         return $this->customValues; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getData() | ||||
|     { | ||||
|         return $this->data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param null $view | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function render($view = null) | ||||
|     { | ||||
|         if( ! is_null($view)) | ||||
|             $this->table_view = $view; | ||||
|  | ||||
|         return View::make($this->table_view, $this->getViewParameters()); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * returns an array with the parameters that will be passed to the view when it's rendered | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getViewParameters() | ||||
|     { | ||||
|         if(!isset($this->options['sAjaxSource'])) | ||||
|         { | ||||
|             $this->setUrl(Request::url()); | ||||
|         } | ||||
|  | ||||
|         // create mapping for frontend | ||||
|         if(!$this->createdMapping) | ||||
|         { | ||||
|             $this->createMapping(); | ||||
|         } | ||||
|         return array( | ||||
|             'options' => $this->convertData(array_merge($this->options, $this->callbacks)), | ||||
|             'values'    => $this->customValues, | ||||
|             'data'      => $this->data, | ||||
|             'columns'   => array_combine($this->aliasColumns,$this->columns), | ||||
|             'noScript'  => $this->noScript, | ||||
|             'id'        => $this->idName, | ||||
|             'class'     => $this->className, | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Instructs the table not to echo the javascript | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function noScript() | ||||
|     { | ||||
|         $this->noScript = true; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
| 	private function convertData($options) { | ||||
| 		$is_obj = false; | ||||
| 		$first = true; | ||||
| 		$data = ""; | ||||
| 		foreach ($options as $k => $o) { | ||||
| 			if ($first == true) { | ||||
| 				if (!is_numeric($k)) { | ||||
| 					$is_obj = true; | ||||
| 				} | ||||
| 				$first = false; | ||||
| 			} else { | ||||
| 				$data .= ",\n"; | ||||
| 			} | ||||
| 			if (!is_numeric($k)) { | ||||
| 				$data .= json_encode($k) . ":"; | ||||
| 			} | ||||
| 			if (is_string($o)) { | ||||
| 				if (@preg_match("#^\s*function\s*\([^\)]*#", $o)) { | ||||
| 					$data .= $o; | ||||
| 				} else { | ||||
| 					$data .= json_encode($o); | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (is_array($o)) { | ||||
| 					$data .= $this->convertData($o); | ||||
| 				} else { | ||||
| 					$data .= json_encode($o); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if ($is_obj) { | ||||
| 			$data = "{ $data }"; | ||||
| 		} else { | ||||
| 			$data = "[ $data ]"; | ||||
| 		} | ||||
|  | ||||
| 		return $data; | ||||
| 	} | ||||
|  | ||||
|     public function script($view = null) | ||||
|     { | ||||
|         if( ! is_null($view)) | ||||
|             $this->script_view = $view; | ||||
|  | ||||
|         // create mapping for frontend | ||||
|         if(!$this->createdMapping) | ||||
|         { | ||||
|             $this->createMapping(); | ||||
|         } | ||||
|  | ||||
|         return View::make($this->script_view,array( | ||||
|             'options' => $this->convertData(array_merge($this->options, $this->callbacks)), | ||||
|             'id'        =>  $this->idName, | ||||
|         )); | ||||
|     } | ||||
|  | ||||
|     public function getId() | ||||
|     { | ||||
|         return $this->idName; | ||||
|     } | ||||
|  | ||||
|     public function setId($id = '') | ||||
|     { | ||||
|         $this->idName = empty($id)? str_random(8) : $id; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getClass() | ||||
|     { | ||||
|         return $this->className; | ||||
|     } | ||||
|  | ||||
|     public function setClass($class) | ||||
|     { | ||||
|         $this->className = $class; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setAliasMapping($value) | ||||
|     { | ||||
|         $this->createdMapping = !$value; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     //--------------------PRIVATE FUNCTIONS | ||||
|  | ||||
|     private function createMapping() | ||||
|     { | ||||
|         // set options for better handling | ||||
|         // merge with existing options | ||||
|         if(!array_key_exists('aoColumns', $this->options)) | ||||
|         { | ||||
|             $this->options['aoColumns'] = array(); | ||||
|         } | ||||
|         $matching = array(); | ||||
|         $i = 0; | ||||
|         foreach($this->aliasColumns as $name) | ||||
|         { | ||||
|             if(array_key_exists($i,$this->options['aoColumns'])) | ||||
|             { | ||||
|                 $this->options['aoColumns'][$i] = array_merge_recursive($this->options['aoColumns'][$i],array('mData' => $name)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 $this->options['aoColumns'][$i] = array('mData' => $name); | ||||
|             } | ||||
|             $i++; | ||||
|         } | ||||
|         $this->createdMapping = true; | ||||
|         //dd($matching); | ||||
|         return $matching; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										146
									
								
								vendor/chumper/datatable/src/config/config.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										146
									
								
								vendor/chumper/datatable/src/config/config.php
									
									
									
									
										vendored
									
									
								
							| @@ -1,146 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| return array( | ||||
|  | ||||
|     /* | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | Table specific configuration options. | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | | ||||
|     */ | ||||
|  | ||||
|     'table' => array( | ||||
|  | ||||
|         /* | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | Table class | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | | ||||
|         | Class(es) added to the table | ||||
|         | Supported: string | ||||
|         | | ||||
|         */ | ||||
|  | ||||
|         'class' => 'table table-bordered', | ||||
|  | ||||
|         /* | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | Table ID | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | | ||||
|         | ID given to the table. Used for connecting the table and the Datatables | ||||
|         | jQuery plugin. If left empty a random ID will be generated. | ||||
|         | Supported: string | ||||
|         | | ||||
|         */ | ||||
|  | ||||
|         'id' => '', | ||||
|  | ||||
|         /* | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | DataTable options | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | | ||||
|         | jQuery dataTable plugin options. The array will be json_encoded and | ||||
|         | passed through to the plugin. See https://datatables.net/usage/options | ||||
|         | for more information. | ||||
|         | Supported: array | ||||
|         | | ||||
|         */ | ||||
|  | ||||
|         'options' => array( | ||||
|  | ||||
|             "sPaginationType" => "full_numbers", | ||||
|  | ||||
|             "bProcessing" => false | ||||
|  | ||||
|         ), | ||||
|  | ||||
|         /* | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | DataTable callbacks | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | | ||||
|         | jQuery dataTable plugin callbacks. The array will be json_encoded and | ||||
|         | passed through to the plugin. See https://datatables.net/usage/callbacks | ||||
|         | for more information. | ||||
|         | Supported: array | ||||
|         | | ||||
|         */ | ||||
|  | ||||
|         'callbacks' => array(), | ||||
|  | ||||
|         /* | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | Skip javascript in table template | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | | ||||
|         | Determines if the template should echo the javascript | ||||
|         | Supported: boolean | ||||
|         | | ||||
|         */ | ||||
|  | ||||
|         'noScript' => false, | ||||
|  | ||||
|  | ||||
|         /* | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | Table view | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | | ||||
|         | Template used to render the table | ||||
|         | Supported: string | ||||
|         | | ||||
|         */ | ||||
|  | ||||
|         'table_view' => 'chumper.datatable::template', | ||||
|  | ||||
|  | ||||
|         /* | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | Script view | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | | ||||
|         | Template used to render the javascript | ||||
|         | Supported: string | ||||
|         | | ||||
|         */ | ||||
|  | ||||
|         'script_view' => 'chumper.datatable::javascript', | ||||
|     ), | ||||
|  | ||||
|  | ||||
|     /* | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | Engine specific configuration options. | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | | ||||
|     */ | ||||
|  | ||||
|     'engine' => array( | ||||
|  | ||||
|         /* | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | Search for exact words | ||||
|         |-------------------------------------------------------------------------- | ||||
|         | | ||||
|         | If the search should be done with exact matching | ||||
|         | Supported: boolean | ||||
|         | | ||||
|         */ | ||||
|  | ||||
|         'exactWordSearch' => false, | ||||
|  | ||||
|     ), | ||||
|     /* | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | Allow overrides Datatable core classes | ||||
|     |-------------------------------------------------------------------------- | ||||
|     | | ||||
|     */ | ||||
|     'classmap' => array( | ||||
|         'CollectionEngine' => 'Chumper\Datatable\Engines\CollectionEngine', | ||||
|         'QueryEngine' => 'Chumper\Datatable\Engines\QueryEngine', | ||||
|         'Table' => 'Chumper\Datatable\Table', | ||||
|     ) | ||||
| ); | ||||
| @@ -1,8 +0,0 @@ | ||||
| <script type="text/javascript"> | ||||
|     jQuery(document).ready(function(){ | ||||
|         // dynamic table | ||||
|         oTable = jQuery('#{!! $id !!}').dataTable( | ||||
|             {!! $options !!} | ||||
|         ); | ||||
|     }); | ||||
| </script> | ||||
| @@ -1,27 +0,0 @@ | ||||
| <table id="{!! $id !!}" class="{!! $class !!}"> | ||||
|     <colgroup> | ||||
|         @for ($i = 0; $i < count($columns); $i++) | ||||
|         <col class="con{!! $i !!}" /> | ||||
|         @endfor | ||||
|     </colgroup> | ||||
|     <thead> | ||||
|     <tr> | ||||
|         @foreach($columns as $i => $c) | ||||
|         <th align="center" valign="middle" class="head{!! $i !!}">{!! $c !!}</th> | ||||
|         @endforeach | ||||
|     </tr> | ||||
|     </thead> | ||||
|     <tbody> | ||||
|     @foreach($data as $d) | ||||
|     <tr> | ||||
|         @foreach($d as $dd) | ||||
|         <td>{!! $dd !!}</td> | ||||
|         @endforeach | ||||
|     </tr> | ||||
|     @endforeach | ||||
|     </tbody> | ||||
| </table> | ||||
|  | ||||
| @if (!$noScript) | ||||
|     @include(Config::get('chumper.datatable.table.script_view'), array('id' => $id, 'options' => $options)) | ||||
| @endif | ||||
		Reference in New Issue
	
	Block a user
	 RafficMohammed
					RafficMohammed