访问另一个页面的强制协议表?

时间:2012-05-21 作者:Greg Ihne

我想设置一个页面,在进入另一个页面之前,访问者需要填写一个表单并接受条款。有插件可以做到这一点吗?如果没有插件,还有其他方法吗?

任何帮助都将不胜感激!

格雷格

2 个回复
SO网友:chrisguitarguy

我会使用一个短代码。将您想要的内容包装在“terms\\u required”快捷码后面,如果用户不同意这些条款,请向他们显示表单。

表单将提交到一个自定义重写规则(url端点),该规则验证表单,并在所有内容都签出时设置cookie。

让我们首先将所有内容包装在一个类中——这里有几个类常量,我们稍后将使用它们。

<?php
class WPSE_52793
{
    /**
     * Query variable we\'ll use for rewrites and catching the form handler
     *
     */
    const Q_VAR = \'wpse52793_handler\';

    /**
     * Form key field name.
     *
     */
    const F_KEY = \'wpse52793_accepted\';

    /**
     * Form field nonce.
     *
     */
    const NONCE = \'wpse52793_fnonce\';

    /**
     * Cookie key.
     *
     */
    const COOKIE = \'wpse52793_agreed\';

    /********** Basic setup fluff **********/

    private static $ins = null;

    public static function instance()
    {
        is_null(self::$ins) && self::$ins = new self;
        return self::$ins;
    }

    public static function init()
    {
        add_action(\'plugins_loaded\', array(self::instance(), \'_setup\'));
    }

    public function _setup()
    {
         // we\'ll add actions here later
    }
}
我们可以添加短代码:hook-intoinit, 调用add shortcode并注册回调。回调只检查cookie。如果有,则显示内容,如果没有,则显示术语和表单。

<?php
class WPSE_52793
{
    // snip snip

