Il Plugin `db-error.php`

Il Plugin `db-error.php`

Nel gergo di WordPress un Plugin Drop-in è uno script PHP che sostituisce una funzionalità di WordPress, diventando in qualche modo parte del core. Infatti questi speciali plugin non hanno bisogno di essere attivati perché vengano caricati, basta farli "cadere" nella cartella wp-content.

Il plugin db-error.php è un Drop-in che WordPress prova a caricare ogni qualvolta si presenta un problema di connessione al database, dandoci così la possibilità di mostrare una pagina d'errore personalizzata in luogo della pagina che sfoggia il messaggio "Errore nello stabilire una connessione al database".

Quanto segue è più o meno il contenuto del file db-error.php che ho scritto per questo sito web:

1<?php
2/**
3 * Whenever there is a problem connecting to the database this Drop-in
4 * plugin shows to the visitor a custom error page and sends to your 
5 * inbox a notification about the insurrection.
6 *
7 * Version: 1.0
8 * 
9 * 
10 * Copyright 2020 Luigi Cavalieri.
11 * 
12 * This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
16 * 
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 * 
22 * You should have received a copy of the GNU General Public License
23 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 *
25 * *********************************************************************** */
26
27
28// Direct script access denied.
29if (! defined( 'ABSPATH' ) ) {
30    exit;
31}
32
33define( 'FROM_EMAIL_ADDRESS', 'your_admin@email.address' );
34define( 'TO_EMAIL_ADDRESS', 'your_private@email.address' );
35define( 'THIRTY_MINUTES', 1800 );
36
37session_start();
38
39$now = time();
40
41// Timestamp of the last email sent.
42// Used to limit the number of notifications 
43// sent via email.
44//
45// It is saved both to a text file 
46// and to a session variable, 
47// so that the text file is read only 
48// once per visit.
49$last_email_time = 0;
50
51// Full path to the text file 
52// where $last_email_time is saved.
53$timestamp_file_path = WP_CONTENT_DIR . '/db-error.txt';
54
55if (
56    isset( $_SESSION['last_email_time'] ) && 
57    is_int( $_SESSION['last_email_time'] ) 
58) {
59    $last_email_time = $_SESSION['last_email_time'];
60}
61else {
62    $last_email_time = (int) file_get_contents( $timestamp_file_path );
63    
64    $_SESSION['last_email_time'] = $last_email_time;
65}
66
67// Makes sure that the inbox doesn't catch fire.
68if ( ( $now - $last_email_time ) > THIRTY_MINUTES ) {
69    $email_subject = 'Database error';
70    $error_message = 'Database unreachable: ' . $_SERVER['REQUEST_URI'];
71    $extra_headers = 'From: ' . FROM_EMAIL_ADDRESS;
72    $email_sent    = mail(
73        TO_EMAIL_ADDRESS,
74        $email_subject,
75        $error_message,
76        $extra_headers
77    );
78
79    if ( $email_sent ) {
80        $_SESSION['last_email_time'] = $now;
81        
82        file_put_contents( $timestamp_file_path, $now );
83    }
84
85    error_log( $error_message );
86}
87
88// Some HTTP headers for search engines.
89header( 'HTTP/1.1 503 Service Temporarily Unavailable' );
90header( 'Status: 503 Service Temporarily Unavailable' );
91header( 'Retry-After: ' . THIRTY_MINUTES );
92
93// The database connection problem
94// might be only temporary.
95header( 'Refresh: 10' );
96
97?><!DOCTYPE html>
98<html>
99<head>
100<meta charset="UTF-8">
101
102<title>Error</title>
103</head>
104
105<body>
106    <p>A few lines for the visitor.</p>
107</body>
108</html>

Come Testarlo

C'è più di un modo per testare questo plugin, ma quello più pratico che ho trovato è l'incollare le seguenti tre linee di codice da qualche parte nel file wp-config.php:

1global $wpdb;
2
3$wpdb        = new stdClass();
4$wpdb->error = 'crash';

È un hackeraggio, ma impermanente dopo tutto.

TOP