1<?php
2/**
3 * Error Protection API: Functions
4 *
5 * @package WordPress
6 * @since 5.2.0
7 */
8
9/**
10 * Get the instance for storing paused plugins.
11 *
12 * @return WP_Paused_Extensions_Storage
13 */
14function wp_paused_plugins() {
15 static $storage = null;
16
17 if ( null === $storage ) {
18 $storage = new WP_Paused_Extensions_Storage( 'plugin' );
19 }
20
21 return $storage;
22}
23
24/**
25 * Get the instance for storing paused extensions.
26 *
27 * @return WP_Paused_Extensions_Storage
28 */
29function wp_paused_themes() {
30 static $storage = null;
31
32 if ( null === $storage ) {
33 $storage = new WP_Paused_Extensions_Storage( 'theme' );
34 }
35
36 return $storage;
37}
38
39/**
40 * Get a human readable description of an extension's error.
41 *
42 * @since 5.2.0
43 *
44 * @param array $error Error details from `error_get_last()`.
45 * @return string Formatted error description.
46 */
47function wp_get_extension_error_description( $error ) {
48 $constants = get_defined_constants( true );
49 $constants = isset( $constants['Core'] ) ? $constants['Core'] : $constants['internal'];
50 $core_errors = array();
51
52 foreach ( $constants as $constant => $value ) {
53 if ( str_starts_with( $constant, 'E_' ) ) {
54 $core_errors[ $value ] = $constant;
55 }
56 }
57
58 if ( isset( $core_errors[ $error['type'] ] ) ) {
59 $error['type'] = $core_errors[ $error['type'] ];
60 }
61
62 /* translators: 1: Error type, 2: Error line number, 3: Error file name, 4: Error message. */
63 $error_message = __( 'An error of type %1$s was caused in line %2$s of the file %3$s. Error message: %4$s' );
64
65 return sprintf(
66 $error_message,
67 "<code>{$error['type']}</code>",
68 "<code>{$error['line']}</code>",
69 "<code>{$error['file']}</code>",
70 "<code>{$error['message']}</code>"
71 );
72}
73
74/**
75 * Registers the shutdown handler for fatal errors.
76 *
77 * The handler will only be registered if {@see wp_is_fatal_error_handler_enabled()} returns true.
78 *
79 * @since 5.2.0
80 */
81function wp_register_fatal_error_handler() {
82 if ( ! wp_is_fatal_error_handler_enabled() ) {
83 return;
84 }
85
86 $handler = null;
87 if ( defined( 'WP_CONTENT_DIR' ) && is_readable( WP_CONTENT_DIR . '/fatal-error-handler.php' ) ) {
88 $handler = include WP_CONTENT_DIR . '/fatal-error-handler.php';
89 }
90
91 if ( ! is_object( $handler ) || ! is_callable( array( $handler, 'handle' ) ) ) {
92 $handler = new WP_Fatal_Error_Handler();
93 }
94
95 register_shutdown_function( array( $handler, 'handle' ) );
96}
97
98/**
99 * Checks whether the fatal error handler is enabled.
100 *
101 * A constant `WP_DISABLE_FATAL_ERROR_HANDLER` can be set in `wp-config.php` to disable it, or alternatively the
102 * {@see 'wp_fatal_error_handler_enabled'} filter can be used to modify the return value.
103 *
104 * @since 5.2.0
105 *
106 * @return bool True if the fatal error handler is enabled, false otherwise.
107 */
108function wp_is_fatal_error_handler_enabled() {
109 $enabled = ! defined( 'WP_DISABLE_FATAL_ERROR_HANDLER' ) || ! WP_DISABLE_FATAL_ERROR_HANDLER;
110
111 /**
112 * Filters whether the fatal error handler is enabled.
113 *
114 * **Important:** This filter runs before it can be used by plugins. It cannot
115 * be used by plugins, mu-plugins, or themes. To use this filter you must define
116 * a `$wp_filter` global before WordPress loads, usually in `wp-config.php`.
117 *
118 * Example:
119 *
120 * $GLOBALS['wp_filter'] = array(
121 * 'wp_fatal_error_handler_enabled' => array(
122 * 10 => array(
123 * array(
124 * 'accepted_args' => 0,
125 * 'function' => function() {
126 * return false;
127 * },
128 * ),
129 * ),
130 * ),
131 * );
132 *
133 * Alternatively you can use the `WP_DISABLE_FATAL_ERROR_HANDLER` constant.
134 *
135 * @since 5.2.0
136 *
137 * @param bool $enabled True if the fatal error handler is enabled, false otherwise.
138 */
139 return apply_filters( 'wp_fatal_error_handler_enabled', $enabled );
140}
141
142/**
143 * Access the WordPress Recovery Mode instance.
144 *
145 * @since 5.2.0
146 *
147 * @return WP_Recovery_Mode
148 */
149function wp_recovery_mode() {
150 static $wp_recovery_mode;
151
152 if ( ! $wp_recovery_mode ) {
153 $wp_recovery_mode = new WP_Recovery_Mode();
154 }
155
156 return $wp_recovery_mode;
157}
158