activity_log = $activity_log;
foreach ( glob( MWPAL_BASE_DIR . 'includes/loggers/*.php' ) as $file ) {
$this->add_from_file( $file );
}
}
/**
* Add new logger from file inside autoloader path.
*
* @param string $file Path to file.
*/
public function add_from_file( $file ) {
$this->add_from_class( $this->get_class_name( $file ) );
}
/**
* Add new logger given class name.
*
* @param string $class Class name.
*/
public function add_from_class( $class ) {
$this->add_instance( new $class( $this->activity_log ) );
}
/**
* Add newly created logger to list.
*
* @param AbstractLogger[] $logger - The new logger.
*/
public function add_instance( AbstractLogger $logger ) {
$this->loggers[] = $logger;
}
/**
* Get class name for logger classes.
*
* @param string $file – File name.
* @return string
*/
private function get_class_name( $file ) {
if ( empty( $file ) ) {
return false;
}
// Replace file path, `class-`, and `.php` in the file string.
$file = str_replace( array( MWPAL_BASE_DIR . 'includes/loggers/', 'class-', '.php' ), '', $file );
$file = str_replace( 'logger', 'Logger', $file );
$file = ucfirst( $file );
$file = '\WSAL\MainWPExtension\Loggers\\' . $file;
return $file;
}
/**
* Register a whole group of items.
*
* @param array $groups - An array with group name as the index and an array of group items as the value.
* Item values is an array of [type, code, description, message] respectively.
*/
public function RegisterGroup( $groups ) {
foreach ( $groups as $name => $group ) {
foreach ( $group as $subname => $subgroup ) {
foreach ( $subgroup as $item ) {
list($type, $code, $desc, $mesg) = $item;
$this->Register( array( $type, $code, $name, $subname, $desc, $mesg ) );
}
}
}
}
/**
* Register an alert type.
*
* @param array $info - Array of [type, code, category, description, message] respectively.
* @throws \Exception - Error if alert is already registered.
*/
public function Register( $info ) {
if ( 1 === func_num_args() ) {
// Handle single item.
list($type, $code, $catg, $subcatg, $desc, $mesg) = $info;
if ( isset( $this->alerts[ $type ] ) ) {
add_action( 'admin_notices', array( $this, 'duplicate_event_notice' ) );
/* Translators: Event ID */
throw new \Exception( sprintf( esc_html__( 'Event %s already registered with Activity Log MainWP Extension.', 'mwp-al-ext' ), $type ) );
}
$this->alerts[ $type ] = new Alert( $type, $code, $catg, $subcatg, $desc, $mesg );
} else {
// Handle multiple items.
foreach ( func_get_args() as $arg ) {
$this->Register( $arg );
}
}
}
/**
* Duplicate Event Notice
*
* WP admin notice for duplicate event.
*/
public function duplicate_event_notice() {
$class = 'notice notice-error';
$message = __( 'You have custom events that are using the same ID or IDs which are already registered in the plugin, so they have been disabled.', 'mwp-al-ext' );
printf(
/* Translators: 1.CSS classes, 2. Notice, 3. Contact us link */
'
%2$s %3$s ' . esc_html__( '%4$s to help you solve this issue.', 'mwp-al-ext' ) . '
',
esc_attr( $class ),
'' . esc_html__( 'ERROR:', 'mwp-al-ext' ) . '',
esc_html( $message ),
'' . esc_html__( 'Contact us', 'mwp-al-ext' ) . ''
);
}
/**
* Method: Returns an array of loaded loggers.
*
* @return AbstractLogger[]
*/
public function get_loggers() {
return $this->loggers;
}
/**
* Return alert given alert type.
*
* @param integer $type - Alert type.
* @param mixed $default - Returned if alert is not found.
* @return \WSAL\MainWPExtension\Alert
*/
public function GetAlert( $type, $default = null ) {
foreach ( $this->alerts as $alert ) {
if ( $alert->type == $type ) {
return $alert;
}
}
return $default;
}
/**
* Returns all supported alerts.
*
* @return \WSAL\MainWPExtension\Alert[]
*/
public function GetAlerts() {
return $this->alerts;
}
/**
* Method: Returns array of alerts by category.
*
* @param string $category - Alerts category.
* @return \WSAL\MainWPExtension\Alert[]
*/
public function get_alerts_by_category( $category ) {
// Categorized alerts array.
$alerts = array();
foreach ( $this->alerts as $alert ) {
if ( $category === $alert->catg ) {
$alerts[ $alert->type ] = $alert;
}
}
return $alerts;
}
/**
* Method: Returns array of alerts by sub-category.
*
* @param string $sub_category - Alerts sub-category.
* @return \WSAL\MainWPExtension\Alert[]
*/
public function get_alerts_by_sub_category( $sub_category ) {
// Sub-categorized alerts array.
$alerts = array();
foreach ( $this->alerts as $alert ) {
if ( $sub_category === $alert->subcatg ) {
$alerts[ $alert->type ] = $alert;
}
}
return $alerts;
}
/**
* Returns all supported alerts.
*
* @param bool $sorted – Sort the alerts array or not.
* @return array
*/
public function get_categorized_alerts( $sorted = true ) {
$result = array();
foreach ( $this->alerts as $alert ) {
if ( ! isset( $result[ $alert->catg ] ) ) {
$result[ $alert->catg ] = array();
}
if ( ! isset( $result[ $alert->catg ][ $alert->subcatg ] ) ) {
$result[ $alert->catg ][ $alert->subcatg ] = array();
}
$result[ $alert->catg ][ $alert->subcatg ][] = $alert;
}
if ( $sorted ) {
ksort( $result );
}
return $result;
}
/**
* Log events in the database.
*
* @param array $events – Activity Log Events.
* @param integer $site_id – Site ID according to MainWP.
* @return void
*/
public function log_events( $events, $site_id ) {
if ( empty( $events ) ) {
return;
}
if ( is_array( $events ) ) {
foreach ( $events as $event_id => $event ) {
// Get loggers.
$loggers = $this->get_loggers();
// Get meta data of event.
$meta_data = $event->meta_data;
$user_data = isset( $meta_data['UserData'] ) ? $meta_data['UserData'] : false;
// Username.
if ( isset( $user_data->username ) ) {
$meta_data['Username'] = $user_data->username;
}
// Log the events in DB.
foreach ( $loggers as $logger ) {
$logger->log( $event->alert_id, $meta_data, $event->created_on, $site_id );
}
}
}
}
/**
* Trigger an event.
*
* @param integer $type - Event type.
* @param array $data - Event data.
*/
public function trigger( $type, $data = array() ) {
// Get username.
if ( ! isset( $data['Username'] ) || empty( $data['Username'] ) ) {
$data['Username'] = wp_get_current_user()->user_login;
}
// Get current user roles.
$roles = $this->activity_log->settings->get_current_user_roles();
if ( empty( $roles ) && ! empty( $data['CurrentUserRoles'] ) ) {
$roles = $data['CurrentUserRoles'];
}
// Trigger event.
$this->commit_event( $type, $data, null );
}
/**
* Method: Commit an alert now.
*
* @param int $type - Alert type.
* @param array $data - Data of the alert.
* @param array $cond - Condition for the alert.
* @param bool $retry - Retry.
* @internal
*
* @throws Exception - Error if alert is not registered.
*/
protected function commit_event( $type, $data, $cond, $retry = true ) {
if ( ! $cond || ! ! call_user_func( $cond, $this ) ) {
if ( isset( $this->alerts[ $type ] ) ) {
// Ok, convert alert to a log entry.
$this->triggered_types[] = $type;
$this->log( $type, $data );
} elseif ( $retry ) {
// This is the last attempt at loading alerts from default file.
$this->activity_log->load_events();
return $this->commit_event( $type, $data, $cond, false );
} else {
// In general this shouldn't happen, but it could, so we handle it here.
/* translators: Event ID */
throw new Exception( sprintf( esc_html__( 'Event with code %d has not be registered.', 'mwp-al-ext' ), $type ) );
}
}
}
/**
* Log Alert
*
* Converts an Alert into a Log entry (by invoking loggers).
* You should not call this method directly.
*
* @param integer $type - Alert type.
* @param array $data - Misc alert data.
*/
protected function log( $type, $data = array() ) {
// Client IP.
if ( ! isset( $data['ClientIP'] ) ) {
$client_ip = $this->activity_log->settings->get_main_client_ip();
if ( ! empty( $client_ip ) ) {
$data['ClientIP'] = $client_ip;
}
}
// User agent.
if ( ! isset( $data['UserAgent'] ) ) {
if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
$data['UserAgent'] = sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) );
}
}
// Username.
if ( ! isset( $data['Username'] ) && ! isset( $data['CurrentUserID'] ) ) {
if ( function_exists( 'get_current_user_id' ) ) {
$data['CurrentUserID'] = get_current_user_id();
}
}
// Current user roles.
if ( ! isset( $data['CurrentUserRoles'] ) && function_exists( 'is_user_logged_in' ) && is_user_logged_in() ) {
$current_user_roles = $this->activity_log->settings->get_current_user_roles();
if ( ! empty( $current_user_roles ) ) {
$data['CurrentUserRoles'] = $current_user_roles;
}
}
// Log event.
foreach ( $this->loggers as $logger ) {
$logger->log( $type, $data, null, 0 );
}
}
/**
* Delete Events from Child Sites.
*
* @since 1.0.1
*
* @param integer $site_id - Child site ID.
*/
public function delete_site_events( $site_id = 0 ) {
if ( $site_id ) {
// Delete events by site id.
$delete_query = new \WSAL\MainWPExtension\Models\OccurrenceQuery();
$delete_query->addCondition( 'site_id = %s ', $site_id );
$delete_query->getAdapter()->Delete( $delete_query );
}
}
/**
* Fetch Events from Child Sites.
*
* @since 1.0.1
*
* @param integer $site_id - Child site id.
* @return array
*/
public function fetch_site_events( $site_id = 0, $trigger_retrieving = true ) {
$sites_data = array();
if ( $site_id ) {
// Get server IP.
$server_ip = $this->activity_log->settings->get_server_ip();
if ( $trigger_retrieving ) {
// Extension has started retrieving.
$this->trigger( 7711, array(
'mainwp_dash' => true,
'Username' => 'System',
'ClientIP' => ! empty( $server_ip ) ? $server_ip : false,
) );
}
// Post data for child sites.
$post_data = array(
'action' => 'get_events',
'events_count' => $this->activity_log->settings->get_child_site_events(),
);
// Call to child sites to fetch WSAL events.
return apply_filters(
'mainwp_fetchurlauthed',
$this->activity_log->get_child_file(),
$this->activity_log->get_child_key(),
$site_id,
'extra_excution',
$post_data
);
}
return $sites_data;
}
/**
* Save Events from Child Sites.
*
* @since 1.0.1
*
* @param array $sites_data - Sites data.
*/
public function set_site_events( $sites_data = array() ) {
if ( ! empty( $sites_data ) && is_array( $sites_data ) ) {
// Get MainWP child sites.
$mwp_sites = $this->activity_log->settings->get_mwp_child_sites();
// Get server IP.
$server_ip = $this->activity_log->settings->get_server_ip();
foreach ( $sites_data as $site_id => $site_events ) {
// If $site_events is array, then MainWP failed to fetch logs from the child site.
if ( ! empty( $site_events ) && is_array( $site_events ) ) {
// Search for the site data.
$key = array_search( $site_id, array_column( $mwp_sites, 'id' ), false );
if ( false !== $key && isset( $mwp_sites[ $key ] ) ) {
// Extension is unable to retrieve events.
$this->trigger( 7710, array(
'friendly_name' => $mwp_sites[ $key ]['name'],
'site_url' => $mwp_sites[ $key ]['url'],
'site_id' => $mwp_sites[ $key ]['id'],
'mainwp_dash' => true,
'Username' => 'System',
'ClientIP' => ! empty( $server_ip ) ? $server_ip : false,
) );
}
} elseif ( empty( $site_events ) || ! isset( $site_events->events ) ) {
continue;
}
$this->log_events( $site_events->events, $site_id );
}
}
}
}