I've got a basic email form that I want to use a custom handler on. I tried following this tutorial https://blog.osmosys.asia/2016/05/07/handling-form-submissions-in-wordpress/ but it seems that my custom hook is not being called.
<form class="" action="<?php echo admin_url('admin-post.php') ?>" method="post">
<input type="hidden" name="action" value="bb_submit_email">
<input type="email" id="email" name="email" value="example#email.com" required>
<?php wp_nonce_field('submit-email', '_mynonce'); ?>
<input type="submit" class="float-right btn btn-primary form-button" value="Submit">
</form>
<?php
add_action('admin_post_bb_submit_email', 'bb_handle_email_submit');
add_action('admin_post_nopriv_bb_submit_email', 'bb_handle_email_submit');
function bb_handle_email_submit() {
$logger = wc_get_logger();
$logger->add('submit-email-debug', 'triggered!');
if ( !isset($_POST['_mynonce']) || !wp_verify_nonce($_POST['_mynonce'], 'register-user')) {
return;
}
wp_remote_post('example.com', $_POST );
}
I tried using wp_ajax instead but that didn't work either. Anyone see something I'm missing here?
Update: I don't know if this helps but I checked the POST Request data and it has the following:
action: bb_submit_email
email: example#email.com
_mynonce: a2c0e80de7
_wp_http_referer: /
That all looks right to me?
I moved this
<?php
add_action('admin_post_bb_submit_email', 'bb_handle_email_submit');
add_action('admin_post_nopriv_bb_submit_email', 'bb_handle_email_submit');
function bb_handle_email_submit() {
$logger = wc_get_logger();
$logger->add('submit-email-debug', 'triggered!');
if ( !isset($_POST['_mynonce']) || !wp_verify_nonce($_POST['_mynonce'], 'register-user')) {
return;
}
wp_remote_post('example.com', $_POST );
}
to functions.php and it started working. Honestly not sure why?
Related
I'm using admin_post_{$action} to handle the form. I just copy-paste the example from https://developer.wordpress.org/reference/hooks/admin_post_action/.
I created front-page.php in the theme directory and just paste in:
<form action="http://www.example.com/wp-admin/admin-post.php" method="post">
<input type="hidden" name="action" value="our_action_hook">
<input type="submit" value="Submit">
</form>
Then this in the functions.php :
add_action( 'admin_post_our_action_hook', 'am_our_action_hook_function' );
function am_our_action_hook_function() {
// do something
}
But I got an error in the console: 400 bad request . If I make this as a plugin, it works. But if I do it in a theme, it doesn't...
Error 400 shows your request is not valid from your side.
you can check the console-> network and you can find the your request.
anyway, replace the form action with this:
<form action="<?php echo admin_url( 'admin-post.php' ); ?>" method="post">
<input type="hidden" name="action" value="our_action_hook">
<input type="submit" value="Submit">
</form>
I'm working with this avatar community engine built on CodeIgniter, everything is working except the shop system.
Every time I try to buy an item I get this:
An Error Was Encountered
shop_item_id must be valid
I've narrowed the problem to this piece of code:
public function purchase_item()
{
$shop_item_id = $this->input->post('item_id');
if(!is_numeric($shop_item_id)) show_error('shop_item_id must be valid');
$shop_item_query = $this->db->join('avatar_items', 'avatar_items.item_id = shop_items.item_id')->get_where('shop_items', array('shop_item_id' => $shop_item_id));
if($shop_item_query->num_rows() > 0):
$shop_item_data = $shop_item_query->row_array();
else:
show_error('shop_item could not be found.');
endif;
$shop_id = $shop_item_data['shop_id'];
if ( ! $shop_data = $this->cache->get('shop_data_'.$shop_id)):
$shop_data = $this->db->get_where('shops', array('shop_id' => $shop_id))->row_array();
$this->cache->save('shop_data_'.$shop_id, $shop_data, 2400);
endif;
What is the solution?
p.s: I'm using the script of crysandrea (https://github.com/tylerdiaz/Crysandrea). I need this for my assignment.
Here's the code:
<form action="/shops/purchase_item/" method="POST">
<input type="hidden" name="item_id" value="<?php echo $item_data['shop_item_id'] ?>" />
<button type="submit" class="main_button">Purchase item</button>
</form>
You forget semicolon. now try following code
<form action="/shops/purchase_item/" method="POST">
<input type="hidden" name="item_id" value="<?php echo $item_data['shop_item_id']; ?>" />
<button type="submit" class="main_button">Purchase item</button>
</form>
You should write this code in function
if(!is_numeric((int)$shop_item_id)) show_error('shop_item_id must be valid');
I have a Tokening function like this:
public static function create() {
$int = random_int(8, 64);
$ssl = openssl_random_pseudo_bytes(32);
$base64 = base64_encode($ssl);
return Session::put(Config::get('session/token_name'), trim($base64, '='));
}
My tokening function is working, the problem occurs when I tried it now on multiple forms Note: same page
This is my form (example, I only changed the names but that's on my code):
<form method="post">
<input type="hidden" name="t_sample1" value="<?php echo Token::make(); ?>">
<button name="btn1">sample1</button>
</form>
<form method="post">
<input type="hidden" name="t_sample2" value="<?php echo Token::make(); ?>">
<button name="btn2">sample2</button>
</form>
<form method="post">
<input type="hidden" name="t_sample3" value="<?php echo Token::make(); ?>">
<button name="btn3">sample3</button>
</form>
<form method="post">
<input type="hidden" name="t_sample4" value="<?php echo Token::make(); ?>">
<button name="btn4">sample4</button>
</form>
Then, I am only trying this tokening style because I changed my Tokening function from md5(uniqid()) style because they said it is not safe and I read alot of expert tips and said go for openssl then base64_encode it. This is the php code for determining if what form is clicked.
if(Input::exists()) {
if(Token::check(Input::get('t_sample1'))) {
$echo = 'sample1';
}
if(Token::check(Input::get('t_sample2'))) {
$echo = 'sample2';
}
if(Token::check(Input::get('t_sample3'))) {
$echo = 'sample3';
}
if(Token::check(Input::get('t_sample4'))) {
$echo = 'sample4';
}
}
Now the problem is, when I try to click the button sample1-sample3 my token::check is false, but only sample4 does token::check go true. It seems that only the last form will only have a correct token. So I am looking for help how to figure it out how to make the other sample(1-3) go true under token::check, btw the md5(uniqid()) tokening function is working.
is there any server side form validation in magento? i have created a from and using magentos form validation but its not gonna work if someone disable the javascipt and enters something that can be harmful. if there is no built in class for that. could someone please point me in a direction how to implement a server side form validation as a backup. here is my my code for the form
<div style="border:0px solid red; margin:0px auto;">
<?php $_product = $this->getProduct(); ?>
<form id="test" action="<?php echo Mage::getUrl('pricenotify/pricenotify/db') ?>" method="post">
<label for="price">Price *</label>
<input type="text" id="price" name="price" value="" class="required-entry validate-number"/><br />
<label for="email">Email Address *</label>
<input type="text" id="email" name="email" value="" class="required-entry validate-email"/>
<input type="hidden" id="id" name="id" value="<?php echo $_product->getId() ?>" />
<input type="hidden" id="propri" name="propri" value="<?php echo $_product->getPrice() ?>" />
<input type="submit" name="submit" value="<?php echo $this->__('Submit') ?>" onclick="if(customForm.validator && customForm.validator.validate()) this.form.request(); return false;" />
</form>
<script type="text/javascript">
//< ![CDATA[
var customForm = new VarienForm('test',false);
//]]>
</script>
If you want to keep it simple, you could do the validation in your controller
try {
$postObject = new Varien_Object();
$postObject->setData($post);
$error = false;
if (!Zend_Validate::is($postObject->getPrice(), 'NotEmpty')) {
$error = true;
}
if (!Zend_Validate::is($postObject->getEmail(), 'EmailAddress')) {
$error = true;
}
if ($error) {
throw new Exception();
}
//save to db
return;
} catch (Exception $e) {
Mage::getSingleton('customer/session')->addError(Mage::helper('pricenotify')->__('Unable to submit your request. Please, try again later'));
$this->_redirect('/');
return;
}
Zend_Validate : http://files.zend.com/help/Zend-Framework/zend.validate.html
Yes, Magento has server-side validation for some forms. However, the module that added the form is responsible for validating it - so if you're dealing with third-party code like a plugin, it might not be there.
Conventionally, the validation code lives with the Model part of a module. For example, in Magento's built-in review functionality, when a review form is submitted, its data is validated by the validate() function in the /app/code/core/Mage/Review/Model/Review.php file. I'd start by looking at that code, and the code in existing Mage/Core modules for examples.
In the situation that you give, the conventional place for the validation logic would be /app/code/local/YourCompany/PriceNotify/Model/Pricenotify.php
Magento uses prototype to validate forms. To implement this validation, just add "required-entry" to your input tag.
I have a simple form for a mailing list that I found at http://www.notonebit.com/projects/mailing-list/
The problem is when I click submit all I want it to do is display a message under the current form saying "Thanks for subscribing" without any redirect. Instead, it directs me to a completely new page.
<form method="POST" action="mlml/process.php">
<input type="text" name="address" id="email" maxlength="30" size="23">
<input type="submit" value="" id="submit"name="submit" >
</form>
You will need AJAX to post the data to your server. The best solution is to implement the regular posting, so that will at least work. Then, you can hook into that using Javascript. That way, posting will work (with a refresh) when someone doesn't have Javascript.
If found a good article on posting forms with AJAX using JQuery .
In addition, you can choose to post the data to the same url. The JQuery library will add the HTTP_X_REQUESTED_WITH header, of which you can check the value in your server side script. That will allow you to post to the same url but return a different value (entire page, or just a specific response, depending on being an AJAX request or not).
So you can actually get the url from your form and won't need to code it in your Javascript too. That allows you to write a more maintanable script, and may even lead to a generic form handling method that you can reuse for all forms you want to post using Ajax.
Quite simple with jQuery:
<form id="mail_subscribe">
<input type="text" name="address" id="email" maxlength="30" size="23">
<input type="hidden" name="action" value="subscribe" />
<input type="submit" value="" id="submit"name="submit" >
</form>
<p style="display: none;" id="notification">Thank You!</p>
<script>
$('#mail_subscribe').submit(function() {
var post_data = $('#mail_subscribe').serialize();
$.post('mlml/process.php', post_data, function(data) {
$('#notification').show();
});
});
</script>
and in your process.php:
<?php
if(isset($_POST['action'])) {
switch($_POST['action']) {
case 'subscribe' :
$email_address = $_POST['address'];
//do some db stuff...
//if you echo out something, it will be available in the data-argument of the
//ajax-post-callback-function and can be displayed on the html-site
break;
}
}
?>
It redirects to a different page because of your action attribute.
Try:
<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="text" name="address" id="email" maxlength="30" size="23" />
<input type="submit" value="" id="submit" name="submit" />
</form>
<?php if (isset($_POST['submit'])) : ?>
<p>Thank you for subscribing!</p>
<?php endif; ?>
The page will show your "Thank You" message after the user clicks your submit button.
Also, since I don't know the name of the page your code is on, I inserted a superglobal variable that will insert the the filename of the currently executing script, relative to the document root. So, this page will submit to itself.
You have to use AJAX. But that requires JavaScript to be active at the users Brwoser.
In my opinion it's the only way to do without redirect.
to send a form request without redirecting is impossible in php but there is a way you can work around it.
<form method="post" action="http://yoururl.com/recv.php" target="_self">
<input type="text" name="somedata" id="somedata" />
<input type="submit" name="submit" value="Submit!" />
</form>
then for the php page its sending to have it do something but DO NOT echo back a result, instead simply redirect using
header( 'Location: http://yourotherurl.com/formpage' );
if you want it to send back a success message simply do
$success = "true";
header( 'Location: http://yourotherurl.com/formpage?success='.$success);
and on the formpage add
$success = $_GET['success'];
if($success == "true"){ echo 'Your success message'; } else { echo
'Your failure message';
Return and print the contents of another page on the current page.
index.php
<html>
<body>
<p>index.php</p>
<form name="form1" method="post" action="">
Name: <input type="text" name="search">
<input type="submit">
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$_POST['search'];
include 'test.php';
}
?>
</body>
</html>
test.php
<?php
echo 'test.php <br/>';
echo 'data posted is: ' . $_POST['search'];
?>
Result:
Just an idea that might work for you assuming you have no control over the page you are posting to:
Create your own "proxy php target" for action and then reply with the message you want. The data that was posted to your php file can then be forwarded with http_post_data (Perform POST request with pre-encoded data). You might need to parse it a bit.
ENGLISH Version
It seems that no one has solved this problem without javascript or ajax
You can also do the following.
Save a php file with the functions and then send them to the index of your page
Example
INDEX.PHP
<div>
<?php include 'tools/edit.php';?>
<form method="post">
<input type="submit" name="disable" value="Disable" />
<input type="submit" name="enable" value="Enable" />
</form>
</div>
Tools.php (It can be any name, note that it is kept in a folder lame tools)
<?php
if(isset($_POST['enable'])) {
echo "Enable";
} else {
}
if(isset($_POST['disable'])) {
echo "Disable";
} else {
}
?>
Use
form onsubmit="takeActions();return false;"
function takeAction(){
var value1 = document.getElementById('name').innerHTML;
// make an AJAX call and send all the values to it
// Once , you are done with AJAX, time to say Thanks :)
document.getElementById('reqDiv').innerHTML = "Thank You for subscribing";
}