Skip to content

Commit c2d606a

Browse files
author
Adam Segal
committed
Added helpers to get db info from db connection query is from instead of config.
Kind of fix column prefixing. Really shouldn't the query builder be doing that? Simply because of the need for the raw statement for lower case. Escaped columns if dataFullSupport being used.
1 parent 8849334 commit c2d606a

File tree

1 file changed

+73
-10
lines changed

1 file changed

+73
-10
lines changed

src/Bllim/Datatables/Datatables.php

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ protected function saveQuery($query)
358358
$this->query_type = $query instanceof \Illuminate\Database\Query\Builder ? 'fluent' : 'eloquent';
359359
if ($this->dataFullSupport) {
360360
$this->columns = array_map(function ($column) {
361-
return $column['data'];
361+
return trim(DB::connection()->getPdo()->quote($column['data']), "'");
362362
}, $this->input['columns']);
363363
} else {
364364
$this->columns = $this->query_type == 'eloquent' ? ($this->query->getQuery()->columns ?: array()) : ($this->query->columns ?: array());
@@ -682,8 +682,6 @@ protected function filtering()
682682

683683
$this->query->where(function ($query) use (&$that, $column_aliases, $column_names) {
684684

685-
$db_prefix = $that->databasePrefix();
686-
687685
for ($i = 0, $c = count($that->input['columns']); $i < $c; $i++) {
688686
if (isset($column_aliases[$i]) && $that->input['columns'][$i]['searchable'] == "true") {
689687

@@ -731,12 +729,13 @@ protected function filtering()
731729
// If it is, cast the current column to TEXT datatype
732730
$cast_begin = null;
733731
$cast_end = null;
734-
if (DB::getDriverName() === 'pgsql') {
732+
if ($this->databaseDriver() === 'pgsql') {
735733
$cast_begin = "CAST(";
736734
$cast_end = " as TEXT)";
737735
}
738736

739-
$column = $db_prefix . $column_names[$i];
737+
//there's no need to put the prefix unless the column name is prefixed with the table name.
738+
$column = $this->prefixColumn($column_names[$i]);
740739

741740
if (Config::get('datatables::search.case_insensitive', false)) {
742741
$query->orwhere(DB::raw('LOWER(' . $cast_begin . $column . $cast_end . ')'), 'LIKE', strtolower($keyword));
@@ -751,8 +750,6 @@ protected function filtering()
751750

752751
}
753752

754-
$db_prefix = $this->databasePrefix();
755-
756753
// column search
757754
for ($i = 0, $c = count($this->input['columns']); $i < $c; $i++) {
758755
if (isset($column_aliases[$i]) && $this->input['columns'][$i]['orderable'] == "true" && $this->input['columns'][$i]['search']['value'] != '') {
@@ -783,13 +780,19 @@ protected function filtering()
783780

784781
} else // otherwise do simple LIKE search
785782
{
783+
786784
$keyword = $this->formatKeyword($this->input['columns'][$i]['search']['value']);
787785

786+
//there's no need to put the prefix unless the column name is prefixed with the table name.
787+
$column = $this->prefixColumn($column_names[$i]);
788+
788789
if (Config::get('datatables::search.case_insensitive', false)) {
789-
$column = $db_prefix . $column_names[$i];
790790
$this->query->where(DB::raw('LOWER(' . $column . ')'), 'LIKE', strtolower($keyword));
791791
} else {
792-
$col = strstr($column_names[$i], '(') ? DB::raw($column_names[$i]) : $column_names[$i];
792+
//note: so, when would a ( be in the columns? It will break a select if that's put in the columns
793+
//without a DB::raw. It could get there in filter columns, but it wouldn't be delt with here.
794+
//why is it searching for ( ?
795+
$col = strstr($column_names[$i], '(') ? DB::raw($column) : $column;
793796
$this->query->where($col, 'LIKE', $keyword);
794797
}
795798
}
@@ -844,7 +847,67 @@ public function formatWildcard($str, $lowercase = true)
844847
*/
845848
public function databasePrefix()
846849
{
847-
return Config::get('database.connections.' . Config::get('database.default') . '.prefix', '');
850+
if ($this->query_type == 'eloquent') {
851+
$query = $this->query->getQuery();
852+
} else {
853+
$query = $this->query;
854+
}
855+
return $query->getGrammar()->getTablePrefix();
856+
//return Config::get('database.connections.' . Config::get('database.default') . '.prefix', '');
857+
}
858+
859+
/**
860+
* Returns current database driver
861+
*/
862+
protected function databaseDriver()
863+
{
864+
if ($this->query_type == 'eloquent') {
865+
$query = $this->query->getQuery();
866+
} else {
867+
$query = $this->query;
868+
}
869+
return $query->getConnection()->getDriverName();
870+
}
871+
872+
/**
873+
* Will prefix column if needed
874+
*
875+
* @param string $column
876+
* @return string
877+
*/
878+
protected function prefixColumn($column)
879+
{
880+
$table_names = $this->tableNames();
881+
if (count(array_filter($table_names, function($value) use (&$column) { return strpos($column, $value.".") === 0; }))) {
882+
//the column starts with one of the table names
883+
$column = $this->databasePrefix() . $column;
884+
}
885+
return $column;
886+
}
887+
888+
/**
889+
* Will look through the query and all it's joins to determine the table names
890+
*
891+
* @return array
892+
*/
893+
protected function tableNames()
894+
{
895+
$names = [];
896+
897+
$query = ($this->query_type == 'eloquent') ? $this->query->getQuery() : $this->query;
898+
899+
$names[] = $query->from;
900+
$joins = $query->joins?:array();
901+
foreach ($joins as $join) {
902+
$table = preg_split("/ as /i", $join->table);
903+
$names[] = $table[0];
904+
if (isset($table[1]) && strpos($table[1], $this->databasePrefix()) == 0) {
905+
$names[] = preg_replace('/^'.$this->databasePrefix().'/', '', $table[1]);
906+
}
907+
}
908+
909+
return $names;
910+
848911
}
849912

850913
/**

0 commit comments

Comments
 (0)