restrictAccess(Auth::isAdmin())
->addExternalJavascript(WT_JQUERY_DATATABLES_URL)
->addExternalJavascript(WT_JQUERY_JEDITABLE_URL)
->setPageTitle(WT_I18N::translate('Site access rules'));
$action = WT_Filter::get('action');
switch ($action) {
case 'delete':
$user_access_rule_id = WT_Filter::getInteger('site_access_rule_id');
WT_DB::prepare("DELETE FROM `##site_access_rule` WHERE site_access_rule_id=?")->execute(array($user_access_rule_id));
break;
case 'allow':
case 'deny':
case 'robot':
$user_access_rule_id = WT_Filter::getInteger('site_access_rule_id');
WT_DB::prepare("UPDATE `##site_access_rule` SET rule=? WHERE site_access_rule_id=?")->execute(array($action, $user_access_rule_id));
break;
case 'load_rules':
Zend_Session::writeClose();
// AJAX callback for datatables
$search = WT_Filter::get('search');
$search = $search['value'];
$start = WT_Filter::getInteger('start');
$length = WT_Filter::getInteger('length');
$sql=
"SELECT SQL_CACHE SQL_CALC_FOUND_ROWS".
" INET_NTOA(ip_address_start), ip_address_start, INET_NTOA(ip_address_end), ip_address_end, user_agent_pattern, rule, comment, site_access_rule_id".
" FROM `##site_access_rule`".
" WHERE rule<>'unknown'";
$args=array();
if ($search) {
$sql.=
" AND (INET_ATON(?) BETWEEN ip_address_start AND ip_address_end".
" OR INET_NTOA(ip_address_start) LIKE CONCAT('%', ?, '%')".
" OR INET_NTOA(ip_address_end) LIKE CONCAT('%', ?, '%')".
" OR user_agent_pattern LIKE CONCAT('%', ?, '%')".
" OR comment LIKE CONCAT('%', ?, '%'))";
$args[]=$search;
$args[]=$search;
$args[]=$search;
$args[]=$search;
$args[]=$search;
}
$order = WT_Filter::getArray('order');
if ($order) {
$sql .= ' ORDER BY ';
foreach ($order as $key => $value) {
if ($key > 0) {
$sql .= ',';
}
// Datatables numbers columns 0, 1, 2, ...
// MySQL numbers columns 1, 2, 3, ...
switch ($value['dir']) {
case 'asc':
$sql .= (1 + $value['column']) . ' ASC ';
break;
case 'desc':
$sql .= (1 + $value['column']) . ' DESC ';
break;
}
}
} else {
$sql .= 'ORDER BY 1 ASC';
}
if ($length>0) {
$sql.=" LIMIT " . $start . ',' . $length;
}
// This becomes a JSON list, not a JSON array, so we need numeric keys.
$data = WT_DB::prepare($sql)->execute($args)->fetchAll(PDO::FETCH_NUM);
// Reformat the data for display
foreach ($data as &$datum) {
$site_access_rule_id = $datum[7];
$user_agent = $datum[4];
$datum[0] = edit_field_inline('site_access_rule-ip_address_start-' . $site_access_rule_id, $datum[0]);
$datum[2] = edit_field_inline('site_access_rule-ip_address_end-' . $site_access_rule_id, $datum[2]);
$datum[4] = edit_field_inline('site_access_rule-user_agent_pattern-' . $site_access_rule_id, $datum[4]);
$datum[5] = select_edit_control_inline('site_access_rule-rule-' . $site_access_rule_id, array(
'allow' => /* I18N: An access rule - allow access to the site */ WT_I18N::translate('allow'),
'deny' => /* I18N: An access rule - deny access to the site */ WT_I18N::translate('deny'),
'robot' => /* I18N: http://en.wikipedia.org/wiki/Web_crawler */ WT_I18N::translate('robot'),
), null, $datum[5]);
$datum[6] = edit_field_inline('site_access_rule-comment-'.$site_access_rule_id, $datum[6]);
$datum[7] = '';
}
// Total filtered/unfiltered rows
$recordsFiltered = WT_DB::prepare("SELECT FOUND_ROWS()")->fetchOne();
$recordsTotal = WT_DB::prepare("SELECT COUNT(*) FROM `##site_access_rule` WHERE rule <> 'unknown'")->fetchOne();
header('Content-type: application/json');
echo json_encode(array( // See http://www.datatables.net/usage/server-side
'draw' => WT_Filter::getInteger('draw'), // Always an integer
'recordsTotal' => $recordsTotal,
'recordsFiltered' => $recordsFiltered,
'data' => $data
));
exit;
case 'load_unknown':
Zend_Session::writeClose();
// AJAX callback for datatables
$search = WT_Filter::get('search');
$search = $search['value'];
$start = WT_Filter::getInteger('start');
$length = WT_Filter::getInteger('length');
$sql=
"SELECT SQL_CACHE SQL_CALC_FOUND_ROWS".
" INET_NTOA(ip_address_start), ip_address_start, user_agent_pattern, DATE(updated) AS updated, site_access_rule_id".
" FROM `##site_access_rule`".
" WHERE rule='unknown'";
$args = array();
if ($search) {
$sql .=
" AND (INET_ATON(ip_address_start) LIKE CONCAT('%', ?, '%')".
" OR user_agent_pattern LIKE CONCAT('%', ?, '%'))";
$args[] = $search;
$args[] = $search;
}
$order = WT_Filter::getArray('order');
if ($order) {
$sql .= ' ORDER BY ';
foreach ($order as $key => $value) {
if ($key > 0) {
$sql .= ',';
}
// Datatables numbers columns 0, 1, 2, ...
// MySQL numbers columns 1, 2, 3, ...
switch ($value['dir']) {
case 'asc':
$sql .= (1 + $value['column']) . ' ASC ';
break;
case 'desc':
$sql .= (1 + $value['column']) . ' DESC ';
break;
}
}
} else {
$sql .= 'ORDER BY 1 ASC';
}
if ($length>0) {
$sql .= " LIMIT " . $start . ',' . $length;
}
// This becomes a JSON list, not a JSON array, so we need numeric keys.
$data = WT_DB::prepare($sql)->execute($args)->fetchAll(PDO::FETCH_NUM);
// Reformat the data for display
foreach ($data as &$datum) {
$site_access_rule_id=$datum[4];
$datum[4] = '';
$datum[5] = '';
$datum[6] = '';
}
// Total filtered/unfiltered rows
$recordsFiltered = WT_DB::prepare("SELECT FOUND_ROWS()")->fetchOne();
$recordsTotal = WT_DB::prepare("SELECT COUNT(*) FROM `##site_access_rule` WHERE rule = 'unknown'")->fetchOne();
header('Content-type: application/json');
echo json_encode(array( // See http://www.datatables.net/usage/server-side
'draw' => WT_Filter::getInteger('draw'), // Always an integer
'recordsTotal' => $recordsTotal,
'recordsFiltered' => $recordsFiltered,
'data' => $data
));
exit;
}
$controller
->pageHeader()
->addInlineJavascript('
jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))};
jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))};
jQuery("#site_access_rules").dataTable({
dom: \'<"H"pf<"dt-clear">irl>t<"F"pl>\',
ajax: "'.WT_SERVER_NAME.WT_SCRIPT_PATH.WT_SCRIPT_NAME.'?action=load_rules",
serverSide: true,
'.WT_I18N::datatablesI18N().',
jQueryUI: true,
autoWidth: false,
processing: true,
pagingType: "full_numbers",
stateSave: true,
stateDuration: 180,
columns: [
/* 0 ip_address_start */ { dataSort: 1, class: "ip_address" },
/* 1 ip_address_start (sort) */ { type: "num", visible: false },
/* 2 ip_address_end */ { dataSort: 3, class: "ip_address" },
/* 3 ip_address_end (sort) */ { type: "num", visible: false },
/* 4 user_agent_pattern */ { class: "ua_string" },
/* 5 comment */ { },
/* 6 rule */ { },
/* 7 */ { sortable: false, class: "center" }
],
fnDrawCallback: function() {
// Our JSON responses include Javascript as well as HTML. This does not get
// executed, So extract it, and execute it
jQuery("#site_access_rules script").each(function() {
eval(this.text);
});
}
});
jQuery("#unknown_site_visitors").dataTable({
dom: \'<"H"pf<"dt-clear">irl>t<"F"pl>\',
ajax: "'.WT_SERVER_NAME.WT_SCRIPT_PATH.WT_SCRIPT_NAME.'?action=load_unknown",
serverSide: true,
'.WT_I18N::datatablesI18N().',
jQueryUI: true,
autoWidth: false,
processing: true,
stateSave: true,
stateDuration: 180,
pagingType: "full_numbers",
columns: [
/* 0 ip_address */ { dataSort: 1, class: "ip_address" },
/* 0 ip_address (sort) */ { type: "num", visible: false },
/* 1 user_agent_pattern */ { class: "ua_string" },
/* 2 updated */ { class: "ua_string" },
/* 3 */ { sortable: false, class: "center" },
/* 4 */ { sortable: false, class: "center" },
/* 5 */ { sortable: false, class: "center" }
]
});
');
// Delete any "unknown" visitors that are now "known".
// This could happen every time we create/update a rule.
WT_DB::exec(
"DELETE unknown".
" FROM `##site_access_rule` AS unknown".
" JOIN `##site_access_rule` AS known ON (unknown.user_agent_pattern LIKE known.user_agent_pattern)".
" WHERE unknown.rule='unknown' AND known.rule<>'unknown'".
" AND unknown.ip_address_start BETWEEN known.ip_address_start AND known.ip_address_end"
);
?>