File: /var/www/html/wpwatermates_err/wp-content/plugins/defender-security/src/model/audit-log.php
<?php
namespace WP_Defender\Model;
use WP_Defender\DB;
class Audit_Log extends DB {
public const EVENT_TYPE_USER = 'user', EVENT_TYPE_SYSTEM = 'system', EVENT_TYPE_COMMENT = 'comment',
EVENT_TYPE_MEDIA = 'media', EVENT_TYPE_SETTINGS = 'settings', EVENT_TYPE_CONTENT = 'content',
EVENT_TYPE_MENU = 'menu';
protected $table = 'defender_audit_log';
/**
* @var int
* @defender_property
*/
public $id;
/**
* @var int
* @defender_property
*/
public $timestamp;
/**
* @var string
* @defender_property
*/
public $event_type;
/**
* @var string
* @defender_property
*/
public $action_type;
/**
* @var string
* @defender_property
*/
public $site_url;
/**
* @var int
* @defender_property
*/
public $user_id;
/**
* @var string
* @defender_property
*/
public $context;
/**
* @var string
* @defender_property
*/
public $ip;
/**
* @var string
* @defender_property
*/
public $msg;
/**
* @var int
* @defender_property
*/
public $blog_id;
/**
* @var bool
* @defender_property
*/
public $synced;
/**
* @var int
* @defender_property
*/
public $ttl;
public $safe = [
'id',
'timestamp',
'event_type',
'action_type',
'site_url',
'user_id',
'context',
'ip',
'msg',
'blog_id',
'synced',
'ttl',
];
/**
* Truncate the table, as this is mostly use for cache, when we fetch new data, old data should be removed for consistent sync with API side.
*/
public static function truncate() {
$orm = self::get_orm();
$orm->get_repository( self::class )->truncate();
}
/**
* Get the very last item, mostly use for testing.
*
* @return self|null
*/
public static function get_last() {
$orm = self::get_orm();
return $orm->get_repository( self::class )
->where( 'synced', 'in', [ 0, 1 ] )
->order_by( 'id', 'desc' )
->first();
}
/**
* Sometimes we need the pre of last, for testing.
*
* @return self|null
*/
public static function get_pre_last() {
$orm = self::get_orm();
$model = $orm->get_repository( self::class )
->where( 'synced', 'in', [ 0, 1 ] )
->order_by( 'id', 'desc' )
->limit( '0,2' )
->get();
return array_pop( $model );
}
/**
* @return self[]
*/
public static function get_logs_need_flush() {
$orm = self::get_orm();
return $orm->get_repository( self::class )->where( 'synced', 0 )->limit( 50 )->get();
}
/**
* Query logs from internal cache.
*
* @param int $date_from The start date we want to query, in timestamp format.
* @param int $date_to The date end for the query, in timestamp format.
* @param array $events Type of the event, e.g. comment, user, system.
* @param string $user_id Who trigger this event, if it 0, will be guest.
* @param string $ip IP of who trigger this.
* @param int|bool $paged Current page.
*
* @return array
*/
public static function query( $date_from, $date_to, $events = [], $user_id = '', $ip = '', $paged = 1 ): array {
$orm = self::get_orm();
$builder = $orm->get_repository( self::class );
$builder->where( 'timestamp', '>=', $date_from )
->where( 'timestamp', '<=', $date_to );
if ( is_array( $events )
&& count( $events )
&& count( array_diff( $events, self::allowed_events() ) ) === 0 ) {
$builder->where( 'event_type', 'in', $events );
}
if ( ! empty( $user_id ) ) {
$builder->where( 'user_id', $user_id );
}
if ( ! empty( $ip ) ) {
$builder->where( 'ip', 'like', "%$ip%" );
}
$builder->order_by( 'timestamp', 'desc' );
if ( false !== $paged ) {
// If paged == false, then it will be no paging.
$per_page = 20;
$offset = ( ( $paged - 1 ) * $per_page ) . ',' . $per_page;
$builder->limit( $offset );
}
return $builder->get();
}
/**
* Clean up the old logs depending on the storage settings.
*
* @param int $date_from The start date we want to query, in timestamp format.
* @param int $date_to The date end for the query, in timestamp format.
* @param int|null $limit Limit.
*
* @return void
*/
public static function delete_old_logs( $date_from, $date_to, $limit = null ) {
$orm = self::get_orm();
$builder = $orm->get_repository( self::class );
$builder->where( 'timestamp', '>=', $date_from )
->where( 'timestamp', '<=', $date_to );
if ( null === $limit ) {
$builder->delete_all();
} else {
$builder->order_by( 'id' )
->limit( $limit )
->delete_by_limit();
}
}
/**
* This similar to @query, but we count the total row.
*
* @param $date_from
* @param $date_to
* @param array $events
* @param string $user_id
* @param string $ip
*/
public static function count( $date_from, $date_to, $events = [], $user_id = '', $ip = '' ) {
$orm = self::get_orm();
$builder = $orm->get_repository( self::class );
$builder->where( 'timestamp', '>=', $date_from )
->where( 'timestamp', '<=', $date_to );
if ( count( $events ) && count( array_diff( $events, self::allowed_events() ) ) === 0 ) {
$builder->where( 'event_type', 'in', $events );
}
if ( ! empty( $user_id ) ) {
$builder->where( 'user_id', $user_id );
}
if ( ! empty( $ip ) ) {
$builder->where( 'ip', 'like', "%$ip%" );
}
return $builder->count();
}
/**
* Mass insert logs, usually where we fetched from API.
*
* @param $data
*
* @throws \ReflectionException
*/
public static function mass_insert( $data ) {
// Use raw sql for faster.
foreach ( $data as $datum ) {
$item = new Audit_Log();
$item->import( $datum );
$item->synced = 1;
$item->save();
}
}
/**
* @param int $id
*/
public static function get_by_id( $id ) {
$orm = self::get_orm();
return $orm->get_repository( self::class )->find_by_id( $id );
}
/**
* Get allowed types.
*
* @return array
*/
public static function allowed_events(): array {
return [
self::EVENT_TYPE_USER,
self::EVENT_TYPE_SYSTEM,
self::EVENT_TYPE_COMMENT,
self::EVENT_TYPE_MEDIA,
self::EVENT_TYPE_SETTINGS,
self::EVENT_TYPE_CONTENT,
self::EVENT_TYPE_MENU,
];
}
}