Wordpress - 为前端用户使用“Flash消息”的最佳方式

时间:2017-01-25 19:47:54

标签: php wordpress

一些背景:我开发了一个带有表单的wordpress插件。我需要一种方法来通知用户他们是否搞砸了填写表格。我最初的倾向是php会话变量。我在我的插件中添加了各种代码以使其工作,包括我标题顶部的session_start(),这打破了事情。所以我开始研究向用户显示消息的最佳方式。

我可以使用cookie作为php会话的替代方案,但我的问题是:

在Wordpress中设置前端消息的最佳方法是什么? 我是wordpress的新手。我听说过Wordpress全局变量? Wordpress是否提供了我可以设置的全局变量,可以在任何地方访问?那会有用。是否有一些我应该研究的插件(我不想讨厌这个)。饼干是最好的路线吗?

以下是一段代码,可以说明我要完成的任务:

前端表格(短代码)

  <form method='POST'class="kb_donation_form" action="<?= plugins_url() ?>/kb-donations/includes/handler.php">

            <div class="form-group">
                <label for="kb_first_name">First Name</label>
                <input type="text" class="form-control" id="kb_first_name" name="kb_first_name" placeholder="First Name">
            </div>

            <div class="form-group">
                <label for="kb_last_name">Last Name</label>
                <input type="text" class="form-control" id="kb_last_name" name="kb_last_name" placeholder="First Name">
            </div>
            <div class="form-group">
                <label for="kb_email">Email</label>
                <input type="email" class="form-control" id="kb_email" name="kb_email" placeholder="Email Address">
            </div>

            <div class="form-group">
                <label for="kb_grad_year">Graduation Year</label>
                <select id="kb_grad_year" name="kb_grad_year" class="form-control">
                    <option value="friend">I am just a friend.</option>
                    <option value="1950">1950</option>
                </select>
            </div>

            <div class="form-group">
                <label for="kb_donation_amount">Donation Amount</label>
                <input type="text" class="form-control" id="kb_donation_amount" name="kb_donation_amount" placeholder="100.00">
            </div>

            <div class="form-group">
                <input type="submit" name="submit" value="Make Donation" class="btn btn-default">
            </div>
        </form>

邮政处理程序代码:

if(isset($_POST['submit'])) {
    if(
        !empty($_POST['kb_first_name']) &&
        !empty($_POST['kb_last_name']) &&
        !empty($_POST['kb_email']) &&
        !empty($_POST['kb_grad_year']) &&
        !empty($_POST['kb_donation_amount'])
       ) {
        // All Data Is Set

        // Make sure email is valid format
        $email = filter_var($_POST['kb_email'], FILTER_VALIDATE_EMAIL);

        if(!empty($email)) { // ect.. ect..}
else {
// screw up
// Notify the user
// $_SESSION['error'] = 'You Screwed Up' === NEED ALTERNATIVE
}

2 个答案:

答案 0 :(得分:3)

首先,不要像使用的那样提供任何PHP脚本链接     行动=&#34; /kb-donations/includes/handler.php"

它可能引发安全问题。它不是WordPress的做事方式。

要处理表单,请使用&#34; admin_post&#34;(admin_post_YOUR_ACTION)和&#34; admin_post_nopriv&#34; (admin_post_nopriv_YOUR_ACTION)动作。这是一个很好的解释:

https://www.sitepoint.com/handling-post-requests-the-wordpress-way/

然后您需要设置Flash消息以向用户提供错误消息或成功消息。

如果是后端表单,请使用&#34; admin_notices&#34;行动。这是一个很好的解释:

https://premium.wpmudev.org/blog/adding-admin-notices/

对于前端表单:

我。您可以使用表单模型显示flash消息(通过存储&#34;成功或错误消息;错误&#34;备份模型的私有变量)

或ii。你可以使用&#34; template_notices&#34;行动。

或iii。你可以使用&#34; session_start&#34; (开始会话,将数据存储到会话中并在显示后清除)解决方案。

使用全局变量总是一个坏主意。

答案 1 :(得分:0)

这是带有Flash消息的重定向类

    <?php


namespace App\Core;


class Flash
{

    protected static $instance = null;

    const FLASH_MESSAGE_SKIP_CLEAN = 'flash_message_flag';
    const FLASH_MESSAGE_STORED_KEYS = 'flash_message_keys';
    private $xRedirectBy = 'flash';
    private $statusCode = 302;
    private $redirectUrl;

    public static function init()
    {

        if (!defined("FLASH_INIT")) {
            // ensure session is started
            if (session_status() !== PHP_SESSION_ACTIVE) {
                session_start();
            }
            // clean up flash messages from session on script finishing point
            register_shutdown_function([Flash::class, 'cleanUpFlashMessages']);
            // define flash is initialized
            define("FLASH_INIT", true);
        }
    }

    /**
     * Its a callback for (@register_shutdown_function) which registered in constructor
     */
    public static function cleanUpFlashMessages()
    {

        if (isset($_SESSION[self::FLASH_MESSAGE_SKIP_CLEAN])) {

            //just skip cleaning flash messages
            unset($_SESSION[self::FLASH_MESSAGE_SKIP_CLEAN]);

        } else if (isset($_SESSION[self::FLASH_MESSAGE_STORED_KEYS])) {

            //clean flash messages by using stored keys
            foreach ($_SESSION[self::FLASH_MESSAGE_STORED_KEYS] as $message_key) {
                unset($_SESSION[$message_key]);
            }

            //then clean stored keys itself
            unset($_SESSION[self::FLASH_MESSAGE_STORED_KEYS]);
        }
    }

    /**
     * @param string $key flash message key in session storage
     * @param string $message message value
     *
     * @return Flash
     */
    public function message($key, $message)
    {
        $_SESSION[self::FLASH_MESSAGE_STORED_KEYS][] = $key;
        $_SESSION[$key] = $message;
        return $this;
    }

    /**
     * @param $url
     *
     * @return Flash
     */
    public function redirectLocation($url)
    {
        $this->redirectUrl = $url;
        return $this;
    }

    /**
     * @param $status
     *
     * @return Flash
     */
    public function withStatus($status = 302)
    {
        $this->statusCode = $status;
        return $this;
    }

    /**
     * @param $xRedirectBy
     *
     * @return Flash
     */
    public function redirectBy($xRedirectBy = 'flash')
    {
        $this->xRedirectBy = $xRedirectBy;
        return $this;
    }

    public function redirect()
    {
        //skip cleaning once for redirection
        $_SESSION[self::FLASH_MESSAGE_SKIP_CLEAN] = true;
        @header("X-Redirect-By: $this->xRedirectBy", true, $this->statusCode);
        @header("Location: $this->redirectUrl", true, $this->statusCode);
    }

}

在您的functions.php l Flash::init();中初始化该类,然后使用该类通过Flash消息进行重定向。

        $flash = new Flash();

        if ( $success ) {
            $flash->message( 'success', 'Your message sent successfully!' )
                  ->redirectLocation( site_url( '/contact' ) )
                  ->redirectBy( 'contact' )
                  ->redirect();
        }

在前端检查会话中是否存在您的消息密钥,请执行特殊的工作... 开心的编码