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::get('order'); if ($order) { $sql .= ' ORDER BY '; for ($i = 0; $i < count($order); ++$i) { if ($i > 0) { $sql .= ','; } // Datatables numbers columns 0, 1, 2, ... // MySQL numbers columns 1, 2, 3, ... switch ($order[$i]['dir']) { case 'asc': $sql .= (1 + $order[$i]['column']) . ' ASC '; break; case 'desc': $sql .= (1 + $order[$i]['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::get('order'); if ($order) { $sql .= ' ORDER BY '; for ($i = 0; $i < count($order); ++$i) { if ($i > 0) { $sql .= ','; } // Datatables numbers columns 0, 1, 2, ... // MySQL numbers columns 1, 2, 3, ... switch ($order[$i]['dir']) { case 'asc': $sql .= (1 + $order[$i]['column']) . ' ASC '; break; case 'desc': $sql .= (1 + $order[$i]['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" ); ?>

- -

-