我会使用一个短代码。将您想要的内容包装在“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-into
init
, 调用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_section
和add_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,
)
);
}
}