activity_log = $activity_log; $this->query_args = $query_args; // Set GMT offset. $timezone = $this->activity_log->settings->get_timezone(); if ( 'utc' === $timezone ) { $this->gmt_offset_sec = date( 'Z' ); } else { $this->gmt_offset_sec = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS; } // Get MainWP child sites. $this->mwp_child_sites = $this->activity_log->settings->get_mwp_child_sites(); parent::__construct( array( 'singular' => 'activity-log', 'plural' => 'activity-logs', 'ajax' => true, 'screen' => 'interval-list', ) ); } /** * Empty View. */ public function no_items() { esc_html_e( 'No events so far.', 'mwp-al-ext' ); } /** * Generate the table navigation above or below the table * * @param string $which – Nav position. */ protected function display_tablenav( $which ) { if ( 'top' === $which ) { wp_nonce_field( 'bulk-' . $this->_args['plural'] ); } ?>
extra_tablenav( $which ); $this->pagination( $which ); ?>
activity_log->settings->is_infinite_scroll() ) : // Items-per-page widget. $per_page = $this->activity_log->settings->get_view_per_page(); $items = array( 5, 10, 15, 30, 50 ); if ( ! in_array( $per_page, $items, true ) ) { $items[] = $per_page; } ?>
activity_log->settings->is_infinite_scroll() ) : ?>

