web-dev-qa-db-fra.com

Utilise eval () ok dans ce scénario

J'essaie d'inclure les entrées utilisateur inclut "get_template_part ()". Les inclus sont ajoutés aux options du thème, par exemple une entrée utilisateur.

get_template_part('content/block', 'branding');
get_template_part('content/block', 'footer');

J'ai besoin d'exécuter ce code en tant que php et d'avoir un hook personnalisé pour add_before_content () qui s'exécute juste avant le contenu et les barres latérales.

Dans ma classe de mises en page, j'ai une méthode qui vérifie l'entrée de l'utilisateur puis l'utilise pour ajouter l'include à l'aide de eval ().

function add_before_content() {
    global $options;
    $string = "get_template_part('content/block', 'branding');";
    return eval($string);
}

add_action('before_content', 'add_before_content');

Cela fonctionne parfaitement, mais je suis nerveux lors de l’utilisation de eval (), en particulier lorsqu’il implique un contenu saisi par l’utilisateur.

Mon raisonnement dans ce scénario est qu'il devrait être évité, car il permet aux utilisateurs de saisir n'importe quel code php et il sera exécuté.

Cependant, le seul accès est à partir de la connexion administrateur.

Depuis, j’ai mis en œuvre une solution différente, mais je voulais poser cette question car il serait bon d’obtenir un retour d’information.

Eval () serait-il une mauvaise idée dans ce scénario?

Plus de précisions

J'essaie d'obtenir le même résultat qu'en ouvrant le fichier index.php du thème et en ajoutant get_template_part() pour inclure un fichier modèle. Par exemple:

<?php get_template_part('content/block', 'header'); ?>

Mais permettre à l'utilisateur de le faire à partir des options de thème sans avoir à ouvrir les fichiers de thème.

Le contenu du fichier n'est pas vraiment important, c'est juste un php normal qui devrait être inclus et exécuté à l'appel.

Dans mes options de thème, j'ai un élément d'édition (extension de texte) que j'utilise pour quelques fonctionnalités afin que du code puisse être ajouté dans le thème à partir des options de thème sans que l'utilisateur ait besoin d'ouvrir les fichiers de thème.

Cela fonctionne parfaitement pour le HTML que j'ai ajouté jusqu'à présent. La valeur est stockée dans la base de données et quand elle se répercute dans le thème, elle fait écho au code HTML, pas de problème.

Cependant, lorsque je voulais permettre à l'utilisateur d'ajouter l'inclus qui est php de l'éditeur de thèmes, c'est là où je me suis retrouvé coincé.

Il y a 2 endroits où l'utilisateur ajouterait ceux-ci. Ci-dessus et ci-dessous le contenu pour lequel il existe également des crochets, raison pour laquelle je les utilise.

Voici une capture d'écran de l'éditeur avec les inclus définis.

http://cl.ly/3n3r3H381g1U1a2t3T3g

Ce dont j'ai besoin, c'est que les noms de marque et l'en-tête soient inclus, comme si j'avais ouvert le fichier index.php et saisi manuellement get_template_part inclus dans le fichier, au lieu de l'éditeur.

Répondant simplement à la valeur en utilisant la façon dont vous avez expliqué, la sortie sur la page sous forme de chaîne comme celle-ci

http://cl.ly/3I251I0B282i0c0E0U2j

Au lieu d'inclure réellement ces fichiers modèles.

Utiliser eval () signifie que la valeur sauvegardée de l'éditeur, qui est une chaîne, serait évaluée en php et ajoute l'inclus comme si je l'avais ajoutée dans le fichier index.php, d'où son fonctionnement et la seule façon dont je pouvais le comprendre.

J'espère que cela rend les choses beaucoup plus claires.

Merci pour votre patience :)

Le concept

Cette fonctionnalité particulière dont je parle ici est le seul endroit où je faisais quelque chose de très similaire où j'essaye d'ajouter du php et depuis suis passé par un autre chemin, mais j'ai posté cette question à propos de eval () car je voulais confirmer ma pensée.

Il s’agit d’un thème parent et, lors de sa première installation, ne comporte qu’une zone de contenu et des barres latérales. C'est comme une "table rase" à partir de laquelle construire un site. Le thème comporte un élément appelé "constructeur de blocs" qui permet aux utilisateurs de définir et d'ajouter/de supprimer des "blocs de construction" sur leur site Web, puis de définir le contenu à afficher dans ces blocs de construction. par exemple: ils peuvent ajouter un bloc appelé "branding"

