Linux webm002.cluster126.gra.hosting.ovh.net 6.18.39-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Tue Jul 21 12:03:15 CEST 2026 x86_64
/
home
/
ariannadhf
/
www
/
wp-content
/
plugins
/
simple-history
/
loggers
/
/home/ariannadhf/www/wp-content/plugins/simple-history/loggers/class-available-updates-logger.php
<?php namespace Simple_History\Loggers; use Simple_History\Event_Details\Event_Details_Container; use Simple_History\Event_Details\Event_Details_Group; use Simple_History\Event_Details\Event_Details_Group_Inline_Formatter; use Simple_History\Event_Details\Event_Details_Group_Table_Formatter; use Simple_History\Event_Details\Event_Details_Item; use Simple_History\Log_Initiators; /** * Logs available updates to themes, plugins and WordPress core * * @package SimpleHistory */ class Available_Updates_Logger extends Logger { /** @var string Logger slug */ public $slug = 'AvailableUpdatesLogger'; /** * Return logger info * * @return array */ public function get_info() { return array( 'name' => _x( 'Available Updates Logger', 'AvailableUpdatesLogger', 'simple-history' ), 'type' => 'core', 'description' => __( 'Logs found updates to WordPress, plugins, and themes', 'simple-history' ), 'capability' => 'manage_options', 'messages' => array( 'core_update_available' => __( 'Found an update to WordPress', 'simple-history' ), 'plugin_update_available' => __( 'Found an update to plugin "{plugin_name}"', 'simple-history' ), 'theme_update_available' => __( 'Found an update to theme "{theme_name}"', 'simple-history' ), ), 'labels' => array( 'search' => array( 'label' => _x( 'WordPress and plugins updates found', 'Plugin logger: updates found', 'simple-history' ), 'label_all' => _x( 'All found updates', 'Plugin logger: updates found', 'simple-history' ), 'options' => array( _x( 'WordPress updates found', 'Plugin logger: updates found', 'simple-history' ) => array( 'core_update_available', ), _x( 'Plugin updates found', 'Plugin logger: updates found', 'simple-history' ) => array( 'plugin_update_available', ), _x( 'Theme updates found', 'Plugin logger: updates found', 'simple-history' ) => array( 'theme_update_available', ), ), ), // search array. ), // labels. ); } /** * Called when logger is loaded. */ public function loaded() { // When WP is done checking for core updates it sets a site transient called "update_core". add_action( 'set_site_transient_update_core', array( $this, 'on_setted_update_core_transient' ), 10, 1 ); // Ditto for plugins. add_action( 'set_site_transient_update_plugins', array( $this, 'on_setted_update_plugins_transient' ), 10, 1 ); add_action( 'set_site_transient_update_themes', array( $this, 'on_setted_update_update_themes' ), 10, 1 ); } /** * Called when WordPress is done checking for core updates. * WP sets site transient 'update_core' when done. * Log found core update. * * @param object $updates Updates object. */ public function on_setted_update_core_transient( $updates ) { global $wp_version; $last_version_checked = get_option( "simplehistory_{$this->get_slug()}_wp_core_version_available" ); // During update of network sites this was not set, so make sure to check. if ( empty( $updates->updates[0]->current ) ) { return; } $new_wp_core_version = $updates->updates[0]->current; // The new WP core version. // Some plugins can mess with version, so get fresh from the version file. require_once ABSPATH . WPINC . '/version.php'; // If found version is same version as we have logged about before then don't continue. if ( $last_version_checked === $new_wp_core_version ) { return; } // is WP core update available? if ( ! isset( $updates->updates[0]->response ) || $updates->updates[0]->response !== 'upgrade' ) { return; } $this->notice_message( 'core_update_available', array( 'wp_core_current_version' => $wp_version, 'wp_core_new_version' => $new_wp_core_version, '_initiator' => Log_Initiators::WORDPRESS, ) ); // Store updated version available, so we don't log that version again. // Autoload disabled since this option is only accessed during update checks. update_option( "simplehistory_{$this->get_slug()}_wp_core_version_available", $new_wp_core_version, false ); } /** * Called when WordPress is done checking for plugin updates. * WP sets site transient 'update_plugins' when done. * Log found plugin updates. * * @param object $updates Updates object. */ public function on_setted_update_plugins_transient( $updates ) { if ( empty( $updates->response ) || ! is_array( $updates->response ) ) { return; } $option_key = "simplehistory_{$this->get_slug()}_plugin_updates_available"; $checked_updates = get_option( $option_key ); if ( ! is_array( $checked_updates ) ) { $checked_updates = array(); } // File needed plugin API. if ( ! function_exists( 'get_plugin_data' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } // For each available update. foreach ( $updates->response as $key => $data ) { // Make sure plugin directory exists or get_plugin_data will give warning. $file = WP_PLUGIN_DIR . '/' . $key; // Continue with next plugin if plugin file did not exist. if ( ! is_file( $file ) ) { continue; } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen $fp = fopen( $file, 'r' ); // Continue with next plugin if plugin file could not be read. if ( $fp === false ) { continue; } $plugin_info = get_plugin_data( $file, true, false ); $plugin_new_version = $data->new_version ?? ''; // Check if this plugin and this version has been checked/logged already. if ( ! array_key_exists( $key, $checked_updates ) ) { $checked_updates[ $key ] = array( 'checked_version' => null, ); } if ( $checked_updates[ $key ]['checked_version'] === $plugin_new_version ) { // This version has been checked/logged already. continue; } $checked_updates[ $key ]['checked_version'] = $plugin_new_version; $context = array( 'plugin_name' => $plugin_info['Name'] ?? '', 'plugin_slug' => $data->slug ?? '', 'plugin_current_version' => $plugin_info['Version'] ?? '', 'plugin_new_version' => $plugin_new_version, '_initiator' => Log_Initiators::WORDPRESS, ); // Add autoupdate flag if present (indicates forced security update). if ( ! empty( $data->autoupdate ) ) { $context['plugin_autoupdate'] = '1'; } // Add upgrade notice if present. if ( ! empty( $data->upgrade_notice ) ) { $context['plugin_upgrade_notice'] = $data->upgrade_notice; } $this->notice_message( 'plugin_update_available', $context ); } // Autoload disabled since this option is only accessed during update checks. update_option( $option_key, $checked_updates, false ); } /** * Called when WordPress is done checking for theme updates. * WP sets site transient 'update_themes' when done. * Log found theme updates. * * @param object $updates Updates object. */ public function on_setted_update_update_themes( $updates ) { if ( empty( $updates->response ) || ! is_array( $updates->response ) ) { return; } $option_key = "simplehistory_{$this->get_slug()}_theme_updates_available"; $checked_updates = get_option( $option_key ); if ( ! is_array( $checked_updates ) ) { $checked_updates = array(); } // For each available update. foreach ( $updates->response as $key => $data ) { $theme_info = wp_get_theme( $key ); $theme_new_version = $data['new_version'] ?? ''; // check if this plugin and this version has been checked/logged already. if ( ! array_key_exists( $key, $checked_updates ) ) { $checked_updates[ $key ] = array( 'checked_version' => null, ); } if ( $checked_updates[ $key ]['checked_version'] === $theme_new_version ) { // This version has been checked/logged already. continue; } $checked_updates[ $key ]['checked_version'] = $theme_new_version; $this->notice_message( 'theme_update_available', array( 'theme_name' => $theme_info['Name'] ?? '', 'theme_current_version' => $theme_info['Version'] ?? '', 'theme_new_version' => $theme_new_version, '_initiator' => Log_Initiators::WORDPRESS, ) ); } // Autoload disabled since this option is only accessed during update checks. update_option( $option_key, $checked_updates, false ); } /** * Append prev and current version of update object as details in the output * * @param object $row Log row. * @return Event_Details_Group|Event_Details_Container|string */ public function get_log_row_details_output( $row ) { $context_message_key = $row->context_message_key ?? null; $context = $row->context ?? array(); $current_version = null; $new_version = null; $groups = []; switch ( $context_message_key ) { case 'core_update_available': $current_version = $context['wp_core_current_version'] ?? null; $new_version = $context['wp_core_new_version'] ?? null; break; case 'plugin_update_available': $current_version = $context['plugin_current_version'] ?? null; $new_version = $context['plugin_new_version'] ?? null; // Security auto-update notice. if ( ! empty( $context['plugin_autoupdate'] ) ) { $security_group = ( new Event_Details_Group() ) ->set_formatter( new Event_Details_Group_Table_Formatter() ) ->add_item( ( new Event_Details_Item( null, _x( 'Security auto-update', 'Available updates logger: forced update indicator', 'simple-history' ) ) )->set_new_value( __( 'This update will be installed automatically by WordPress.', 'simple-history' ) ) ); $groups[] = $security_group; } // Upgrade notice. if ( ! empty( $context['plugin_upgrade_notice'] ) ) { $upgrade_notice = wp_strip_all_tags( $context['plugin_upgrade_notice'] ); $upgrade_notice = wp_trim_words( $upgrade_notice, 30, '…' ); $notice_group = ( new Event_Details_Group() ) ->set_formatter( new Event_Details_Group_Table_Formatter() ) ->add_item( ( new Event_Details_Item( null, _x( 'Update notice', 'Available updates logger: update notice label', 'simple-history' ) ) )->set_new_value( $upgrade_notice ) ); $groups[] = $notice_group; } break; case 'theme_update_available': $current_version = $context['theme_current_version'] ?? null; $new_version = $context['theme_new_version'] ?? null; break; } // Version info as inline group. if ( $current_version && $new_version ) { $version_group = ( new Event_Details_Group() ) ->set_formatter( new Event_Details_Group_Inline_Formatter() ) ->add_items( [ ( new Event_Details_Item( null, __( 'Available version', 'simple-history' ) ) ) ->set_new_value( $new_version ), ( new Event_Details_Item( null, __( 'Installed version', 'simple-history' ) ) ) ->set_new_value( $current_version ), ] ); $groups[] = $version_group; } if ( empty( $groups ) ) { return ''; } return Event_Details_Container::create_from( $groups ); } /** * Get action links for a log row. * * @param object $row Log row object. * @return array Array of action link arrays. */ public function get_action_links( $row ) { $is_allowed_to_update_page = current_user_can( 'update_core' ) || current_user_can( 'update_themes' ) || current_user_can( 'update_plugins' ); if ( ! $is_allowed_to_update_page ) { return []; } $action_links = [ [ 'url' => admin_url( 'update-core.php' ), 'label' => __( 'View all updates', 'simple-history' ), 'action' => 'view', ], ]; // Add "View changelog" for plugin updates with a known slug. $context = $row->context; $message_key = $context['_message_key'] ?? ''; $plugin_slug = $context['plugin_slug'] ?? ''; if ( $message_key === 'plugin_update_available' && $plugin_slug ) { $url = is_multisite() ? network_admin_url( "plugin-install.php?tab=plugin-information&plugin={$plugin_slug}§ion=changelog&TB_iframe=true&width=772&height=550" ) : admin_url( "plugin-install.php?tab=plugin-information&plugin={$plugin_slug}§ion=changelog&TB_iframe=true&width=772&height=550" ); // Prepend so changelog appears before "View all updates". array_unshift( $action_links, [ 'url' => $url, 'label' => _x( 'View changelog', 'Available updates logger: changelog link', 'simple-history' ), 'action' => 'edit', ] ); } return $action_links; } }