web-dev-qa-db-fra.com

Le tableau de bord disparaît après la mise à niveau

Après une mise à niveau récente vers WP et un site MySQL doté d'un plugin personnalisé, une erreur fatale est générée:

Erreur fatale: impossible de réaffecter la variable globale automatique _REQUEST dans /home/mysitexyz/public_html/wp-content/plugins/employment_application/employment_application.php à la ligne 549

Voici le code incriminé:

function getApplications($_REQUEST) {
    global $wpdb;
    $sql = "SELECT * FROM employment_applications";
    if($_REQUEST['s'] != '') {

    }
    $sql .= " WHERE applicant_name LIKE '%" . $_REQUEST['s']  . "%'";
//echo "SQL: $sql<BR>"; 
    $applications = $wpdb->get_results($sql);
    $wpdb->show_errors();
    //$errors = $wpdb->print_error();
    $error = $wpdb->last_error;     
    if($error != '') {
        echo '<div class="alert alert-error">' . $error . '</div>';
    }
    //print_r($applications);
    return $applications;
}

Je sais que ce forum ne prend pas en charge les plug-ins, et comme je ne suis pas le développeur d'origine et que je n'ai que hérité du problème, j'aimerais aborder l'autre problème:

Lorsque je supprime le plug-in mentionné ci-dessus en modifiant le nom du dossier, le site réapparaît, mais seule la barre de navigation latérale du tableau de bord s'affiche. Le reste est vide.

enter image description here

Est-il possible de désactiver les plugins sans les supprimer du dossier Plugins? Existe-t-il un meilleur moyen de résoudre la cause première du tableau de bord vide?

Merci!

2
fmz

C’est un plugin vraiment insolent, mon ami.


Prologue

Avant de commencer, supprimez ce conditionnel - il ne fait absolument rien:

if($_REQUEST['s'] != '') {

}

Mais vraiment, plus que probablement, le développeur du plugin original avait voulu que ce conditionnel fasse réellement quelque chose en se retirant de la fonction si $_REQUEST['s'] n'est pas défini (vu que cette fonction fera très peu en un tel cas):

function getApplications( $_REQUEST ) {
    if( empty( $_REQUEST['s'] ) ) {
        return false;
    }

    global $wpdb;
    $sql = "SELECT * FROM employment_applications";

    ...

    return $applications;
}

L'erreur fatale

Tout d'abord: l'erreur fatale. $_REQUEST in PHP est un super-global automatiquement renseigné que PHP remplit avec les données de la requête HTTP. En tant que tel, il peut être considéré comme un mot réservé (plus précisément, une variable prédéfinie ). Spécifier $_REQUEST en tant que paramètre de la fonction getApplications() indique à PHP de référencer le premier argument avec $_REQUEST, mais les super-globaux ne peuvent pas être localisés en PHP5, ce qui signifie que PHP interprète le code comme une tentative. réaffecter le super-global, donc l'erreur (pas sûr de la version spécifique dans laquelle cela a changé, mais il était possible d'utiliser des super-globaux comme paramètres dans PHP4).

Si la fonction getApplications() est appelée avec des arguments , modifiez le nom du paramètre pour conserver un flux approprié et éviter de réaffecter le super-global $_REQUEST:

function getApplications( $request ) {
    if( empty( $request['s'] ) )
        return false;

    global $wpdb;
    $sql = "SELECT * FROM employment_applications";
    $sql .= " WHERE applicant_name LIKE '%" . $request['s']  . "%'";

    $applications = $wpdb->get_results( $sql );
    $wpdb->show_errors();
    $error = $wpdb->last_error;

    if($error != '') {
        echo '<div class="alert alert-error">' . $error . '</div>';
    }

    return $applications;
}

Si la fonction getApplications() appelée sans arguments ( ou est toujours appelée avec l'argument $_REQUEST, c'est-à-dire getApplications( $_REQUEST )) , supprime entièrement le paramètre et utilise directement le $_REQUEST super-global:

function getApplications() {
    if( empty( $_REQUEST['s'] ) )
        return false;

    global $wpdb;
    $sql = "SELECT * FROM employment_applications";
    $sql .= " WHERE applicant_name LIKE '%" . $_REQUEST['s']  . "%'";

    $applications = $wpdb->get_results( $sql );
    $wpdb->show_errors();
    $error = $wpdb->last_error;

    if($error != '') {
        echo '<div class="alert alert-error">' . $error . '</div>';
    }

    return $applications;
}

Plus que probablement, votre solution sera la dernière des deux.


Désactivation des plug-in en dehors du tableau de bord

