diff --git a/classes/AuditLogListView.php b/classes/AuditLogListView.php index 30c36f57..6581512f 100644 --- a/classes/AuditLogListView.php +++ b/classes/AuditLogListView.php @@ -27,7 +27,7 @@ class WSAL_AuditLogListView extends WP_List_Table { /** * Instance of WpSecurityAuditLog. * - * @var object + * @var WpSecurityAuditLog */ protected $_plugin; @@ -51,6 +51,8 @@ class WSAL_AuditLogListView extends WP_List_Table { /** * Selected Columns. * + * @since 3.3.1 + * * @var array() */ private $selected_columns = ''; @@ -58,19 +60,31 @@ class WSAL_AuditLogListView extends WP_List_Table { /** * Display Name Type. * + * @since 3.3.1 + * * @var string */ private $name_type = ''; /** - * Method: Constructor. + * Events Query Arguments. * - * @param object $plugin - Instance of WpSecurityAuditLog. + * @since 3.3.1.1 + * + * @var stdClass */ - public function __construct( $plugin ) { - $this->_plugin = $plugin; + private $query_args; - $timezone = $this->_plugin->settings->GetTimezone(); + /** + * Method: Constructor. + * + * @param object $plugin - Instance of WpSecurityAuditLog. + * @param stdClass $query_args - Events query arguments. + */ + public function __construct( $plugin, $query_args ) { + $this->_plugin = $plugin; + $this->query_args = $query_args; + $timezone = $this->_plugin->settings->GetTimezone(); /** * Transform timezone values. @@ -145,73 +159,86 @@ protected function display_tablenav( $which ) { */ public function extra_tablenav( $which ) { // If the position is not top then render. - if ( 'top' !== $which ) : + if ( 'top' !== $which && ! $this->_plugin->settings->is_infinite_scroll() ) : // Items-per-page widget. $p = $this->_plugin->settings->GetViewPerPage(); $items = array( 5, 10, 15, 30, 50 ); - if ( ! in_array( $p, $items ) ) { + if ( ! in_array( $p, $items, true ) ) { $items[] = $p; } ?>
is_multisite() && $this->is_main_blog() ) { - $curr = $this->get_view_site_id(); + if ( 'top' !== $which && $this->_plugin->settings->is_infinite_scroll() ) : ?> -
- get_site_count() > 15 ) { ?> - - blogname . ' (' . $curr->domain . ')' ) : 'All Sites'; ?> - - - - -
+
is_multisite() && $this->is_main_blog() ) { + if ( + ( 'top' === $which && $this->_plugin->settings->is_infinite_scroll() ) + || ! $this->_plugin->settings->is_infinite_scroll() + ) { + $curr = $this->get_view_site_id(); + ?> +
+ get_site_count() > 15 ) : ?> + + blogname . ' (' . $curr->domain . ')' ) : 'All Sites'; ?> + + + + +
+ _plugin->settings->IsArchivingEnabled() ) { - $selected = 'live'; - $selected_db = get_transient( 'wsal_wp_selected_db' ); - if ( $selected_db && 'archive' == $selected_db ) { - $selected = 'archive'; + if ( + ( 'top' === $which && $this->_plugin->settings->is_infinite_scroll() ) + || ! $this->_plugin->settings->is_infinite_scroll() + ) { + $selected = 'live'; + $selected_db = get_transient( 'wsal_wp_selected_db' ); + if ( $selected_db && 'archive' === $selected_db ) { + $selected = 'archive'; + } + ?> +
+ +
+ -
- -
- selected_columns ) ) { unset( $cols ); - $this->selected_columns = (array) json_decode( $this->selected_columns ); + $this->selected_columns = is_string( $this->selected_columns ) ? (array) json_decode( $this->selected_columns ) : $this->selected_columns; foreach ( $this->selected_columns as $key => $value ) { switch ( $key ) { case 'alert_code': @@ -579,7 +606,7 @@ public function reorder_items_int( $a, $b ) { * Method: Meta data formater. * * @param string $name - Name of the data. - * @param mixed $value - Value of the data. + * @param mix $value - Value of the data. * @return string * @deprecated 3.3 */ @@ -667,7 +694,7 @@ public function meta_formatter( $name, $value ) { return '' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . ''; case strncmp( $value, 'http://', 7 ) === 0: - case strncmp( $value, 'https://', 8 ) === 0: + case strncmp( $value, 'https://', 7 ) === 0: return '' . esc_html( $value ) . ''; case '%PostStatus%' === $name: @@ -731,10 +758,7 @@ protected function is_main_blog() { * @return bool */ protected function is_specific_view() { - // Filter $_GET array for security. - $get_array = filter_input_array( INPUT_GET ); - - return isset( $get_array['wsal-cbid'] ) && '0' != $get_array['wsal-cbid']; + return isset( $this->query_args->site_id ) && '0' != $this->query_args->site_id; } /** @@ -743,10 +767,7 @@ protected function is_specific_view() { * @return int */ protected function get_specific_view() { - // Filter $_GET array for security. - $get_array = filter_input_array( INPUT_GET ); - - return isset( $get_array['wsal-cbid'] ) ? (int) $get_array['wsal-cbid'] : 0; + return isset( $this->query_args->site_id ) ? (int) $this->query_args->site_id : 0; } /** @@ -772,85 +793,28 @@ protected function get_view_site_id() { } /** - * Method: Prepare items. + * Set Events for Audit Log Viewer. */ public function prepare_items() { - if ( $this->_plugin->settings->IsArchivingEnabled() ) { - // Switch to Archive DB. - $selected_db = get_transient( 'wsal_wp_selected_db' ); - if ( $selected_db && 'archive' == $selected_db ) { - $this->_plugin->settings->SwitchToArchiveDB(); - } - } - - $per_page = $this->_plugin->settings->GetViewPerPage(); - - $columns = $this->get_columns(); - $hidden = array(); - $sortable = $this->get_sortable_columns(); - + $columns = $this->get_columns(); + $hidden = array(); + $sortable = $this->get_sortable_columns(); $this->_column_headers = array( $columns, $hidden, $sortable ); - // $this->process_bulk_action(); - // TO DO: Get rid of OccurrenceQuery and use the Occurence Model. - $query = new WSAL_Models_OccurrenceQuery(); - - $bid = (int) $this->get_view_site_id(); - if ( $bid ) { - $query->addCondition( 'site_id = %s ', $bid ); + $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->_plugin->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 = apply_filters( 'wsal_auditlog_query', $query ); - - $total_items = $query->getAdapter()->Count( $query ); - - // Filter $_GET and $_POST arrays for security. - $get_array = filter_input_array( INPUT_GET ); - - if ( empty( $get_array['orderby'] ) ) { - $query->addOrderBy( 'created_on', true ); - } else { - $order_by_field = $get_array['orderby']; - - $is_descending = true; - if ( ! empty( $get_array['order'] ) && 'asc' == $get_array['order'] ) { - $is_descending = false; - } - - // TO DO: Allow order by meta values. - if ( 'scip' == $order_by_field ) { - $query->addMetaJoin(); // Since LEFT JOIN clause causes the result values to duplicate. - $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. - $query->addOrderBy( 'CASE WHEN meta.name = "ClientIP" THEN meta.value END', $is_descending ); - } elseif ( 'user' == $order_by_field ) { - $query->addMetaJoin(); // Since LEFT JOIN clause causes the result values to duplicate. - $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. - $query->addOrderBy( 'CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $is_descending ); - } else { - $tmp = new WSAL_Models_Occurrence(); - // Making sure the field exists to order by. - if ( isset( $tmp->{$order_by_field} ) ) { - // TODO: We used to use a custom comparator ... is it safe to let MySQL do the ordering now?. - $query->addOrderBy( $get_array['orderby'], $is_descending ); - - } else { - $query->addOrderBy( 'created_on', true ); - } - } - } - - $query->setOffset( ( $this->get_pagenum() - 1 ) * $per_page ); - $query->setLimit( $per_page ); - - $this->items = $query->getAdapter()->Execute( $query ); - - $this->set_pagination_args( - array( - 'total_items' => $total_items, - 'per_page' => $per_page, - 'total_pages' => ceil( $total_items / $per_page ), - ) - ); } /** @@ -859,7 +823,7 @@ public function prepare_items() { * @param object $item - Item. */ public function single_row( $item ) { - if ( 9999 == $item->alert_id ) { + if ( 9999 === $item->alert_id ) { echo ''; $this->single_row_columns( $item ); echo ''; @@ -882,15 +846,14 @@ public function print_column_headers( $with_id = true ) { $current_url = set_url_scheme( esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ) ); $current_url = remove_query_arg( 'paged', $current_url ); - // Get $_GET global array. - $get_array = filter_input_array( INPUT_GET ); - if ( isset( $get_array['orderby'] ) ) { - $current_orderby = sanitize_text_field( $get_array['orderby'] ); + // Set order by query arg. + if ( isset( $this->query_args->order_by ) ) { + $current_orderby = $this->query_args->order_by; } else { $current_orderby = ''; } - if ( isset( $get_array['order'] ) && 'desc' === $get_array['order'] ) { + if ( isset( $this->query_args->order ) && 'desc' === $this->query_args->order ) { $current_order = 'desc'; } else { $current_order = 'asc'; @@ -898,7 +861,7 @@ public function print_column_headers( $with_id = true ) { if ( ! empty( $columns['cb'] ) ) { static $cb_counter = 1; - $columns['cb'] = '' + $columns['cb'] = '' . ''; $cb_counter++; } @@ -971,6 +934,94 @@ public function print_column_headers( $with_id = true ) { * @return int */ public function get_total_items() { - return $this->_pagination_args['total_items']; + return isset( $this->_pagination_args['total_items'] ) ? $this->_pagination_args['total_items'] : false; + } + + /** + * Query Events from WSAL DB. + * + * @since 3.3.1.1 + * + * @param integer $paged - Page number. + * @return array + */ + public function query_events( $paged = 0 ) { + if ( $this->_plugin->settings->IsArchivingEnabled() ) { + // Switch to Archive DB. + $selected_db = get_transient( 'wsal_wp_selected_db' ); + if ( $selected_db && 'archive' === $selected_db ) { + $this->_plugin->settings->SwitchToArchiveDB(); + } + } + + // TO DO: Get rid of OccurrenceQuery and use the Occurence Model. + $query = new WSAL_Models_OccurrenceQuery(); + + $bid = (int) $this->query_args->site_id; + if ( $bid ) { + $query->addCondition( 'site_id = %s ', $bid ); + } + + /** + * Hook: `wsal_auditlog_query` + * + * This hook is used to filter events query object. + * It is used to support search by filters. + * + * @see WSAL_SearchExtension()->__construct() + * @param WSAL_Models_OccurrenceQuery $query - Audit log events query object. + */ + $query = apply_filters( 'wsal_auditlog_query', $query ); + + if ( ! $this->_plugin->settings->is_infinite_scroll() ) { + $total_items = $query->getAdapter()->Count( $query ); + $per_page = $this->_plugin->settings->GetViewPerPage(); + $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 ) { + $query->addOrderBy( 'created_on', true ); + } else { + $is_descending = true; + if ( $order && 'asc' === $order ) { + $is_descending = false; + } + + // TO DO: Allow order by meta values. + if ( 'scip' === $order_by ) { + $query->addMetaJoin(); // Since LEFT JOIN clause causes the result values to duplicate. + $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. + $query->addOrderBy( 'CASE WHEN meta.name = "ClientIP" THEN meta.value END', $is_descending ); + } elseif ( 'user' === $order_by ) { + $query->addMetaJoin(); // Since LEFT JOIN clause causes the result values to duplicate. + $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. + $query->addOrderBy( 'CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $is_descending ); + } else { + $tmp = new WSAL_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?. + $query->addOrderBy( $order_by, $is_descending ); + } else { + $query->addOrderBy( 'created_on', true ); + } + } + } + + $query->setOffset( $offset ); // Set query offset. + $query->setLimit( $per_page ); // Set number of events per page. + return array( + 'total_items' => $total_items, + 'per_page' => $per_page, + 'items' => $query->getAdapter()->Execute( $query ), + ); } } diff --git a/classes/Sensors/Database.php b/classes/Sensors/Database.php index 325f8a04..22804bae 100644 --- a/classes/Sensors/Database.php +++ b/classes/Sensors/Database.php @@ -45,8 +45,9 @@ public function HookEvents() { * @param WP_Query $query - Query object. */ public function EventDropQuery( $query ) { + global $wpdb; $table_names = array(); - $str = explode( ' ', $query ); + $str = explode( ' ', $query ); if ( preg_match( '|DROP TABLE ([^ ]*)|', $query ) ) { if ( ! empty( $str[4] ) ) { @@ -55,15 +56,25 @@ public function EventDropQuery( $query ) { array_push( $table_names, $str[2] ); } - // Filter $_SERVER array for security. - $server_array = filter_input_array( INPUT_SERVER ); - - $actype = ( isset( $server_array['SCRIPT_NAME'] ) ) ? basename( $server_array['SCRIPT_NAME'], '.php' ) : false; + $actype = isset( $_SERVER['SCRIPT_NAME'] ) ? basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ), '.php' ) : false; $alert_options = $this->GetActionType( $actype ); + $type_query = 'delete'; + } elseif ( preg_match( '|CREATE TABLE IF NOT EXISTS ([^ ]*)|', $query ) ) { + if ( $str[5] !== $wpdb->get_var( "SHOW TABLES LIKE '" . $str[5] . "'" ) ) { + /** + * Some plugins keep trying to create tables even + * when they already exist- would result in too + * many alerts. + */ + array_push( $table_names, $str[5] ); + $actype = isset( $_SERVER['SCRIPT_NAME'] ) ? basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ), '.php' ) : false; + $alert_options = $this->GetActionType( $actype ); + $type_query = 'create'; + } } if ( ! empty( $table_names ) ) { - $event_code = $this->GetEventQueryType( $actype, 'delete' ); + $event_code = $this->GetEventQueryType( $actype, $type_query ); $alert_options['TableNames'] = implode( ',', $table_names ); $this->plugin->alerts->Trigger( $event_code, $alert_options ); } @@ -106,21 +117,17 @@ public function EventDBDeltaQuery( $queries ) { } if ( ! empty( $type_queries['create'] ) || ! empty( $type_queries['update'] ) || ! empty( $type_queries['delete'] ) ) { - // Filter $_SERVER array for security. - $server_array = filter_input_array( INPUT_SERVER ); - - $actype = ( isset( $server_array['SCRIPT_NAME'] ) ) ? basename( $server_array['SCRIPT_NAME'], '.php' ) : false; + $actype = isset( $_SERVER['SCRIPT_NAME'] ) ? basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ), '.php' ) : false; $alert_options = $this->GetActionType( $actype ); foreach ( $type_queries as $query_type => $table_names ) { if ( ! empty( $table_names ) ) { - $event_code = $this->GetEventQueryType( $actype, $query_type ); + $event_code = $this->GetEventQueryType( $actype, $query_type ); $alert_options['TableNames'] = implode( ',', $table_names ); $this->plugin->alerts->Trigger( $event_code, $alert_options ); } } } - return $queries; } @@ -133,29 +140,29 @@ public function EventDBDeltaQuery( $queries ) { protected function GetEventQueryType( $type_action, $type_query ) { switch ( $type_action ) { case 'plugins': - if ( 'create' == $type_query ) { + if ( 'create' === $type_query ) { return 5010; - } elseif ( 'update' == $type_query ) { + } elseif ( 'update' === $type_query ) { return 5011; - } elseif ( 'delete' == $type_query ) { + } elseif ( 'delete' === $type_query ) { return 5012; } // In case of plugins. case 'themes': - if ( 'create' == $type_query ) { + if ( 'create' === $type_query ) { return 5013; - } elseif ( 'update' == $type_query ) { + } elseif ( 'update' === $type_query ) { return 5014; - } elseif ( 'delete' == $type_query ) { + } elseif ( 'delete' === $type_query ) { return 5015; } // In case of themes. default: - if ( 'create' == $type_query ) { + if ( 'create' === $type_query ) { return 5016; - } elseif ( 'update' == $type_query ) { + } elseif ( 'update' === $type_query ) { return 5017; - } elseif ( 'delete' == $type_query ) { + } elseif ( 'delete' === $type_query ) { return 5018; } } @@ -167,45 +174,58 @@ protected function GetEventQueryType( $type_action, $type_query ) { * @param string $actype - Plugins, themes or unknown. */ protected function GetActionType( $actype ) { - // Filter $_GET array for security. - $get_array = filter_input_array( INPUT_GET ); - - $is_themes = 'themes' == $actype; - $is_plugins = 'plugins' == $actype; + // Check the component type (theme or plugin). + $is_themes = 'themes' === $actype; + $is_plugins = 'plugins' === $actype; // Action Plugin Component. $alert_options = array(); if ( $is_plugins ) { $plugin_file = ''; - if ( isset( $get_array['plugin'] ) ) { - $plugin_file = $get_array['plugin']; - } elseif ( isset( $get_array['checked'] ) ) { - $plugin_file = $get_array['checked'][0]; + // @codingStandardsIgnoreStart + if ( isset( $_GET['plugin'] ) ) { + $plugin_file = sanitize_text_field( wp_unslash( $_GET['plugin'] ) ); + } elseif ( isset( $_GET['checked'] ) ) { + $plugin_file = sanitize_text_field( wp_unslash( $_GET['checked'][0] ) ); + } + // @codingStandardsIgnoreEnd + + // Get plugin data. + $plugins = get_plugins(); + if ( isset( $plugins[ $plugin_file ] ) ) { + $plugin = $plugins[ $plugin_file ]; + + // Set alert options. + $alert_options['Plugin'] = (object) array( + 'Name' => $plugin['Name'], + 'PluginURI' => $plugin['PluginURI'], + 'Version' => $plugin['Version'], + ); + } else { + $plugin_name = basename( $plugin_file, '.php' ); + $plugin_name = str_replace( array( '_', '-', ' ' ), ' ', $plugin_name ); + $plugin_name = ucwords( $plugin_name ); + $alert_options['Plugin'] = (object) array( 'Name' => $plugin_name ); } - $plugin_name = basename( $plugin_file, '.php' ); - $plugin_name = str_replace( array( '_', '-', ' ' ), ' ', $plugin_name ); - $plugin_name = ucwords( $plugin_name ); - $alert_options['Plugin'] = (object) array( - 'Name' => $plugin_name, - ); - // Action Theme Component. } elseif ( $is_themes ) { + // Action Theme Component. $theme_name = ''; - if ( isset( $get_array['theme'] ) ) { - $theme_name = $get_array['theme']; - } elseif ( isset( $get_array['checked'] ) ) { - $theme_name = $get_array['checked'][0]; + + // @codingStandardsIgnoreStart + if ( isset( $_GET['theme'] ) ) { + $theme_name = sanitize_text_field( wp_unslash( $_GET['theme'] ) ); + } elseif ( isset( $_GET['checked'] ) ) { + $theme_name = sanitize_text_field( wp_unslash( $_GET['checked'][0] ) ); } - $theme_name = str_replace( array( '_', '-', ' ' ), ' ', $theme_name ); - $theme_name = ucwords( $theme_name ); - $alert_options['Theme'] = (object) array( - 'Name' => $theme_name, - ); - // Action Unknown Component. + // @codingStandardsIgnoreEnd + + $theme_name = str_replace( array( '_', '-', ' ' ), ' ', $theme_name ); + $theme_name = ucwords( $theme_name ); + $alert_options['Theme'] = (object) array( 'Name' => $theme_name ); } else { + // Action Unknown Component. $alert_options['Component'] = 'Unknown'; } - return $alert_options; } } diff --git a/classes/Sensors/PluginsThemes.php b/classes/Sensors/PluginsThemes.php index f4a0d22c..7d627865 100644 --- a/classes/Sensors/PluginsThemes.php +++ b/classes/Sensors/PluginsThemes.php @@ -557,7 +557,7 @@ public function EventPluginPostCreate( $post_id, $post ) { // Check if Yoast SEO is active. $is_yoast = is_plugin_active( 'wordpress-seo/wp-seo.php' ) || is_plugin_active( 'wordpress-seo-premium/wp-seo-premium.php' ); - if ( $is_yoast && isset( $get_array['classic-editor'] ) ) { + if ( $is_yoast ) { return; } diff --git a/classes/Sensors/WooCommerce.php b/classes/Sensors/WooCommerce.php index 1bcfd338..49a04987 100644 --- a/classes/Sensors/WooCommerce.php +++ b/classes/Sensors/WooCommerce.php @@ -2144,13 +2144,29 @@ public function event_order_status_changed( $order_id, $status_from, $status_to, $order_title = ( null !== $order_post && $order_post instanceof WP_Post ) ? $order_post->post_title : false; $order_post = get_post( $order_id ); $edit_link = $this->GetEditorLink( $order_post ); - - $this->plugin->alerts->Trigger( 9036, array( + $event_data = array( 'OrderID' => $order_id, 'OrderTitle' => $this->get_order_title( $order ), 'OrderStatus' => $status_to, $edit_link['name'] => $edit_link['value'], - ) ); + ); + $this->plugin->alerts->TriggerIf( 9036, $event_data, array( $this, 'must_not_contain_refund' ) ); + } + + /** + * Checks if event 9041 has triggered or if it will + * trigger. + * + * @since 3.3.1.1 + * + * @param WSAL_AlertManager $manager - Alert manager instance. + * @return boolean + */ + public function must_not_contain_refund( WSAL_AlertManager $manager ) { + if ( $manager->WillOrHasTriggered( 9041 ) ) { + return false; + } + return true; } /** @@ -2170,13 +2186,16 @@ private function check_order_modify_change( $order_id, $oldorder, $neworder ) { // Get editor link. $edit_link = $this->GetEditorLink( $oldorder ); - // Log event. - $this->plugin->alerts->Trigger( 9040, array( + // Set event data. + $event_data = array( 'OrderID' => $order_id, 'OrderTitle' => $this->get_order_title( $order_id ), 'OrderStatus' => $neworder->post_status, $edit_link['name'] => $edit_link['value'], - ) ); + ); + + // Log event. + $this->plugin->alerts->TriggerIf( 9040, $event_data, array( $this, 'must_not_contain_refund' ) ); } /** diff --git a/classes/Sensors/YoastSEO.php b/classes/Sensors/YoastSEO.php index cb9f5289..20d0dca6 100644 --- a/classes/Sensors/YoastSEO.php +++ b/classes/Sensors/YoastSEO.php @@ -93,7 +93,7 @@ protected function retrieve_post_data() { && ! ( isset( $post_array['action'] ) && 'autosave' === $post_array['action'] ) ) { $this->post_id = intval( $post_array['post_ID'] ); - $this->post = get_post( $this->post_id ); + $this->post = get_post( $this->post_id ); $this->set_post_seo_data(); } } @@ -104,14 +104,14 @@ protected function retrieve_post_data() { private function set_post_seo_data() { // Set post SEO meta data. $this->post_seo_data = array( - '_yoast_wpseo_title' => get_post_meta( $this->post_id, '_yoast_wpseo_title', true ), - '_yoast_wpseo_metadesc' => get_post_meta( $this->post_id, '_yoast_wpseo_metadesc', true ), - '_yoast_wpseo_focuskw' => get_post_meta( $this->post_id, '_yoast_wpseo_focuskw', true ), - '_yst_is_cornerstone' => get_post_meta( $this->post_id, '_yst_is_cornerstone', true ), - '_yoast_wpseo_meta-robots-noindex' => get_post_meta( $this->post_id, '_yoast_wpseo_meta-robots-noindex', true ), + '_yoast_wpseo_title' => get_post_meta( $this->post_id, '_yoast_wpseo_title', true ), + '_yoast_wpseo_metadesc' => get_post_meta( $this->post_id, '_yoast_wpseo_metadesc', true ), + '_yoast_wpseo_focuskw' => get_post_meta( $this->post_id, '_yoast_wpseo_focuskw', true ), + '_yst_is_cornerstone' => get_post_meta( $this->post_id, '_yst_is_cornerstone', true ), + '_yoast_wpseo_meta-robots-noindex' => get_post_meta( $this->post_id, '_yoast_wpseo_meta-robots-noindex', true ), '_yoast_wpseo_meta-robots-nofollow' => get_post_meta( $this->post_id, '_yoast_wpseo_meta-robots-nofollow', true ), - '_yoast_wpseo_meta-robots-adv' => get_post_meta( $this->post_id, '_yoast_wpseo_meta-robots-adv', true ), - '_yoast_wpseo_canonical' => get_post_meta( $this->post_id, '_yoast_wpseo_canonical', true ), + '_yoast_wpseo_meta-robots-adv' => get_post_meta( $this->post_id, '_yoast_wpseo_meta-robots-adv', true ), + '_yoast_wpseo_canonical' => get_post_meta( $this->post_id, '_yoast_wpseo_canonical', true ), ); } @@ -154,9 +154,9 @@ protected function get_post_seo_data( $key = '' ) { * @return array $editor_link - Name and value link. */ private function get_editor_link( $post_id ) { - $value = get_edit_post_link( $post_id ); + $value = get_edit_post_link( $post_id ); $editor_link = array( - 'name' => 'EditorLinkPost', + 'name' => 'EditorLinkPost', 'value' => $value, ); return $editor_link; @@ -168,19 +168,19 @@ private function get_editor_link( $post_id ) { protected function check_seo_data_change() { // Set filter input args. $filter_input_args = array( - 'post_ID' => FILTER_VALIDATE_INT, - '_wpnonce' => FILTER_SANITIZE_STRING, - 'action' => FILTER_SANITIZE_STRING, - 'yoast_wpseo_title' => FILTER_SANITIZE_STRING, - 'yoast_wpseo_metadesc' => FILTER_SANITIZE_STRING, - 'yoast_wpseo_focuskw' => FILTER_SANITIZE_STRING, - '_yst_is_cornerstone' => FILTER_VALIDATE_INT, - 'yoast_wpseo_meta-robots-noindex' => FILTER_VALIDATE_INT, + 'post_ID' => FILTER_VALIDATE_INT, + '_wpnonce' => FILTER_SANITIZE_STRING, + 'action' => FILTER_SANITIZE_STRING, + 'yoast_wpseo_title' => FILTER_SANITIZE_STRING, + 'yoast_wpseo_metadesc' => FILTER_SANITIZE_STRING, + 'yoast_wpseo_focuskw' => FILTER_SANITIZE_STRING, + '_yst_is_cornerstone' => FILTER_VALIDATE_INT, + 'yoast_wpseo_meta-robots-noindex' => FILTER_VALIDATE_INT, 'yoast_wpseo_meta-robots-nofollow' => FILTER_VALIDATE_INT, - 'yoast_wpseo_meta-robots-adv' => array( + 'yoast_wpseo_meta-robots-adv' => array( 'flags' => FILTER_REQUIRE_ARRAY, ), - 'yoast_wpseo_canonical' => FILTER_VALIDATE_URL, + 'yoast_wpseo_canonical' => FILTER_VALIDATE_URL, ); // Filter POST global array. @@ -216,21 +216,25 @@ protected function check_title_change( $title ) { return; } + // Remove whitespaces at the ends of the titles. + $old_title = trim( $old_title ); + $title = trim( $title ); + // If title is changed then log alert. if ( $old_title !== $title ) { $editor_link = $this->get_editor_link( $this->post_id ); $this->plugin->alerts->Trigger( 8801, array( - 'PostID' => $this->post->ID, - 'PostType' => $this->post->post_type, - 'PostTitle' => $this->post->post_title, - 'PostStatus' => $this->post->post_status, - 'PostDate' => $this->post->post_date, - 'PostUrl' => get_permalink( $this->post->ID ), - 'OldSEOTitle' => $old_title, - 'NewSEOTitle' => $title, + 'PostID' => $this->post->ID, + 'PostType' => $this->post->post_type, + 'PostTitle' => $this->post->post_title, + 'PostStatus' => $this->post->post_status, + 'PostDate' => $this->post->post_date, + 'PostUrl' => get_permalink( $this->post->ID ), + 'OldSEOTitle' => $old_title, + 'NewSEOTitle' => $title, $editor_link['name'] => $editor_link['value'], - 'ReportText' => $old_title . '|' . $title, + 'ReportText' => $old_title . '|' . $title, ) ); } @@ -243,7 +247,8 @@ protected function check_title_change( $title ) { */ protected function check_desc_change( $desc ) { // Get old desc value. - $old_desc = $this->get_post_seo_data( 'metadesc' ); + $old_desc = esc_html( $this->get_post_seo_data( 'metadesc' ) ); + $desc = esc_html( $desc ); // If old and new values are empty then don't log the alert. if ( empty( $old_desc ) && empty( $desc ) ) { @@ -255,16 +260,16 @@ protected function check_desc_change( $desc ) { $editor_link = $this->get_editor_link( $this->post_id ); $this->plugin->alerts->Trigger( 8802, array( - 'PostID' => $this->post->ID, - 'PostType' => $this->post->post_type, - 'PostTitle' => $this->post->post_title, - 'PostStatus' => $this->post->post_status, - 'PostDate' => $this->post->post_date, - 'PostUrl' => get_permalink( $this->post->ID ), - 'old_desc' => $old_desc, - 'new_desc' => $desc, + 'PostID' => $this->post->ID, + 'PostType' => $this->post->post_type, + 'PostTitle' => $this->post->post_title, + 'PostStatus' => $this->post->post_status, + 'PostDate' => $this->post->post_date, + 'PostUrl' => get_permalink( $this->post->ID ), + 'old_desc' => $old_desc, + 'new_desc' => $desc, $editor_link['name'] => $editor_link['value'], - 'ReportText' => $old_desc . '|' . $desc, + 'ReportText' => $old_desc . '|' . $desc, ) ); } @@ -794,4 +799,3 @@ private function yoast_setting_switch_alert( $key, $new_value ) { } } } - diff --git a/classes/Settings.php b/classes/Settings.php index 44e9f53c..10b654a9 100644 --- a/classes/Settings.php +++ b/classes/Settings.php @@ -1917,4 +1917,44 @@ public function slack_meta_formatter( $name, $value, $occ_id, $highlight ) { return '*' . esc_html( $value ) . '*'; } } + + /** + * Checks Infinite Scroll. + * + * Returns true if infinite scroll is enabled. + * + * @since 3.3.1.1 + * + * @return boolean + */ + public function is_infinite_scroll() { + return 'infinite-scroll' === $this->get_events_type_nav() ? true : false; + } + + /** + * Checks Events Navigation Type. + * + * Returns type of navigation for events log viewer. + * + * @since 3.3.1.1 + * + * @return string + */ + public function get_events_type_nav() { + return $this->_plugin->GetGlobalOption( 'events-nav-type', 'infinite-scroll' ); + } + + /** + * Sets Events Navigation Type. + * + * Sets type of navigation for events log viewer. + * + * @since 3.3.1.1 + * + * @param string $nav_type - Navigation type. + * @return string + */ + public function set_events_type_nav( $nav_type ) { + $this->_plugin->SetGlobalOption( 'events-nav-type', $nav_type ); + } } diff --git a/classes/Views/AuditLog.php b/classes/Views/AuditLog.php index 41b3a6b5..cd2e80c4 100644 --- a/classes/Views/AuditLog.php +++ b/classes/Views/AuditLog.php @@ -45,6 +45,15 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView { */ private $adverts; + /** + * Audit Log View Arguments. + * + * @since 3.3.1.1 + * + * @var stdClass + */ + private $page_args; + /** * Method: Constructor * @@ -69,6 +78,10 @@ public function __construct( WpSecurityAuditLog $plugin ) { add_filter( 'wsal_pointers_toplevel_page_wsal-auditlog', array( $this, 'register_privacy_pointer' ), 10, 1 ); add_action( 'admin_init', array( $this, 'handle_form_submission' ) ); + if ( $this->_plugin->settings->is_infinite_scroll() ) { + add_action( 'wp_ajax_wsal_infinite_scroll_events', array( $this, 'infinite_scroll_events' ) ); + } + // Check plugin version for to dismiss the notice only until upgrade. $this->_version = WSAL_VERSION; @@ -270,8 +283,27 @@ public function GetWeight() { * Method: Get View. */ protected function GetListView() { + // Set page arguments. + if ( ! $this->page_args ) { + $this->page_args = new stdClass(); + + // @codingStandardsIgnoreStart + $this->page_args->page = isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : false; + $this->page_args->site_id = isset( $_REQUEST['wsal-cbid'] ) ? (int) sanitize_text_field( wp_unslash( $_REQUEST['wsal-cbid'] ) ) : false; + + // Order arguments. + $this->page_args->order_by = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : false; + $this->page_args->order = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : false; + + // Search arguments. + $this->page_args->search_term = ( isset( $_REQUEST['s'] ) && ! empty( $_REQUEST['s'] ) ) ? trim( sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) ) : false; + $this->page_args->search_filters = ( isset( $_REQUEST['filters'] ) && is_array( $_REQUEST['filters'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['filters'] ) ) : false; + // @codingStandardsIgnoreEnd + } + + // Set events listing view class. if ( is_null( $this->_listview ) ) { - $this->_listview = new WSAL_AuditLogListView( $this->_plugin ); + $this->_listview = new WSAL_AuditLogListView( $this->_plugin, $this->page_args ); } return $this->_listview; } @@ -345,23 +377,34 @@ public function Render() { check_admin_referer( 'bulk-logs' ); } - // @codingStandardsIgnoreStart - $wsal_page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : false; // Admin WSAL Page. - $site_id = isset( $_GET['wsal-cbid'] ) ? (int) sanitize_text_field( $_GET['wsal-cbid'] ) : false; // Site id. - $search_term = ( isset( $_REQUEST['s'] ) && ! empty( $_REQUEST['s'] ) ) ? trim( sanitize_text_field( $_REQUEST['s'] ) ) : false; - $search_filters = ( isset( $_REQUEST['Filters'] ) && is_array( $_REQUEST['Filters'] ) ) ? array_map( 'sanitize_text_field', $_REQUEST['Filters'] ) : false; - // @codingStandardsIgnoreEnd - $this->GetListView()->prepare_items(); - ?>
- - - GetListView() ); ?> - GetListView()->display(); ?> - GetListView() ); ?> + + + _listview - Audit log list view object. + */ + do_action( 'wsal_auditlog_before_view', $this->GetListView() ); + + // Display the audit log list. + $this->GetListView()->display(); + + /** + * Hook: `wsal_auditlog_after_view` + * + * This action hook is triggered after displaying the audit log view. + * + * @param WSAL_AuditLogListView $this->_listview - Audit log list view object. + */ + do_action( 'wsal_auditlog_after_view', $this->GetListView() ); + ?>
@@ -403,7 +446,7 @@ public function Render() { page_args->search_filters ) || ( ! empty( $this->page_args->search_term ) && trim( $this->page_args->search_term ) ) ) ) : ?>