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=safe_GET('action'); $from =safe_GET('from', '\d\d\d\d-\d\d-\d\d', $earliest); $to =safe_GET('to', '\d\d\d\d-\d\d-\d\d', $latest); $type =safe_GET('type', array('auth','change','config','debug','edit','error','media','search')); $text =safe_GET('text'); $ip =safe_GET('ip'); $user =safe_GET('user'); if (WT_USER_IS_ADMIN) { // Administrators can see all logs $gedc=safe_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': 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': $iDisplayStart =(int)safe_GET('iDisplayStart'); $iDisplayLength=(int)safe_GET('iDisplayLength'); set_user_setting(WT_USER_ID, 'admin_site_log_page_size', $iDisplayLength); if ($iDisplayLength>0) { $LIMIT=" LIMIT " . $iDisplayStart . ',' . $iDisplayLength; } else { $LIMIT=""; } $iSortingCols=safe_GET('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 (safe_GET('sSortDir_'.$i)) { case 'asc': if ((int)safe_GET('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+(int)safe_GET('iSortCol_'.$i)).' ASC '; } break; case 'desc': if ((int)safe_GET('iSortCol_'.$i)==0) { $ORDER_BY.='log_id DESC '; } else { $ORDER_BY.=(1+(int)safe_GET('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); // 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' =>(int)safe_GET('sEcho'), 'iTotalRecords' =>$iTotalRecords, 'iTotalDisplayRecords'=>$iTotalDisplayRecords, 'aaData' =>$aaData )); exit; } $controller ->pageHeader() ->addExternalJavaScript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js') ->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).'", "oLanguage": { "sLengthMenu": "'./* I18N: Display %s [records per page], %s is a placeholder for listbox containing numeric options */ WT_I18N::translate('Display %s', '').'", "sZeroRecords": "'.WT_I18N::translate('No records to display').'", "sInfo": "'./* I18N: %s are placeholders for numbers */ WT_I18N::translate('Showing %1$s to %2$s of %3$s', '_START_', '_END_', '_TOTAL_').'", "sInfoEmpty": "'./* I18N: %s are placeholders for numbers */ WT_I18N::translate('Showing %1$s to %2$s of %3$s', '0', '0', '0').'", "sInfoFiltered": "'./* I18N: %s is a placeholder for a number */ WT_I18N::translate('(filtered from %s total entries)', '_MAX_').'", "sProcessing": "'.WT_I18N::translate('Loading...').'", "sSearch": "'.WT_I18N::translate('Filter').'", "oPaginate": { "sFirst": "'./* I18N: button label, first page */ WT_I18N::translate('first').'", "sLast": "'./* I18N: button label, last page */ WT_I18N::translate('last').'", "sNext": "'./* I18N: button label, next page */ WT_I18N::translate('next').'", "sPrevious": "'./* I18N: button label, previous page */ WT_I18N::translate('previous').'" } }, "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); $gedc_array=array(); foreach (get_all_gedcoms() as $ged_id=>$ged_name) { $gedc_array[$ged_name]=WT_I18N::translate('%s', get_gedcom_setting($ged_id, 'title')); } $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', $gedc_array, '', $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'), '
'; }