我正在修改WP插件(PHP;最新版本的WP)。它有一个用户可以提出问题的表单。它带有它自己的提交按钮。我找到了一个动作挂钩,我可以在表单中添加自己的代码,所以我添加了Braintree最简单的付款方式 - DropIn UI。 This is a screenshot of what both forms look like when I set them up
问题:
插件附带的“发布问题”按钮无效,我怀疑这是由于第二种形式的存在。
我尝试了什么:
我删除了我添加的代码的一些部分,试图找出可能导致这种情况的代码,它归结为DropIn的表单代码本身。此页面上存在第二个表单会导致问题。
我的问题:当一个页面上有两个表单时,什么可能导致提交问题?
注意 - 我使用了一个动作钩子将我的代码插入到一个将自己描述为主要插件的表单页脚的函数中。我感觉这是一个表格嵌套问题。
我创建Braintree表单的函数:
class FD_Braintree_Form
{
public function fd_bt_form()
{
echo
'<form id="checkout" action="/process-trans.php" method="post">
<p>
<label><font size="5">Amount:</font></label>
<input type="text" size="4" name="amount" />
</p>
<div id="payment-form"></div>
<input type="submit" value="Pay" />
</form>';
}
}
我生成Braintree表单的函数:
class Find_Do_For_Anspress
{
add_action('ap_form_bottom_ask_form', array( $this, 'fd_bt_form_html')); //This is where I use the action hook to insert my code into the plugin's form_footer()
public function fd_bt_form_html()
{
$class_bt_token = new Braintree_ClientToken();
$clientToken = $class_bt_token->generate();
?>
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
braintree.setup(
'<?php echo $clientToken ?>',
'dropin', {
container: 'payment-form',
});
</script>
<?php
$class_bt_form = new FD_Braintree_Form();
$bt_form = $class_bt_form->fd_bt_form();
echo $bt_form;
}
}
插件的主要代码,用于生成问题表单:
function ap_ask_form($editing = false){
global $editing_post;
$is_private = false;
if($editing){
$is_private = $editing_post->post_status == 'private_post' ? true : false;
}
$args = array(
'name' => 'ask_form',
'is_ajaxified' => true,
'submit_button' => ($editing ? __('Update question', 'ap') : __('Post question', 'ap')),
'fields' => array(
array(
'name' => 'title',
'label' => __('Title', 'ap'),
'type' => 'text',
'placeholder' => __('Question in one sentence', 'ap'),
'desc' => __('Write a meaningful title for the question.', 'ap'),
'value' => ( $editing ? $editing_post->post_title : sanitize_text_field( @$_POST['title'] ) ),
'order' => 5,
'attr' => 'data-action="suggest_similar_questions"',
'autocomplete' => false,
),
array(
'name' => 'title',
'type' => 'custom',
'order' => 5,
'html' => '<div id="similar_suggestions"></div>'
),
array(
'name' => 'description',
'label' => __('Description', 'ap'),
'type' => 'editor',
'desc' => __('Write description for the question.', 'ap'),
'value' => ( $editing ? apply_filters('the_content', $editing_post->post_content) : @$_POST['description'] ),
'settings' => apply_filters( 'ap_ask_form_editor_settings', array(
'textarea_rows' => 8,
'tinymce' => ap_opt('question_text_editor') ? false : true,
'quicktags' => ap_opt('question_text_editor') ? true : false ,
'media_buttons' =>false,
)),
),
array(
'name' => 'ap_upload',
'type' => 'custom',
'html' => ap_post_upload_form(),
'order' => 10
),
array(
'name' => 'parent_id',
'type' => 'hidden',
'value' => ( $editing ? $editing_post->post_parent : get_query_var('parent') ),
'order' => 20
)
),
);
if(ap_opt('allow_private_posts'))
$args['fields'][] = array(
'name' => 'is_private',
'type' => 'checkbox',
'desc' => __('Only visible to admin and moderator.', 'ap'),
'value' => $is_private,
'order' => 12,
'show_desc_tip' => false
);
if(ap_opt('recaptcha_site_key') == '')
$reCaptcha_html = '<div class="ap-notice red">'.__('reCaptach keys missing, please add keys', 'ap').'</div>';
else
$reCaptcha_html = '<div class="g-recaptcha" id="recaptcha" data-sitekey="'.ap_opt('recaptcha_site_key').'"></div><script type="text/javascript"
src="https://www.google.com/recaptcha/api.js?hl='.get_locale().'&onload=onloadCallback&render=explicit" async defer></script><script type="text/javascript">var onloadCallback = function() {
widgetId1 = grecaptcha.render("recaptcha", {
"sitekey" : "'.ap_opt('recaptcha_site_key').'"
});
};</script>';
if(ap_opt('enable_recaptcha'))
$args['fields'][] = array(
'name' => 'captcha',
'type' => 'custom',
'order' => 100,
'html' => $reCaptcha_html
);
/**
* FILTER: ap_ask_form_fields
* Filter for modifying $args
* @var array
* @since 2.0
*/
$args = apply_filters( 'ap_ask_form_fields', $args, $editing );
if($editing){
$args['fields'][] = array(
'name' => 'edit_post_id',
'type' => 'hidden',
'value' => $editing_post->ID,
'order' => 20
);
}
$form = new AnsPress_Form($args);
echo $form->get_form();
echo ap_post_upload_hidden_form();
}
该插件的“表单页脚”代码和我使用的操作挂钩:
private function form_footer()
{
ob_start();
/**
* ACTION: ap_form_bottom_[form_name]
* action for hooking captcha and extar fields
* @since 2.0.1
*/
do_action('ap_form_bottom_'. $this->name);
$this->output .= ob_get_clean();
$this->output .= '<button type="submit" class="ap-btn ap-btn-submit">'.$this->args['submit_button'].'</button>';
if(@$this->args['show_cancel'] === true)
$this->output .= '<button type="button" class="ap-btn ap-btn-cancel">'.__('Cancel', 'ap').'</button>';
$this->output .= '</form>';
}
隐藏的上传功能:
function ap_post_upload_hidden_form(){
if(ap_opt('allow_upload_image'))
return '<form id="hidden-post-upload" enctype="multipart/form-data" method="POST" style="display:none">
<input type="file" name="post_upload_image" class="ap-upload-input">
<input type="hidden" name="ap_ajax_action" value="upload_post_image" />
<input type="hidden" name="ap_form_action" value="upload_post_image" />
<input type="hidden" name="__nonce" value="'.wp_create_nonce( 'upload_image_'.get_current_user_id()).'" />
<input type="hidden" name="action" value="ap_ajax" />
</form>';
}
包含插件的表单代码的HTML:
<div class="ap-tab-container">
<div id="ap-form-main" class="active ap-tab-item">
<?php ap_ask_form(); ?>
</div>
</div>
答案 0 :(得分:0)
编辑:案例中的问题是您正在使用的动作挂钩是将您的表单放在插件的表单中。你需要使用一个不同的动作钩子(或者你需要使用这个钩子。)
您正在使用的插件没有提供适当的操作挂钩来将表单放在您尝试放置它的位置(在ask_form之后)。您必须修改插件代码才能使用。如果您愿意修改插件代码,您可以这样做:
修改插件表单页脚方法:
private function form_footer()
{
ob_start();
/**
* ACTION: ap_form_bottom_[form_name]
* action for hooking captcha and extar fields
* @since 2.0.1
*/
do_action('ap_form_bottom_'. $this->name);
$this->output .= ob_get_clean();
$this->output .= '<button type="submit" class="ap-btn ap-btn-submit">'.$this->args['submit_button'].'</button>';
if(@$this->args['show_cancel'] === true)
$this->output .= '<button type="button" class="ap-btn ap-btn-cancel">'.__('Cancel', 'ap').'</button>';
$this->output .= '</form>';
//MODIFICATION added action
do_action('ap_form_aftercustom_'. $this->name);
}
然后,修改你的fd_bt_form_html函数:
class Find_Do_For_Anspress
{
//MODIFICATION use the new action
add_action('ap_form_aftercustom_ask_form', array( $this, 'fd_bt_form_html')); //This is where I use the action hook to insert my code into the plugin's form_footer()
public function fd_bt_form_html()
{
$class_bt_token = new Braintree_ClientToken();
$clientToken = $class_bt_token->generate();
?>
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
braintree.setup(
'<?php echo $clientToken ?>',
'dropin', {
container: 'payment-form',
});
</script>
<?php
$class_bt_form = new FD_Braintree_Form();
$bt_form = $class_bt_form->fd_bt_form();
echo $bt_form;
}
}
- 结束编辑 -
在获得额外信息之前我的原始反馈:
我认为这里有两个可能的罪魁祸首(没有看到你的代码)。
<form>
<input ...>
<input ...>
<input type="submit" form="SomeForm" value="Submit Form 1">
<form>
<input ...>
<input ...>
<input type="submit" form="SomeForm" value="Submit Form 2">
</form>
</form>
<form name="SomeForm" id="SomeForm">
<input form="SomeForm" ...>
<input form="SomeForm" ...>
<input type="submit" form="SomeForm" value="Submit Form 1">
</form>
<form>
<input form="SomeForm" ...>
<input form="SomeForm" ...>
<input type="submit" form="SomeForm" value="Submit Form 2">
</form>
以下是一个表单嵌套的示例,它可以在html5中的某些浏览器上运行(不推荐使用解决方案)。
<form name="SomeForm" id="SomeForm">
<input form="SomeForm" ...>
<input form="SomeForm" ...>
<input type="submit" form="SomeForm" value="Submit Form 1">
<form name="SomeForm2" id="SomeForm2">
<input form="SomeForm2" ...>
<input form="SomeForm2" ...>
<input type="submit" form="SomeForm2" value="Submit Form 2">
</form>
</form>
Wordpress是一款非常受欢迎且非常强大的工具。但是,每当我被迫查看它的代码时,我都会被提醒为什么我不使用它。这是我见过的任何适应性很强的程序中最糟糕的PHP代码。这太糟糕了。如果任何阅读本文的人都在学习PHP 并使用Wordpress作为示例,请帮自己一个忙,并使用任何其他PHP示例代码源。 Wordpress完全是垃圾,代码方面。