requireManagerLogin() ->setPageTitle(WT_I18N::translate('Logs')); require WT_ROOT.'includes/functions/functions_edit.php'; $earliest=WT_DB::prepare("SELECT DATE(MIN(log_time)) FROM `##log`")->execute(array())->fetchOne(); $latest =WT_DB::prepare("SELECT DATE(MAX(log_time)) FROM `##log`")->execute(array())->fetchOne(); // Filtering $action = WT_Filter::get('action'); $from = WT_Filter::get('from', '\d\d\d\d-\d\d-\d\d', $earliest); $to = WT_Filter::get('to', '\d\d\d\d-\d\d-\d\d', $latest); $type = WT_Filter::get('type', 'auth|change|config|debug|edit|error|media|search'); $text = WT_Filter::get('text'); $ip = WT_Filter::get('ip'); $user = WT_Filter::get('user'); if (WT_USER_IS_ADMIN) { // Administrators can see all logs $gedc = WT_Filter::get('gedc'); } else { // Managers can only see logs relating to this gedcom $gedc = WT_GEDCOM; } $query=array(); $args =array(); if ($from) { $query[]='log_time>=?'; $args []=$from; } if ($to) { $query[]='log_timeexecute($args); break; case 'export': Zend_Session::writeClose(); header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename="webtrees-logs.csv"'); $rows=WT_DB::prepare($SELECT1.$WHERE.' ORDER BY log_id')->execute($args)->fetchAll(); foreach ($rows as $row) { echo '"', $row->log_time, '",', '"', $row->log_type, '",', '"', str_replace('"', '""', $row->log_message), '",', '"', $row->ip_address, '",', '"', str_replace('"', '""', $row->user_name), '",', '"', str_replace('"', '""', $row->gedcom_name), '"', "\n"; } exit; case 'load_json': Zend_Session::writeClose(); $iDisplayStart = WT_Filter::getInteger('iDisplayStart'); $iDisplayLength = WT_Filter::getInteger('iDisplayLength'); set_user_setting(WT_USER_ID, 'admin_site_log_page_size', $iDisplayLength); if ($iDisplayLength>0) { $LIMIT=" LIMIT " . $iDisplayStart . ',' . $iDisplayLength; } else { $LIMIT=""; } $iSortingCols = WT_Filter::getInteger('iSortingCols'); if ($iSortingCols) { $ORDER_BY=' ORDER BY '; for ($i=0; $i<$iSortingCols; ++$i) { // Datatables numbers columns 0, 1, 2, ... // MySQL numbers columns 1, 2, 3, ... switch (WT_Filter::get('sSortDir_'.$i)) { case 'asc': if (WT_Filter::getInteger('iSortCol_'.$i)==0) { $ORDER_BY.='log_id ASC '; // column 0 is "timestamp", using log_id gives the correct order for events in the same second } else { $ORDER_BY.=(1 + WT_Filter::getInteger('iSortCol_'.$i)).' ASC '; } break; case 'desc': if (WT_Filter::getInteger('iSortCol_'.$i)==0) { $ORDER_BY.='log_id DESC '; } else { $ORDER_BY.=(1 + WT_Filter::getInteger('iSortCol_'.$i)).' DESC '; } break; } if ($i<$iSortingCols-1) { $ORDER_BY.=','; } } } else { $ORDER_BY='1 DESC'; } // This becomes a JSON list, not array, so need to fetch with numeric keys. $aaData=WT_DB::prepare($SELECT1.$WHERE.$ORDER_BY.$LIMIT)->execute($args)->fetchAll(PDO::FETCH_NUM); foreach ($aaData as &$row) { $row[2]=WT_Filter::escapeHtml($row[2]); } // Total filtered/unfiltered rows $iTotalDisplayRecords=WT_DB::prepare("SELECT FOUND_ROWS()")->fetchColumn(); $iTotalRecords=WT_DB::prepare($SELECT2.$WHERE)->execute($args)->fetchColumn(); header('Content-type: application/json'); echo json_encode(array( // See http://www.datatables.net/usage/server-side 'sEcho' => WT_Filter::getInteger('sEcho'), // Always an integer 'iTotalRecords' => $iTotalRecords, 'iTotalDisplayRecords' => $iTotalDisplayRecords, 'aaData' => $aaData )); exit; } $controller ->pageHeader() ->addExternalJavascript(WT_JQUERY_DATATABLES_URL) ->addInlineJavascript(' var oTable=jQuery("#log_list").dataTable( { "sDom": \'<"H"pf<"dt-clear">irl>t<"F"pl>\', "bProcessing": true, "bServerSide": true, "sAjaxSource": "'.WT_SERVER_NAME.WT_SCRIPT_PATH.WT_SCRIPT_NAME.'?action=load_json&from='.$from.'&to='.$to.'&type='.$type.'&text='.rawurlencode($text).'&ip='.rawurlencode($ip).'&user='.rawurlencode($user).'&gedc='.rawurlencode($gedc).'", '.WT_I18N::datatablesI18N(array(10,20,50,100,500,1000,-1)).', "bJQueryUI": true, "bAutoWidth":false, "aaSorting": [[ 0, "desc" ]], "iDisplayLength": '.get_user_setting(WT_USER_ID, 'admin_site_log_page_size', 20).', "sPaginationType": "full_numbers" }); '); $url= WT_SCRIPT_NAME.'?from='.rawurlencode($from). '&to='.rawurlencode($to). '&type='.rawurlencode($type). '&text='.rawurlencode($text). '&ip='.rawurlencode($ip). '&user='.rawurlencode($user). '&gedc='.rawurlencode($gedc); $users_array=array_combine(get_all_users(), get_all_users()); uksort($users_array, 'strnatcasecmp'); echo '
', '', '', '', '', '', '', '', '', '', '', '', '', '', '
', // I18N: %s are both user-input date fields WT_I18N::translate('From %s to %s', '', ''), '
', WT_I18N::translate('Type'), '
', select_edit_control('type', array(''=>'', 'auth'=>'auth','config'=>'config','debug'=>'debug','edit'=>'edit','error'=>'error','media'=>'media','search'=>'search'), null, $type, ''), '
', WT_I18N::translate('Message'), '
', '
', WT_I18N::translate('IP address'), '
', '
', WT_I18N::translate('User'), '
', select_edit_control('user', $users_array, '', $user, ''), '
', WT_I18N::translate('Family tree'), '
', select_edit_control('gedc', WT_Tree::getNameList(), '', $gedc, WT_USER_IS_ADMIN ? '' : 'disabled'), '
', '', '', '', '
', '
'; if ($action) { echo '
', '', '', '', '', '', '', '', '', '', '', '', '', '', '
', WT_I18N::translate('Timestamp'), '', WT_I18N::translate('Type'), '', WT_I18N::translate('Message'), '', WT_I18N::translate('IP address'), '', WT_I18N::translate('User'), '', WT_I18N::translate('Family tree'), '
'; }