# desktop-mode/1.1.10/includes/core-notices.php

OpenStation: Desktop Windows, Dock &amp; Virtual Desktops for WP Admin, version 1.1.10. 238 lines.

- Page: https://pluginprobe.com/plugins/desktop-mode/1.1.10/code/includes/core-notices.php
- Raw: https://pluginprobe.com/plugins/desktop-mode/1.1.10/raw/includes/core-notices.php
- Modified: 2026-08-07T20:39:04+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/desktop-mode/1.1.10/code/includes/core-notices.php#L10-L20`.

```php
<?php
/**
 * Re-derives WordPress Core's *global* admin notices — the ones that would
 * otherwise repeat in every desktop window — into shell descriptors, so the
 * shell can surface each once. The update nag is handled separately (see
 * update-notice.php); this covers the rest.
 *
 * @package OpenStation
 */

defined( 'ABSPATH' ) || exit;

/**
 * The in-scope global core notices for the current user, as shell
 * descriptors. Each descriptor is `{ id, title, message, actionLabel?,
 * actionUrl? }`, re-derived from authoritative state (never scraped) and
 * capability-gated exactly as Core gates the underlying notice. The shell
 * renders each as a persistent, dismissible toast.
 *
 * @return array<int,array{id:string,title:string,message:string,actionLabel:string,actionUrl:string}>
 */
function openstation_get_core_notices() {
	$builders = array(
		'openstation_core_notice_maintenance',
		'openstation_core_notice_recovery_mode',
		'openstation_core_notice_default_password',
		'openstation_core_notice_deactivated_plugins',
		'openstation_core_notice_paused_plugins',
		'openstation_core_notice_paused_themes',
	);

	$notices = array();
	foreach ( $builders as $builder ) {
		$notice = $builder();
		if ( $notice ) {
			$notices[] = $notice;
		}
	}

	/**
	 * Filters the core notices surfaced once in the desktop shell. Return an
	 * empty array to suppress them all, or unset individual entries by `id`.
	 *
	 * @param array $notices List of notice descriptors.
	 */
	return apply_filters( 'openstation_core_notices', $notices );
}

/**
 * Normalizes a notice descriptor, filling optional fields.
 *
 * @param array $notice Partial descriptor with at least `id` + `message`.
 * @return array{id:string,title:string,message:string,actionLabel:string,actionUrl:string}
 */
function openstation_core_notice( array $notice ) {
	return array(
		'id'          => (string) $notice['id'],
		'title'       => isset( $notice['title'] ) ? (string) $notice['title'] : '',
		'message'     => (string) $notice['message'],
		'actionLabel' => isset( $notice['actionLabel'] ) ? (string) $notice['actionLabel'] : '',
		'actionUrl'   => isset( $notice['actionUrl'] ) ? (string) $notice['actionUrl'] : '',
	);
}

/**
 * Interrupted / failed automated core update — mirrors `maintenance_nag()`.
 *
 * @return array|null
 */
function openstation_core_notice_maintenance() {
	$nag = isset( $GLOBALS['upgrading'] );

	if ( ! $nag ) {
		$failed     = get_site_option( 'auto_core_update_failed' );
		$comparison = ! empty( $failed['critical'] ) ? '>=' : '>';
		if ( isset( $failed['attempted'] )
			&& version_compare( $failed['attempted'], get_bloginfo( 'version' ), $comparison )
		) {
			$nag = true;
		}
	}

	if ( ! $nag ) {
		return null;
	}

	$can = current_user_can( 'update_core' );
	return openstation_core_notice(
		array(
			'id'          => 'maintenance',
			'title'       => __( 'WordPress Updates', 'desktop-mode' ),
			'message'     => $can
				? __( 'An automated WordPress update failed to complete.', 'desktop-mode' )
				: __( 'An automated WordPress update failed to complete. Please notify the site administrator.', 'desktop-mode' ),
			'actionLabel' => $can ? __( 'Retry update', 'desktop-mode' ) : '',
			'actionUrl'   => $can ? self_admin_url( 'update-core.php' ) : '',
		)
	);
}

/**
 * Site is in recovery mode — mirrors `wp_recovery_mode_nag()`.
 *
 * @return array|null
 */
function openstation_core_notice_recovery_mode() {
	if ( ! function_exists( 'wp_is_recovery_mode' ) || ! wp_is_recovery_mode() ) {
		return null;
	}

	$url = wp_login_url();
	$url = add_query_arg( 'action', WP_Recovery_Mode::EXIT_ACTION, $url );
	$url = wp_nonce_url( $url, WP_Recovery_Mode::EXIT_ACTION );

	return openstation_core_notice(
		array(
			'id'          => 'recovery-mode',
			'title'       => __( 'Recovery Mode', 'desktop-mode' ),
			'message'     => __( 'You are in recovery mode. There may be an error with a theme or plugin.', 'desktop-mode' ),
			'actionLabel' => __( 'Exit recovery mode', 'desktop-mode' ),
			'actionUrl'   => $url,
		)
	);
}

/**
 * User is still on their auto-generated password — mirrors
 * `default_password_nag()`.
 *
 * @return array|null
 */
function openstation_core_notice_default_password() {
	if ( ! get_user_option( 'default_password_nag' ) ) {
		return null;
	}

	return openstation_core_notice(
		array(
			'id'          => 'default-password',
			'title'       => __( 'Profile', 'desktop-mode' ),
			'message'     => __( 'You are using an auto-generated password. Would you like to change it?', 'desktop-mode' ),
			'actionLabel' => __( 'Change password', 'desktop-mode' ),
			'actionUrl'   => self_admin_url( 'profile.php#password' ),
		)
	);
}

/**
 * Plugins force-deactivated on a WordPress upgrade — mirrors
 * `deactivated_plugins_notice()`.
 *
 * @return array|null
 */
function openstation_core_notice_deactivated_plugins() {
	if ( ! current_user_can( 'activate_plugins' ) ) {
		return null;
	}

	$deactivated = get_option( 'wp_force_deactivated_plugins' );
	if ( empty( $deactivated ) || ! is_array( $deactivated ) ) {
		return null;
	}

	$names = array();
	foreach ( $deactivated as $plugin ) {
		if ( ! empty( $plugin['plugin_name'] ) ) {
			$names[] = $plugin['plugin_name'];
		}
	}
	if ( ! $names ) {
		return null;
	}

	return openstation_core_notice(
		array(
			'id'          => 'deactivated-plugins',
			'title'       => __( 'Plugins', 'desktop-mode' ),
			'message'     => sprintf(
				/* translators: %s: comma-separated list of plugin names. */
				__( 'Deactivated during a WordPress upgrade for incompatibility: %s.', 'desktop-mode' ),
				implode( ', ', $names )
			),
			'actionLabel' => __( 'View plugins', 'desktop-mode' ),
			'actionUrl'   => self_admin_url( 'plugins.php?plugin_status=inactive' ),
		)
	);
}

/**
 * Plugins paused by recovery mode — mirrors `paused_plugins_notice()`.
 *
 * @return array|null
 */
function openstation_core_notice_paused_plugins() {
	if ( ! current_user_can( 'resume_plugins' ) || ! function_exists( 'wp_paused_plugins' ) ) {
		return null;
	}

	if ( empty( wp_paused_plugins()->get_all() ) ) {
		return null;
	}

	return openstation_core_notice(
		array(
			'id'          => 'paused-plugins',
			'title'       => __( 'Plugins', 'desktop-mode' ),
			'message'     => __( 'One or more plugins failed to load properly.', 'desktop-mode' ),
			'actionLabel' => __( 'Go to Plugins', 'desktop-mode' ),
			'actionUrl'   => self_admin_url( 'plugins.php?plugin_status=paused' ),
		)
	);
}

/**
 * Themes paused by recovery mode — mirrors `paused_themes_notice()`.
 *
 * @return array|null
 */
function openstation_core_notice_paused_themes() {
	if ( ! current_user_can( 'resume_themes' ) || ! function_exists( 'wp_paused_themes' ) ) {
		return null;
	}

	if ( empty( wp_paused_themes()->get_all() ) ) {
		return null;
	}

	return openstation_core_notice(
		array(
			'id'          => 'paused-themes',
			'title'       => __( 'Themes', 'desktop-mode' ),
			'message'     => __( 'One or more themes failed to load properly.', 'desktop-mode' ),
			'actionLabel' => __( 'Go to Themes', 'desktop-mode' ),
			'actionUrl'   => self_admin_url( 'themes.php' ),
		)
	);
}

```
