Обычно я бы даже не ответил на такой вопрос, поскольку он слишком широкий, но, поскольку у меня похожая система, я поделюсь своим подходом. Пожалуйста, обратите внимание, я не предлагаю никакой поддержки в этом, но скорее это для вас, чтобы получить идею и / или разработать собственную реализацию.
Давайте предположим, что мы хотим регистрировать логины пользователей /сбои:
if ($this->ion_auth->login($identity, $this->input->post('password'), false)) {
$this->curr_user->update_ip();
$this->activity->log('logged_in');
$this->response->success()->json();
} else {
$this->activity->log('login_failed', array('username' => $identity));
$this->response->error($this->ion_auth->errors())->json();
}
Мы просто вызываем функцию log
перед перенаправлением / рендерингом вывода, но после того, как требуемое действие (вставка / обновление, вход в систему, и т. д.) завершено.
MODEL
Функция log
использует оператор switch для сохранения однородности сообщений и хранит определенную информацию отдельно от основного сообщения для запросов.Честно говоря, использование оператора switch здесь не слишком элегантно, особенно если у вас много сообщений, поэтому реализация таблицы для хранения сообщений не будет плохой идеей, но это работает для моих нужд.
get_logs
- это классная маленькая функция, которая объединяет все данные и отображает их в отсортированном списке по дате выполнения действия.
class User_activity_model extends CI_Model {
/**
* Admin-only viewable log types
*
* @var array
*/
private $admin_types = array('page_access', 'user_registered', 'logged_in', 'login_failed', 'login_failed_sa', 'delete');
/**
* Main user activity logging function
*
* @param string $action
* @param array $arr Additional attributes per case
* @return void
*/
public function log($action, $arr = array()) {
switch ($action) {
default:
return;
case 'backup_created':
$msg = "{username} created a backup {$arr['filename']} at {time}.";
break;
case 'backup_restored':
$msg = "{username} restored backup {$arr['filename']} at {time}.";
break;
case 'user_registered':
$msg = "{$arr['first_name']} {$arr['last_name']} registered with username: {$arr['username']}.";
break;
case 'added':
$msg = "{username} added item {$arr['id']} to the {$arr['table']} table.";
break;
case 'modified':
$msg = "{username} modified item {$arr['id']} in the {$arr['table']} table.";
break;
case 'deleted':
$msg = "{username} deleted item {$arr['id']} from the {$arr['table']} table.";
break;
case 'published':
$msg = "{username} published item {$arr['id']} from the {$arr['table']} table.";
break;
case 'unpublished':
$msg = "{username} unpublished item {$arr['id']} from the {$arr['table']} table.";
break;
case 'logged_in':
$ip = $this->input->ip_address();
$msg = "{username} logged in at {time} from IP {$ip}.";
break;
case 'login_failed':
$ip = $this->input->ip_address();
$msg = "Someone tried to login with username {$arr['username']} at {time} from IP {$ip}.";
break;
case 'login_failed_sa':
$ip = $this->input->ip_address();
$msg = "Someone tried to login with social auth provider {$arr['provider']} at {time} from IP {$ip}.";
break;
case 'page_access':
$identity = $this->ion_auth->logged_in() ? '{username}' : "Someone (IP: {$this->input->ip_address()})";
$msg = "{$identity} tried to access a page they didn't have permission for: {$arr['uri']}.";
break;
case 'logout':
$msg = "{username} logged out at {time}.";
break;
case 'user_forgotten':
$msg = 'Someone deleted their account.';
break;
}
$this->add($action, $msg);
}
/**
* Adds identifier information to the insert query
*
* @param string $action
* @param string $msg
* @return void
*/
private function add($action, $msg) {
$data = array(
'ip' => $this->input->ip_address(),
'action' => $action,
'type' => in_array($action, $this->admin_types) ? 'admin' : 'all',
'message' => $msg
);
if ($this->ion_auth->logged_in()) {
$data['username'] = $this->curr_user->details()->username;
$data['user_id'] = $this->curr_user->id();
}
$this->db->set('time', 'NOW()', false);
$this->db->insert('user_activity', $data);
}
/**
* Generates log array
*
* Format:
*
* array(
* [date]
* array(
* [0] = message1
* [1] = message2
*
* @param boolean $admin_only Show all logs?
* @return boolean|object Logs object, FALSE otherwise
*/
public function get_logs($admin_only = true) {
if (!$admin_only) {
$this->db->where('type !=', 'admin');
}
$this->db->limit(10000);
$this->db->order_by('time', 'DESC');
$query = $this->db->get('user_activity');
if ($query->num_rows() < 1) {
return false;
}
$rows = $query->result();
$data = new \stdClass();
foreach ($rows as $row) {
// replace {time} with timezone converted time
$time = $this->timezone->convert($row->time);
$row->message = str_replace('{time}', $time, $row->message);
$username = is_null($row->username) ? $this->lang->line('deleted_user') : $row->username;
$row->message = str_replace('{username}', $username, $row->message);
// date Y-m-d acts as key for messages on that day
$key = date('Y-m-d', strtotime($time));
$data->{$key}[] = $row;
}
return $data;
}
/**
* Truncates user_activity table
*
* @return boolean
*/
public function delete_logs() {
return $this->db->truncate('user_activity');
}
/**
* Stub for automate hook to add 'added' activity
*
* @param array $data
*/
public function automate_activity_add($data) {
$this->activity->log('added', array('table' => $data['table'], 'id' => $data['id']));
}
/**
* Stub for automate hook to add 'modified' activity
*
* @param array $data
*/
public function automate_activity_modify($data) {
$this->activity->log('modified', array('table' => $data['table'], 'id' => $data['id']));
}
}
БАЗА ДАННЫХ
дБ дамп: https://pastebin.com/wCEnUigH