    public function _setup()
    {
        add_action(\'init\', array($this, \'shortcode\'));

    }

    public function shortcode()
    {
        add_shortcode(\'terms_required\', array($this, \'shortcode_cb\'));
    }

    public function shortcode_cb($opts, $content=null)
    {
        if(!empty($_COOKIE[self::COOKIE]))
            return $content;

        // if we\'re here, they haven\'t agreed. Show the terms.
        ob_start();
        // Your terms here!
        ?>
        <form method="post" action="<?php echo home_url(\'/terms-handler/\'); ?>">
            <?php wp_nonce_field(self::NONCE, self::NONCE, false); ?>
            <input type="hidden" name="page_id" value="<?php echo get_queried_object_id(); ?>" />
            <label for="agree">
                <input type="checkbox" name="<?php echo esc_attr(self::F_KEY); ?>" value="agree" id="agree" />
                <?php esc_html_e(\'I agree to these terms and conditions.\', \'wpse\'); ?>
            </label>
            <p><input type="submit" value="<?php esc_attr_e(\'Submit\', \'wpse\'); ?>" /></p>
        </form>
        <?php
        return ob_get_clean();
    }
}
重写规则有点复杂:钩住init,调用add_rewrite_rule. 我们还需要过滤query_vars 并添加一个自定义查询变量,以便稍后使用。

<?php
class WPSE_52793
{
    // snip snip

    public function _setup()
    {
        add_action(\'init\', array($this, \'rewrite\'));
        add_filter(\'query_vars\', array($this, \'add_var\'));
        add_action(\'init\', array($this, \'shortcode\'));
    }

    public function rewrite()
    {
        add_rewrite_rule(
            \'^terms-handler/?$\',
            \'index.php?\' . self::Q_VAR . \'=1\',
            \'top\'
        );
    }

    public function add_var($v)
    {
        $v[] = self::Q_VAR;
        return $v;
    }

    // snip snip
}
处理表单提交的最后一块拼图。要做到这一点,请template_redirect 并检查自定义查询变量。如果有,请验证表单:检查nonce,确保我们有一个页面可以重定向它们,并确保它们确实同意。如果一切正常,设置一个cookie并将其发送回原始页面。

<?php
class WPSE_52793
{
    // snip snip

    public function _setup()
    {
        add_action(\'init\', array($this, \'rewrite\'));
        add_filter(\'query_vars\', array($this, \'add_var\'));
        add_action(\'template_redirect\', array($this, \'catch_handler\'));
        add_action(\'init\', array($this, \'shortcode\'));
    }

    // snip snip

    public function catch_handler()
    {
        if(!get_query_var(self::Q_VAR))
            return;

        // only allow post request, check for empty post, and make sure we
        // have a page_id
        if(
            \'POST\' != $_SERVER[\'REQUEST_METHOD\'] ||
            empty($_POST) ||
            empty($_POST[\'page_id\'])
        ) {
            wp_redirect(home_url());
            exit;
        }

        // if we\'re here everything should be good.
        // fetch the permalink
        $r = get_permalink(absint($_POST[\'page_id\']));

        if(!$r)
        {
            // bad permalink for some reason, bail
            wp_redirect(home_url());
            exit;
        }

        if(
            !isset($_POST[self::NONCE]) ||
            !wp_verify_nonce($_POST[self::NONCE], self::NONCE) ||
            empty($_POST[self::F_KEY])
        ) {
            // bad nonce or they didn\'t check the box, try again
            wp_redirect($r);
            exit;
        }

        // whew, they\'ve agreed.  Set a cookie, and send them back to the page.
        setcookie(
            self::COOKIE,
            \'1\',
            strtotime(\'+30 Days\'), // might want to change this?
            \'/\',
            COOKIE_DOMAIN, // WP constant
            false,
            true
        );

        wp_redirect($r);
        exit;
    }
}
另一个值得改进的地方是使用settings API 在管理区域中添加一个字段,您可以在其中显示最终显示在前端的术语。

要做到这一点,请admin_init, 使用register_setting 随着add_settings_sectionadd_settings_field. 我们还需要稍微修改一下短代码回调以使用新选项。结果如下,所有这些混乱in plugin form 供您签出和修改以满足您的需要。

<?php
class WPSE_52793
{
    // snip snip

    /**
     * Settings key.
     *
     */
    const SETTING = \'wpse52793_options\';

    // snip snip

    public function _setup()
    {
        add_action(\'init\', array($this, \'rewrite\'));
        add_filter(\'query_vars\', array($this, \'add_var\'));
        add_action(\'template_redirect\', array($this, \'catch_handler\'));
        add_action(\'init\', array($this, \'shortcode\'));
        add_action(\'admin_init\', array($this, \'settings\'));
    }

    // snip snip

    public function shortcode_cb($opts, $content=null)
    {
        if(!empty($_COOKIE[self::COOKIE]))
            return $content;

        // if we\'re here, they haven\'t agreed. Show the terms.
        ob_start();
        ?>
        <div class="terms-and-conditions">
            <?php echo apply_filters(\'wpse52793_terms\', get_option(self::SETTING, \'\')); ?>
        </div>
        <form method="post" action="<?php echo home_url(\'/terms-handler/\'); ?>">
            <?php wp_nonce_field(self::NONCE, self::NONCE, false); ?>
            <input type="hidden" name="page_id" value="<?php echo get_queried_object_id(); ?>" />
            <label for="agree">
                <input type="checkbox" name="<?php echo esc_attr(self::F_KEY); ?>" value="agree" id="agree" />
                <?php esc_html_e(\'I agree to these terms and conditions.\', \'wpse\'); ?>
            </label>
            <p><input type="submit" value="<?php esc_attr_e(\'Submit\', \'wpse\'); ?>" /></p>
        </form>
        <?php
        return ob_get_clean();
    }

    /**
     * Hooked into `admin_init` -- registers the custom setting and adds a new
     * field and section to the Options > Reading page.
     *
     * @access  public
     * @uses    register_setting
     * @uses    add_settings_section
     * @uses    add_settings_field
     * @return  void
     */
    public function settings()
    {
        register_setting(
            \'reading\',
            self::SETTING,
            array($this, \'validate_cb\')
        );

        add_settings_section(
            \'terms-conditions\',
            __(\'Terms and Conditions\', \'wpse\'),
            array($this, \'section_cb\'),
            \'reading\'
        );

        add_settings_field(
            \'terms-conditions\',
            __(\'Terms & Conditions\', \'wpse\'),
            array($this, \'field_cb\'),
            \'reading\',
            \'terms-conditions\',
            array(\'label_for\' => self::SETTING)
        );
    }

    /**
     * Settings validation callback.  Checks to see if the user can post
     * unfiltered html and return the raw text or a kses filter string
     * where appropriate.
     *
     * @access  public
     * @uses    current_user_can
     * @uses    wp_filter_post_kses
     * @return  string
     */
    public function validate_cb($dirty)
    {
        return current_user_can(\'unfiltered_html\') ?
            $dirty : wp_filter_post_kses($dirty);
    }

    /**
     * Callback for the settings section.  Displays some help text.
     *
     * @access  public
     * @uses    esc_html__
     * @return  void
     */
    public function section_cb()
    {
        echo \'<p class="description">\',
            esc_html__(\'The terms and conditions that get displayed when a user \'.
                \'visits a page protected by the `terms_required` shortcode.\', \'wpse\'),
            \'</p>\';
    }

    /**
     * Callback for the settings field.  Creates a new editor on the screen.
     *
     * @access  public
     * @uses    wp_editor
     * @uses    get_option
     * @return  void
     */
    public function field_cb($args)
    {
        wp_editor(
            get_option(self::SETTING, \'\'),
            self::SETTING,
            array(
                \'wpautop\'       => false,
                \'textarea_rows\' => 10,
            )
        );
    }
}

SO网友:Adam

将此放入functions.php 文件

function redirect_to($location, $status) {
    if(is_page(\'slug-name-here\') ) {

    if ( !isset($_POST[\'terms-accepted\'])) {
                $location =  get_bloginfo(\'url\') . \'/terms/\';
    }
    return $location;
  }

}
add_filter(\'wp_redirect\', \'redirect_to\', 10, 2);
  • slug-name-here = 接受您的条款后要访问的页面$location = 条款页面的路径$_POST[\'terms-accepted\'] = 隐藏的输入字段name="terms-accepted"

    示例:<input type="hidden" name="action" value="" />

结束

相关推荐

get_the_terms issue

我试图列出附加到相关帖子的自定义分类术语(这是一种自定义帖子类型)。我想把它列出来,而不是一个链接,它实际上是一个标题。我试过了,但显然不行。我做错了什么?function woocommerce_output_product_brand() { $terms = get_the_terms( $post->ID, \'brand\' ); foreach($terms as $term){ echo $term; } } 提前感谢!