Un bloc de construction est comme n'importe quelle "section" de contenu sur un site Web. Une zone de logo, une zone de navigation, une étagère de pied de page, une barre d’outils, etc.

Le concept de blocs de construction est tiré du framework de modèles Joomla que nous avons développé et qui repose sur des blocs de construction.

www.getmorph.org

Une fois qu'un bloc est défini, il peut être configuré pour produire de 4 manières.

  1. Widgets (si défini sur widgets, un nouveau widget avec le nom du bloc est créé)
  2. Articles en vedette (peuvent afficher n'importe quel article de la page d'article dans le bloc ou extrait des catégories définies et s'afficher sous forme de grille, de carrousel, de curseur, etc.)
  3. Custom html (ils peuvent entrer n'importe quel html et quelques balises pour des éléments populaires tels que [logo] [nom du site], etc., qui viennent avec le thème. Oui, vous pouvez également utiliser des widgets pour pouvoir les définir comme html dans le widget .. c'est le même résultat, c'est un peu plus facile mais ouvert aux préférences de l'utilisateur.
  4. Désactiver le blocage .. désactive et annule la publication.

La création de bloc est entièrement automatisée. Lorsqu'un nouveau bloc est ajouté, une nouvelle inclusion avec toutes les options pertinentes est créée et une page d'options de thème est également créée à la volée à l'aide de ajax.

Évidemment, cela ne fonctionnera pas sans appeler le bloc du thème quelque part… C’est la seule étape manuelle et c’est là que l’intérêt de ma question initiale est mis au jour.

Il est facile pour tout utilisateur d’ouvrir le fichier index.php ou de créer un thème enfant, d’ajouter un fichier index.php et d’ajouter le code permettant d’appeler le bloc.

<?php get_template_part('content/block', 'header'); ?>

C’est même ainsi que cela est expliqué dans la documentation et qu’un extrait de code est même généré avec le nom du bloc; il suffit de cliquer dessus pour le copier. Des instructions sont données sur la façon d’ajouter le bloc. C’est la seule chose à faire. Très simple en effet.

Cependant, tout en effectuant des tests alpha avec une équipe restreinte d’utilisateurs, quelques-uns ont demandé s’il serait possible de ne pas avoir à ouvrir les fichiers de thème pour ajouter le bloc include… d’où ma question.

Remarque: les blocs de construction sont optionnels. Les utilisateurs ne sont pas obligés de les utiliser, ils peuvent simplement utiliser le thème comme n'importe quel autre thème, mais pour de nombreux utilisateurs, la construction et la modification de leur site Web seront très utiles! Plus facile.

Cela signifie qu'au lieu de définir 70 positions de widgets au cas où un utilisateur en aurait besoin. Notre approche est évolutive, elle commence avec uniquement la position du widget de la barre latérale.

Lorsqu'un thème est développé avec une base ardoise, il est possible d'ajouter un nombre illimité de positions de widget en ajoutant les blocs requis.

2
Andy James

Je vois ce que vous essayez de faire ... et ça ne me plait pas du tout. Vous incluez beaucoup trop d'options en termes de thème, en particulier si vous autorisez le code libre PHP sur un écran d'options.

Pourquoi c'est une mauvaise idée

Le mantra de tout le projet WordPress est "des décisions, pas des options". Le fait est que plus vous avez d'options pour un thème, plus il peut être déroutant de gérer les choses. Si vous avez vraiment besoin de beaucoup de personnalisation, créez un thème parent et demandez aux personnes de créer des thèmes enfants personnalisés.

Pensez à la Genèse ou à la thèse. Thèmes très puissants, avec une grande variété d'options de conception disponibles via des thèmes enfants personnalisés.

Si vous insistez, voici ce que vous pouvez faire à la place

Vous dites que vous souhaitez donner aux utilisateurs la possibilité de mettre en file d'attente les blocs d'affichage du site sans modifier directement les fichiers de thème:

Dans mes options de thème, j'ai un élément d'édition (extension de texte) que j'utilise pour quelques fonctionnalités afin que du code puisse être ajouté dans le thème à partir des options de thème sans que l'utilisateur ait besoin d'ouvrir les fichiers de thème.

Cela ressemble exactement à un autre système qui existe déjà dans WordPress : les widgets.

Un widget est simplement un modèle de contenu prédéfini que vous pouvez glisser-déposer n'importe où sur une surface widgetisée dans WordPress. Certaines personnes n'ont qu'une barre latérale pouvant héberger des widgets. D'autres ont dans leur thème plusieurs régions widgetisées (j'en ai vu au moins une avec 70 emplacements prêts pour le widget !).

Il semble que vous ayez déjà défini vos blocs de contenu (les parties du modèle). Je vous recommande de faire l'une des deux choses suivantes:

  1. Demandez aux utilisateurs de modifier les fichiers directement. Vous les voyez déjà écrire PHP sur votre panneau d'options. Ce n'est pas une étape énorme pour eux de modifier le PHP directement.
  2. Widgetize votre thème. Celles-ci ne doivent pas nécessairement être des widgets WordPress typiques ... mais vos parties de modèle personnalisées sont des blocs de contenu prédéfinis similaires à ceux des widgets. Ne réinventez pas la roue. Si vous voulez que les gens les positionnent à différents endroits, donnez-leur une interface pour le faire.

avec jQuery, il est très facile de faire glisser et déposer des éléments d’une région à l’autre. Ensuite, vous pouvez enregistrer la séquence dans la table des options et appeler les choses directement ... sans utiliser eval().

2
EAMann

Je ne vois aucune raison d'utiliser eval() dans ce cas.

J'ai besoin d'exécuter ce code en tant que php et d'avoir un hook personnalisé pour add_before_content () qui s'exécute juste avant le contenu et les barres latérales.

Vous avez donc fourni à l'utilisateur une entrée de texte, ou textarea, et vous devez générer ce contenu dans le modèle. Et vous voulez le faire à un crochet personnalisé. Tout va bien jusqu'à présent. Voici où vous allez mal:

Dans ma classe de mises en page, j'ai une méthode qui vérifie l'entrée de l'utilisateur puis l'utilise pour ajouter l'include à l'aide de eval ().

function add_before_content() {
    global $options;
    $string = "get_template_part('content/block', 'branding');";
    return eval($string);
}

add_action ('before_content', 'add_before_content');

Quel est le but de cela?

Premièrement: pourquoi voudriez-vous écrire les entrées de l'utilisateur dans un fichier PHP, au lieu de les stocker dans la base de données, comme il convient?

Deuxièmement: vous êtes déjà dans un rappel de hook personnalisé; pourquoi ne pas simplement sortir l'entrée de l'utilisateur directement à partir de votre rappel?

Disons que vous avez appelé cette option content_branding. Essayez quelque chose comme ça:

function add_before_content() {
    global $options;
    // Sanitize, for safety
    $content_branding = wp_kses_post( $options['content_branding'] );
    // Echo (or return) the result
    echo $content_branding;
}

add_action('before_content', 'add_before_content');

Qu'est-ce que je rate?

EDIT

La raison pour laquelle je dis que le contenu n'est pas important, c'est parce que cela peut être n'importe quoi et qu'ils diffèrent tous. Certains ne font que sortir des positions de widget, d'autres des messages en vedette. Mais le même scénario serait vrai si le fichier avait juste ce que le php est à l'intérieur du fichier inclus, il devrait juste fonctionner comme s'il était inclus normalement.

Sur la base de cette clarification, je vais réitérer (et voter à la hausse) la suggestion d'Eric Mann selon laquelle, plutôt que d'utiliser votre approche actuelle, vous utilisez plutôt des barres latérales dynamiques et des widgets personnalisés.

2
Chip Bennett

Vous pouvez soit placer le code entier dans un tableau comme ci-dessous:

$safe= array(

    'get_template_part(\'content/block\', \'branding\');',
    'get_template_part(\'content/block\', \'footer\');'
);

Et introduisez ensuite le contrôle ci-dessous dans votre fonction pour vous assurer qu'aucun autre type de code que celui que vous avez déjà répertorié ne peut être envoyé à eval:

function add_before_content() {
    global $options;
    global $safe;
    $string = (this comes from user)
    if(in_array($string,$safe))
    {
        return eval($string);
    }
}

add_action('before_content', 'add_before_content');

Vous pouvez également modifier la fonction et vérifier par rapport aux différents types de modèles pouvant être inclus:

$safe= array(

    'branding',
    'footer',
);

function add_before_content() {
    global $options;
    global $safe;
    $string = (this comes from user)
    if(in_array($string,$safe))
    {
        return eval("get_template_part('content/block', '".$string."');");
    }
}

add_action('before_content', 'add_before_content');

Dans les deux cas, l'utilisateur n'aura aucune possibilité d'envoyer à eval () autre chose que ce que vous avez autorisé; le système sera donc sécurisé.

Je préfère le dernier depuis son nettoyeur.

0
unity100