Il y a plusieurs façons de s'y prendre, mais voici quelques unes des plus courantes:

  • Modifier l'option active_plugins (permanent)

    • Base de données:

      À l'aide de PHPMyAdmin ou du SQL brut, dans la table wp_options, localisez la ligne dont le champ option_name est active_plugins et modifiez son champ option_value. Notez que il s’agit d’une valeur sérialisée . Par conséquent, si vous ne savez pas exactement comment modifier à la main les données sérialisées, vous devrez désérialiser les données. valeur, apportez vos modifications, puis resérialisez-la avant de la replacer dans le champ. Sinon, la suppression du contenu de option_value désactive tous les plugins (bien que leurs crochets de désactivation ne se déclenchent pas, en fonction de l'implémentation du plugin).

      Ou vous pouvez utiliser un outil de recherche et de remplacement prenant en charge la sérialisation .

    • PHP:

      Utilisez la fonction deactivate_plugins() ou l’API Options dans un doit utiliser le plugin . Les plugins à utiliser sont toujours considérés comme "activés" et sont chargés avant tous les autres plugins; cela fournit un point d'entrée pratique pour exécuter du code même lorsque les grandes parties du site sont inaccessibles.

  • Invalider active_plugins ("undoable")

    C'est essentiellement la même chose que de renommer le dossier des plugins (root). Dans active_plugins, WordPress note l'emplacement du fichier principal de chaque plugin par rapport à la racine du plugin ( la constante WP_PLUGIN_DIR ). En modifiant WP_PLUGIN_DIR, vous pouvez forcer WordPress à perdre le suivi des plugins et donc à ne pas les charger. Traitez la requête comme si aucun plugin n'était présent et laissez l'option active_plugins intacte dans la base de données. Dans wp-config.php : define( 'WP_PLUGIN_DIR', 'thisPathDoesNotExist' );. Supprimer cette ligne rétablira le chemin par défaut du plug-in.


"Un meilleur moyen de résoudre les problèmes"

Veuillez vous reporter à l’entrée Codex Débogage dans WordPress pour un aperçu des fonctionnalités de débogage fournies par WordPress, ainsi qu’une courte liste de très bons plugins aidant. débogage. La toute première étape consiste à toujours à activer la constante WP_DEBUG dans wp-config.php (bien que cela ne soit pas le cas dans un environnement de production):

define( 'WP_DEBUG', true );

Si WP_DEBUG est false (comme par défaut), WordPress supprime la grande majorité des avertissements et des erreurs.

Je recommande également vivement d’utiliser Xdebug sur votre machine de développement pour un accès rapide aux traces de pile ridiculement utiles, aux var_dump()s formatés, au débogage distant et à de jolies couleurs (entre autres). ).


Une note concernant la sécurité

Prenons un moment pour inspecter cette ligne ici:

$sql .= " WHERE applicant_name LIKE '%" . $_REQUEST['s']  . "%'";

Comme $_REQUEST est rempli avec les données de la requête HTTP, cette ligne consiste à extraire la clé de données s directement de la requête et à la déposer dans une requête SQL. Il s'agit d'un trou de sécurité majeur qui expose probablement votre site à des injections SQL . Toute personne ayant accès à une partie du site entraînant l'exécution de la fonction getApplications() peut simplement ajouter ?s=whatever à l'URL pour effectuer des requêtes de sa propre conception. L'absence d'échappement appropriée signifie qu'un attaquant pourrait même potentiellement utiliser cette requête pour accéder à des données en dehors de la table employment_applications.

Si elles ne sont pas résumées et/ou validées, toutes les données fournies par les utilisateurs doivent être échappées, à tout le moins:

$sql = "SELECT * FROM employment_applications";
$sql .= " WHERE applicant_name LIKE '%" . esc_sql( like_escape( $_REQUEST['s'] ) ) . "%'";
$applications = $wpdb->get_results( $sql );

ou

$querystring = "SELECT * FROM employment_applications WHERE applicant_name LIKE '%%%s%%'";
$applications = $wpdb->get_results( $wpdb->prepare( $querystring, $_REQUEST['s'] ) );

Vous devez donner les entrées du Codex sur la validation des données et pour protéger les requêtes contre les attaques par injection SQL une recherche d’une brève introduction à la sécurité des données dans WordPress.


Épilogue

Compte tenu de tout ce qui précède, je pense que votre code modifié devrait ressembler à ce qui suit:

function getApplications() {
    if( empty( $_REQUEST['s'] ) )
        return false;

    global $wpdb;
    $querystring = "SELECT * FROM employment_applications WHERE applicant_name LIKE '%%%s%%'";
    $applications = $wpdb->get_results( $wpdb->prepare( $querystring, $_REQUEST['s'] ) );
    $wpdb->show_errors();
    $error = $wpdb->last_error;

    if( ! empty( $error ) ) {
        echo '<div class="alert alert-error">' . $error . '</div>';
    }

    return $applications;
}
1
bosco

Vous pouvez désactiver un plugin de la base de données en dernier recours, voici un lien vers un article qui vous aidera si vous êtes familier avec MySQL

http://perishablepress.com/quickly-disable-or-enable-all-wordpress-plugins-via-the-database/

Si vous n'êtes pas familier avec MySQL, je vous suggère alors d'utiliser un outil tel que Sequel Pro pour OS X ou . PHPMyAdmin pour rechercher le champ 'active_plugins' dans la table wp_options. Quelque part dans l’objet sérialisé se trouveront vos plugins, il suffit de le supprimer et de son index (la partie "i": 4 avant) et de le sauvegarder.

Vous pouvez également désactiver tous les plugins en définissant la valeur de 'active_plugins' avec une chaîne vide (''). Ensuite, il devrait être assez facile d'activer les plugins que vous voulez avec l'interface d'administration.

1
macguru2000