PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / trunk
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts vtrunk
2.7.7 2.7.6 2.7.5 2.7.4 trunk 1.3 2.0.4 2.0.6 2.1.91 2.2.4 2.2.7 2.2.9 2.3.1 2.3.10 2.4.10 2.4.2 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.6.0 2.6.1 2.7.0 All 28 releases
← All changes | includes/class.error-handler.php +63 -6 2.7.6trunk View file →
@@ -22,8 +22,15 @@
22 22 */
23 23 private static $current_snippet = null;
24 24
25 25 /**
26 + * Previous snippet contexts for nested shortcode execution.
27 + *
28 + * @var array<int, array<string, mixed>|null>
29 + */
30 + private static $snippet_stack = [];
31 +
32 + /**
26 33 * Tracks whether the error handler has been initialized.
27 34 *
28 35 * @var bool
29 36 */
@@ -52,8 +59,9 @@
52 59 *
53 60 * @return void
54 61 */
55 62 public static function set_current_snippet( $snippet_id, $title, $content = null ) {
63 + self::$snippet_stack[] = self::$current_snippet;
56 64 self::$current_snippet = [
57 65 'id' => $snippet_id,
58 66 'title' => $title,
59 67 'content' => $content,
@@ -65,12 +73,44 @@
65 73 *
66 74 * @return void
67 75 */
68 76 public static function clear_current_snippet() {
69 - self::$current_snippet = null;
77 + self::$current_snippet = array_pop( self::$snippet_stack );
70 78 }
71 79
72 80 /**
81 + * Handle a catchable error raised while rendering a PHP shortcode.
82 + *
83 + * @param Throwable $exception Runtime error raised by evaluated snippet code.
84 + * @return string Error details for administrators, or an empty string.
85 + */
86 + public static function handle_exception( $exception ) {
87 + if ( ! self::$current_snippet ) {
88 + return '';
89 + }
90 +
91 + /**
92 + * Fires when PHP shortcode execution raises a catchable error.
93 + *
94 + * @param Throwable $exception Runtime error raised by the snippet.
95 + * @param array<string, mixed> $context Current snippet context.
96 + */
97 + do_action( 'wbcr_inp_php_shortcode_error', $exception, self::$current_snippet );
98 +
99 + if ( ! current_user_can( 'manage_options' ) ) {
100 + return '';
101 + }
102 +
103 + $display = self::build_error_display(
104 + self::$current_snippet['title'],
105 + self::strip_stack_trace( $exception->getMessage() ),
106 + $exception->getLine()
107 + );
108 +
109 + return false !== $display ? $display : '';
110 + }
111 +
112 + /**
73 113 * Customize the error message displayed.
74 114 *
75 115 * @param string $message Original error message.
76 116 * @return string Modified error message.
@@ -77,9 +117,9 @@
77 117 */
78 118 public static function customize_error_message( $message ) {
79 119 $error = error_get_last();
80 120
81 - if ( ! $error || ! self::$current_snippet ) {
121 + if ( ! $error || ! self::$current_snippet || ! current_user_can( 'manage_options' ) ) {
82 122 return $message;
83 123 }
84 124
85 125 if ( ! self::is_eval_error( $error['file'] ) ) {
@@ -85,14 +125,15 @@
85 125 if ( ! self::is_eval_error( $error['file'] ) ) {
86 126 return $message;
87 127 }
88 128
129 + $snippet_id = (int) self::$current_snippet['id'];
89 130 $snippet_title = self::$current_snippet['title'];
90 131 $error_message = self::strip_stack_trace( $error['message'] );
91 132 $error_line = (int) $error['line'];
92 133
93 134 // Build the custom error display.
94 - $custom_message = self::build_error_display( $snippet_title, $error_message, $error_line );
135 + $custom_message = self::build_error_display( $snippet_title, $error_message, $error_line, $snippet_id );
95 136
96 137 return $message . $custom_message;
97 138 }
98 139
@@ -123,9 +164,9 @@
123 164 }
124 165
125 166 $patterns = [
126 167 '/\s*Stack trace:.*/is',
127 - '/\s*#\d+\s+.*/is',
168 + '/\n\s*#\d+\s+.*/is',
128 169 '/\s*thrown in .*/is',
129 170 ];
130 171
131 172 foreach ( $patterns as $pattern ) {
@@ -146,11 +187,12 @@
146 187 *
147 188 * @param string $snippet_title Snippet title.
148 189 * @param string $error_message Error message.
149 190 * @param int $error_line Line number where error occurred.
191 + * @param int $snippet_id Snippet ID.
150 192 * @return string|false HTML for error display.
151 193 */
152 - private static function build_error_display( $snippet_title, $error_message, $error_line ) {
194 + private static function build_error_display( $snippet_title, $error_message, $error_line, $snippet_id = 0 ) {
153 195 $title = $snippet_title
154 196 ? sprintf(
155 197 // translators: %s is snippet title.
156 198 esc_html__( 'Snippet: %s', 'insert-php' ),
@@ -164,12 +206,20 @@
164 206 esc_html__( 'Line %d', 'insert-php' ),
165 207 $error_line
166 208 )
167 209 : '';
210 + $id_info = $snippet_id
211 + ? sprintf(
212 + // translators: %d is the snippet ID.
213 + __( 'Snippet ID: %d', 'insert-php' ),
214 + $snippet_id
215 + )
216 + : '';
168 217
169 218 $full_error_text = sprintf(
170 - "%s\n%s: %s",
219 + "%s\n%s\n%s: %s",
171 220 $title,
221 + $id_info,
172 222 $line_info,
173 223 $error_message
174 224 );
175 225
@@ -269,8 +319,15 @@
269 319 <span class="winp-error-value">
270 320 <?php echo esc_html( $snippet_title ); ?>
271 321 </span>
272 322 </div>
323 +
324 + <?php if ( $snippet_id ) : ?>
325 + <div class="winp-error-row">
326 + <span class="winp-error-label"><?php esc_html_e( 'Snippet ID:', 'insert-php' ); ?></span>
327 + <span class="winp-error-value"><?php echo esc_html( (string) $snippet_id ); ?></span>
328 + </div>
329 + <?php endif; ?>
273 330
274 331 <?php if ( $error_line ) : ?>
275 332 <div class="winp-error-row">
276 333 <span class="winp-error-label"><?php esc_html_e( 'Line:', 'insert-php' ); ?></span>