サーバー側のDatatables(およびCodeIgniter)を使用してデータを表示しています。
データベースからエントリを直接削除できないため(残念ながらプロジェクトのガイドライン)、MySQLが自動的にBOOLEANから変更したため、DBテーブルの「deleted」(tinyint(1)」という列であるdeleted-Flagsを使用しています。それに)。
サーバー側の処理には、 https://github.com/blake-nouribekian/codeigniter-datatables/blob/master/data.phpで提供されているスクリプトを使用していますが、いくつかの小さな変更があります
// Columns use for SELECT part of the query. These names are not being escaped, so subqueries etc are possible.
$aColumns = array('events.id AS id', 'title', "FROM_UNIXTIME(start, '%d.%m.%Y') AS start", "FROM_UNIXTIME(start, '%H:%i') AS start_time", '(SELECT COUNT(*) FROM event_bookings WHERE id_event = events.id AND confirmed IS NOT NULL) AS participants', 'max_participants');
// Column names for WHERE clause (important for stuff like subqueries).
$aColumnNames = array('id', 'title', "start", "start", '(SELECT COUNT(*) FROM event_bookings WHERE id_event = events.id AND confirmed IS NOT NULL)', 'max_participants');
// Column for deleted flag in the DB.
$deleted_column = 'deleted';
// DB table to use
$sTable = 'events';
// no deleted entries
$this->db->where(Event_Model::$dbDeletedFlag, 0);
最初は、データは正しく表示され、削除済みとしてマークされたエントリは表示されません。ただし、検索フィールドに何かを入力するとすぐに、「... LIKE%input%」に一致するすべてのエントリが見つかります。$ this-> db-> where(Event_Model :: $ dbDeletedFlag、0);でワイルドになりました。コマンド、可能なすべての行に配置しますが、それでも改善はありません。削除済みとしてマークされたエントリが表示されます。検索フィールドを使用すると、whereコマンドが機能しなくなります。
これを解決する方法について何か提案はありますか?
編集:
これまでの回答に感謝します。関数全体をここに投稿しています:
public function server_processing() {
// EDIT THIS
// -----
// Columns use for SELECT part of the query. These names are not being escaped, so subqueries etc are possible.
$aColumns = array('events.id AS id', 'title', "FROM_UNIXTIME(start, '%d.%m.%Y') AS start", "FROM_UNIXTIME(start, '%H:%i') AS start_time", '(SELECT COUNT(*) FROM event_bookings WHERE id_event = events.id AND confirmed IS NOT NULL) AS participants', 'max_participants');
// Column names for WHERE clause (important for stuff like subqueries).
$aColumnNames = array('id', 'title', "start", "start", '(SELECT COUNT(*) FROM event_bookings WHERE id_event = events.id AND confirmed IS NOT NULL)', 'max_participants');
// Column for deleted flag in the DB.
$deleted_column = 'deleted';
// DB table to use
$sTable = 'events';
// no deleted entries
$this->db->where(Event_Model::$dbDeletedFlag, 0);
// -------
$iDisplayStart = $this->input->get_post('iDisplayStart', true);
$iDisplayLength = $this->input->get_post('iDisplayLength', true);
$iSortCol_0 = $this->input->get_post('iSortCol_0', true);
$iSortingCols = $this->input->get_post('iSortingCols', true);
$sSearch = $this->input->get_post('sSearch', true);
$sEcho = $this->input->get_post('sEcho', true);
// Paging
if (isset($iDisplayStart) && $iDisplayLength != '-1') {
$this->db->limit($this->db->escape_str($iDisplayLength), $this->db->escape_str($iDisplayStart));
}
// Ordering
if (isset($iSortCol_0)) {
for ($i = 0; $i < intval($iSortingCols); $i++) {
$iSortCol = $this->input->get_post('iSortCol_' . $i, true);
$bSortable = $this->input->get_post('bSortable_' . intval($iSortCol), true);
$sSortDir = $this->input->get_post('sSortDir_' . $i, true);
if ($bSortable == 'true') {
$this->db->order_by($aColumnNames[intval($this->db->escape_str($iSortCol))], $this->db->escape_str($sSortDir));
}
}
}
/*
* Filtering
* NOTE this does not match the built-in DataTables filtering which does it
* word by word on any field. It's possible to do here, but concerned about efficiency
* on very large tables, and MySQL's regex functionality is very limited
*/
if (isset($sSearch) && !empty($sSearch)) {
for ($i = 0; $i < count($aColumns); $i++) {
$bSearchable = $this->input->get_post('bSearchable_' . $i, true);
// Individual column filtering
if (isset($bSearchable) && $bSearchable == 'true') {
$this->db->or_like($aColumnNames[$i], $this->db->escape_like_str($sSearch));
}
}
}
// Select Data
$this->db->select('SQL_CALC_FOUND_ROWS ' . str_replace(' , ', ' ', implode(', ', $aColumns)), false);
$rResult = $this->db->get($sTable);
// Data set length after filtering
$this->db->select('FOUND_ROWS() AS found_rows');
$iFilteredTotal = $this->db->get()->row()->found_rows;
// Total data set length
$iTotal = $this->db->count_all($sTable);
// Output
$output = array(
'sEcho' => intval($sEcho),
'iTotalRecords' => $iTotal,
'iTotalDisplayRecords' => $iFilteredTotal,
'aaData' => array()
);
$output['aaData'] = array();
foreach ($rResult->result_array() as $aRow) {
// EDIT THIS
// --------
$row = array(
'<a class="detail_link link" href="javascript:void(0);" data-event-id="' . $aRow['id'] . '">' . $aRow['title'] . '</a>',
$aRow['start'],
$aRow['start_time'],
$aRow['participants'] . ' / ' . $aRow['max_participants']
);
if ($this->auth->access(Auth::Admin, true, false)) {
$row[] = '<img class="edit_link" data-event-id="' . $aRow['id'] . '" src="' . base_url() . 'img/icons/glyphicons_150_edit.png"> <img class="delete_link" data-event-id="' . $aRow['id'] . '" src="' . base_url() . 'img/icons/glyphicons_192_circle_remove.png">';
}
// --------
$output['aaData'][] = $row;
}
echo json_encode($output);
}
頑張ってくれてありがとう!
編集2
問題は、検索フィールドを使用すると、生成されたSQLステートメントが次のようになることだと思います。
SELECT fields FROM table WHERE deleted = 0 OR field LIKE %input%
それはむしろあるべきですが:
SELECT fields FROM table WHERE field LIKE %input% AND deleted = 0
この問題を解決するために、アクティブレコードがSQLステートメントをどのように構築するのか本当にわかりません