activity_log->settings->get_wsal_child_sites(); if ( count( $wsal_child_sites ) > 0 ) : $current_site = $this->activity_log->settings->get_view_site_id(); ?>
id . '" name="' . esc_attr( $this->_args['singular'] ) . '[]" />'; } /** * Method: Get default column values. * * @param object $item - Column item. * @param string $column_name - Name of the column. */ public function column_default( $item, $column_name ) { $datetime_format = $this->activity_log->settings->get_date_time_format(); // Get date time format. $type_username = $this->activity_log->settings->get_type_username(); // Get username type to display. $mwp_child_sites = $this->mwp_child_sites; // Get MainWP child sites. if ( ! isset( $this->item_meta[ $item->getId() ] ) ) { $this->item_meta[ $item->getId() ] = $item->GetMetaArray(); } switch ( $column_name ) { case 'site': $site_id = (string) $item->site_id; $site_index = array_search( $site_id, array_column( $mwp_child_sites, 'id' ), true ); $html = ''; if ( false !== $site_index && isset( $mwp_child_sites[ $site_index ] ) ) { $html = ''; $html .= esc_html( $mwp_child_sites[ $site_index ]['name'] ); $html .= ''; } else { $html = __( 'MainWP Dashboard', 'mwp-al-ext' ); } return $html; case 'type': $code = $this->activity_log->alerts->GetAlert( $item->alert_id ); return '' . str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' '; case 'code': $code = $this->activity_log->alerts->GetAlert( $item->alert_id ); $code = $code ? $code->code : 0; $const = (object) array( 'name' => 'E_UNKNOWN', 'value' => 0, 'description' => __( 'Unknown error code.', 'mwp-al-ext' ), ); $const = $this->activity_log->constants->GetConstantBy( 'value', $code, $const ); if ( 'E_CRITICAL' === $const->name ) { $const->name = __( 'Critical', 'mwp-al-ext' ); } elseif ( 'E_WARNING' === $const->name ) { $const->name = __( 'Warning', 'mwp-al-ext' ); } elseif ( 'E_NOTICE' === $const->name ) { $const->name = __( 'Notification', 'mwp-al-ext' ); } return ''; case 'crtd': return $item->created_on ? ( str_replace( '$$$', substr( number_format( fmod( $item->created_on + $this->gmt_offset_sec, 1 ), 3 ), 2 ), date( $datetime_format, $item->created_on + $this->gmt_offset_sec ) ) ) : '' . __( 'Unknown', 'mwp-al-ext' ) . ''; case 'user': $username = $item->GetUsername( $this->item_meta[ $item->getId() ] ); // Get username. $user_data = $item->get_user_data( $this->item_meta[ $item->getId() ] ); // Get user data. if ( empty( $user_data ) ) { $user_data = get_user_by( 'login', $username ); } // Check if the usernames exists & matches pre-defined cases. if ( 'Plugin' === $username ) { $image = 'WSAL Logo'; $uhtml = '' . __( 'Plugin', 'mwp-al-ext' ) . ''; $roles = ''; } elseif ( 'Plugins' === $username ) { $image = ''; $uhtml = '' . __( 'Plugins', 'mwp-al-ext' ) . ''; $roles = ''; } elseif ( 'Website Visitor' === $username ) { $image = ''; $uhtml = '' . __( 'Website Visitor', 'mwp-al-ext' ) . ''; $roles = ''; } elseif ( 'System' === $username ) { $image = ''; $uhtml = '' . __( 'System', 'mwp-al-ext' ) . ''; $roles = ''; } elseif ( $username && $user_data ) { $image = get_avatar( $user_data->user_email, 32 ); // Avatar. // Checks for display name. if ( 'display_name' === $type_username && ! empty( $user_data->display_name ) ) { $display_name = $user_data->display_name; } elseif ( 'first_last_name' === $type_username && ( ! empty( $user_data->first_name ) || ! empty( $user_data->last_name ) ) ) { $display_name = $user_data->first_name . ' ' . $user_data->last_name; } else { $display_name = $user_data->username; } $site_id = (string) $item->site_id; $site_index = array_search( $site_id, array_column( $mwp_child_sites, 'id' ), true ); $site_url = '#'; if ( false !== $site_index && isset( $mwp_child_sites[ $site_index ] ) ) { $site_url = $mwp_child_sites[ $site_index ]['url']; $user_url = add_query_arg( 'user_id', $user_data->user_id, trailingslashit( $site_url ) . 'wp-admin/user-edit.php' ); } else { $user_url = add_query_arg( 'user_id', $user_data->ID, admin_url( 'user-edit.php' ) ); } // User html. $uhtml = '' . esc_html( $display_name ) . ''; $roles = $item->GetUserRoles( $this->item_meta[ $item->getId() ] ); if ( is_array( $roles ) && count( $roles ) ) { $roles = esc_html( ucwords( implode( ', ', $roles ) ) ); } elseif ( is_string( $roles ) && '' != $roles ) { $roles = esc_html( ucwords( str_replace( array( '"', '[', ']' ), ' ', $roles ) ) ); } else { $roles = '' . __( 'Unknown', 'mwp-al-ext' ) . ''; } } else { $image = ''; $uhtml = '' . __( 'System', 'mwp-al-ext' ) . ''; $roles = ''; } return $image . $uhtml . '
' . $roles; case 'scip': $scip = $item->GetSourceIP( $this->item_meta[ $item->getId() ] ); if ( is_string( $scip ) ) { $scip = str_replace( array( '"', '[', ']' ), '', $scip ); } $oips = array(); // $item->GetOtherIPs(); // If there's no IP... if ( is_null( $scip ) || '' == $scip ) { return 'unknown'; } // If there's only one IP... $link = 'https://whatismyipaddress.com/ip/' . $scip . '?utm_source=plugin&utm_medium=referral&utm_campaign=WPSAL'; if ( class_exists( 'WSAL_SearchExtension' ) ) { $tooltip = esc_attr__( 'Show me all activity originating from this IP Address', 'mwp-al-ext' ); if ( count( $oips ) < 2 ) { return "" . esc_html( $scip ) . ''; } } else { if ( count( $oips ) < 2 ) { return "" . esc_html( $scip ) . ''; } } // If there are many IPs... if ( class_exists( 'WSAL_SearchExtension' ) ) { $tooltip = esc_attr__( 'Show me all activity originating from this IP Address', 'mwp-al-ext' ); $html = "" . esc_html( $scip ) . ' (more…)
'; foreach ( $oips as $ip ) { if ( $scip != $ip ) { $html .= '
' . $ip . '
'; } } $html .= '
'; return $html; } else { $html = "" . esc_html( $scip ) . ' (more…)
'; foreach ( $oips as $ip ) { if ( $scip != $ip ) { $html .= '
' . $ip . '
'; } } $html .= '
'; return $html; } case 'mesg': return '
' . $item->GetMessage( array( $this, 'meta_formatter' ), $this->item_meta[ $item->getId() ] ) . '
'; case 'data': $url_args = array( 'action' => 'metadata_inspector', 'occurrence_id' => $item->id, 'mwp_meta_nonc' => wp_create_nonce( 'mwp-meta-display-' . $item->id ), 'TB_iframe' => 'true', 'width' => '600', 'height' => '550', ); $url = add_query_arg( $url_args, admin_url( 'admin-ajax.php' ) ); $tooltip = esc_attr__( 'View all details of this change', 'mwp-al-ext' ); return ''; default: /* translators: Column Name */ return isset( $item->$column_name ) ? esc_html( $item->$column_name ) : sprintf( esc_html__( 'Column "%s" not found', 'mwp-al-ext' ), $column_name ); } } /** * Method: Get View Columns. * * @return array */ public function get_columns() { // Audit log columns. $cols = array( 'site' => __( 'Site', 'mwp-al-ext' ), 'type' => __( 'Event ID', 'mwp-al-ext' ), 'code' => __( 'Severity', 'mwp-al-ext' ), 'crtd' => __( 'Date', 'mwp-al-ext' ), 'user' => __( 'User', 'mwp-al-ext' ), 'scip' => __( 'Source IP', 'mwp-al-ext' ), 'mesg' => __( 'Message', 'mwp-al-ext' ), 'data' => '', ); // Get selected columns. $selected = $this->activity_log->settings->get_columns_selected(); // If selected columns are not empty, then unset default columns. if ( ! empty( $selected ) ) { unset( $cols ); $selected = (array) json_decode( $selected ); foreach ( $selected as $key => $value ) { switch ( $key ) { case 'site': $cols['site'] = __( 'Site', 'mwp-al-ext' ); break; case 'alert_code': $cols['type'] = __( 'Event ID', 'mwp-al-ext' ); break; case 'type': $cols['code'] = __( 'Severity', 'mwp-al-ext' ); break; case 'date': $cols['crtd'] = __( 'Date', 'mwp-al-ext' ); break; case 'username': $cols['user'] = __( 'User', 'mwp-al-ext' ); break; case 'source_ip': $cols['scip'] = __( 'Source IP', 'mwp-al-ext' ); break; case 'message': $cols['mesg'] = __( 'Message', 'mwp-al-ext' ); break; } } $cols['data'] = ''; } return $cols; } /** * Method: Get Sortable Columns. * * @return array */ public function get_sortable_columns() { return array( 'read' => array( 'is_read', false ), 'type' => array( 'alert_id', false ), 'crtd' => array( 'created_on', true ), 'user' => array( 'user', true ), 'scip' => array( 'scip', false ), ); } /** * Method: Prepare items. */ public function prepare_items() { $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array( $columns, $hidden, $sortable ); $query_events = $this->query_events(); $this->items = isset( $query_events['items'] ) ? $query_events['items'] : false; $total_items = isset( $query_events['total_items'] ) ? $query_events['total_items'] : false; $per_page = isset( $query_events['per_page'] ) ? $query_events['per_page'] : false; if ( ! $this->activity_log->settings->is_infinite_scroll() ) { $this->set_pagination_args( array( 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil( $total_items / $per_page ), ) ); } } /** * Query Events from WSAL DB. * * @since 1.1 * * @param integer $paged - Page number. * @return array */ public function query_events( $paged = 0 ) { // Query for events. $events_query = new \WSAL\MainWPExtension\Models\OccurrenceQuery(); // Get site id for specific site events. $bid = $this->query_args->site_id; if ( $bid && 'dashboard' !== $bid ) { $events_query->addCondition( 'site_id = %s ', $bid ); } elseif ( 'dashboard' === $bid ) { $events_query->addCondition( 'site_id = %s ', '0' ); } /** * Filter: `mwpal_auditlog_query` * * This filter can be used to modify the query for events. * It is helpful while performing search operations on the * audit log events. * * @param \WSAL\MainWPExtension\Models\OccurrenceQuery $events_query – Occurrrence query instance. */ $events_query = apply_filters( 'mwpal_auditlog_query', $events_query ); if ( ! $this->activity_log->settings->is_infinite_scroll() ) { $total_items = $events_query->getAdapter()->Count( $events_query ); $per_page = $this->activity_log->settings->get_view_per_page(); $offset = ( $this->get_pagenum() - 1 ) * $per_page; } else { $total_items = false; $per_page = 25; // Manually set per page events for infinite scroll. $offset = ( max( 1, $paged ) - 1 ) * $per_page; } // Set query order arguments. $order_by = isset( $this->query_args->order_by ) ? $this->query_args->order_by : false; $order = isset( $this->query_args->order ) ? $this->query_args->order : false; if ( ! $order_by ) { $events_query->addOrderBy( 'created_on', true ); } else { $is_descending = true; if ( ! empty( $order ) && 'asc' === $order ) { $is_descending = false; } // TO DO: Allow order by meta values. if ( 'scip' === $order_by ) { $events_query->addMetaJoin(); // Since LEFT JOIN clause causes the result values to duplicate. $events_query->addCondition( 'meta.name = %s', 'ClientIP' ); // A where condition is added to make sure that we're only requesting the relevant meta data rows from metadata table. $events_query->addOrderBy( 'CASE WHEN meta.name = "ClientIP" THEN meta.value END', $is_descending ); } elseif ( 'user' === $order_by ) { $events_query->addMetaJoin(); // Since LEFT JOIN clause causes the result values to duplicate. $events_query->addCondition( 'meta.name = %s', 'CurrentUserID' ); // A where condition is added to make sure that we're only requesting the relevant meta data rows from metadata table. $events_query->addOrderBy( 'CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $is_descending ); } else { $tmp = new \WSAL\MainWPExtension\Models\Occurrence(); // Making sure the field exists to order by. if ( isset( $tmp->{$order_by} ) ) { // TODO: We used to use a custom comparator ... is it safe to let MySQL do the ordering now?. $events_query->addOrderBy( $order_by, $is_descending ); } else { $events_query->addOrderBy( 'created_on', true ); } } } $events_query->setOffset( $offset ); // Set query offset. $events_query->setLimit( $per_page ); // Set number of events per page. return array( 'total_items' => $total_items, 'per_page' => $per_page, 'items' => $events_query->getAdapter()->Execute( $events_query ), ); } /** * Method: Meta data formater. * * @param string $name - Name of the data. * @param mix $value - Value of the data. * @return string */ public function meta_formatter( $name, $value ) { switch ( true ) { case '%Message%' == $name: return esc_html( $value ); case '%PromoMessage%' == $name: return '

' . $value . '

'; case '%PromoLink%' == $name: case '%CommentLink%' == $name: case '%CommentMsg%' == $name: return $value; case '%MetaLink%' == $name: if ( ! empty( $value ) ) { return " Exclude Custom Field from the Monitoring"; } else { return ''; } case '%RevisionLink%' === $name: $check_value = (string) $value; if ( 'NULL' !== $check_value ) { return ' Click here to see the content changes.'; } else { return false; } case '%EditorLinkPost%' == $name: return ' View the post'; case '%EditorLinkPage%' == $name: return ' View the page'; case '%CategoryLink%' == $name: return ' View the category'; case '%TagLink%' == $name: return ' View the tag'; case '%EditorLinkForum%' == $name: return ' View the forum'; case '%EditorLinkTopic%' == $name: return ' View the topic'; case in_array( $name, array( '%MetaValue%', '%MetaValueOld%', '%MetaValueNew%' ) ): return '' . ( strlen( $value ) > 50 ? ( esc_html( substr( $value, 0, 50 ) ) . '…' ) : esc_html( $value ) ) . ''; case '%ClientIP%' == $name: if ( is_string( $value ) ) { return '' . str_replace( array( '"', '[', ']' ), '', $value ) . ''; } else { return 'unknown'; } case '%LinkFile%' === $name: if ( 'NULL' != $value ) { $site_id = $this->activity_log->settings->get_view_site_id(); // Site id for multisite. return '' . esc_html__( 'Download the log file', 'mwp-al-ext' ) . ''; } else { return 'Click here to log such requests to file'; } case '%URL%' === $name: return ' or exclude this URL from being reported.'; case '%LogFileLink%' === $name: // Failed login file link. return ''; case '%Attempts%' === $name: // Failed login attempts. $check_value = (int) $value; if ( 0 === $check_value ) { return ''; } else { return $value; } case '%LogFileText%' === $name: // Failed login file text. return '' . esc_html__( 'Download the log file.', 'mwp-al-ext' ) . ''; case strncmp( $value, 'http://', 7 ) === 0: case strncmp( $value, 'https://', 7 ) === 0: return '' . esc_html( $value ) . ''; case '%PostStatus%' === $name: if ( ! empty( $value ) && 'publish' === $value ) { return '' . esc_html__( 'published', 'mwp-al-ext' ) . ''; } else { return '' . esc_html( $value ) . ''; } case '%multisite_text%' === $name: if ( $this->is_multisite() && $value ) { $site_info = get_blog_details( $value, true ); if ( $site_info ) { return ' on site ' . esc_html( $site_info->blogname ) . ''; } return; } return; case '%ReportText%' === $name: return; case '%ChangeText%' === $name: $url = admin_url( 'admin-ajax.php' ) . '?action=AjaxInspector&occurrence=' . $this->current_alert_id; return ' View the changes in data inspector.'; case '%ScanError%' === $name: if ( 'NULL' === $value ) { return false; } /* translators: Mailto link for support. */ return ' with errors. ' . sprintf( __( 'Contact us on %s for assistance', 'mwp-al-ext' ), 'support@wpsecurityauditlog.com' ); case '%TableNames%' === $name: $value = str_replace( ',', ', ', $value ); return '' . esc_html( $value ) . ''; case '%FileSettings%' === $name: $file_settings_args = array( 'page' => 'wsal-settings', 'tab' => 'file-changes', ); $file_settings = add_query_arg( $file_settings_args, admin_url( 'admin.php' ) ); return '' . esc_html__( 'plugin settings', 'mwp-al-ext' ) . ''; case '%ContactSupport%' === $name: return '' . esc_html__( 'contact our support', 'mwp-al-ext' ) . ''; default: return '' . esc_html( $value ) . ''; } } }