//Add phone number field to customer registration
add_filter( 'register_form', 'custom_phone_no_registration_field' );
function custom_phone_no_registration_field( ) {
echo '<div class="form-row form-row-wide"><label for="reg_phone">'.__('Phone Number', 'woocommerce').' <span class="required">*</span></label>
<input type="text" class="input-text" name="phone" id="reg_phone" size="30" value="'.esc_attr($_POST['phone']).'" /></div>';
}
//Validation registration form after submission using the filter registration_errors
add_action('registration_errors', 'custom_registration_errors_validation', 10,3);
function custom_registration_errors_validation($reg_errors, $sanitized_user_login, $user_email) {
global $woocommerce;
extract($_POST); // extracting $_POST into separate variables
if(empty($phone)) :
$woocommerce->add_error( __( 'Please, fill in all the required fields.', 'woocommerce' ) );
endif;
return $reg_errors;
}
I'm using register_form function to add a phone number field to registration form.it works but the registration_errors function is not working. Can anyone please help me with the code ?
I think you need to validate on the woocommerce_process_registration_errors filter. Take a look at process_registration() method in includes/class-wc-form-handler.php.
add_action( 'woocommerce_process_registration_errors', 'custom_registration_error' );
function custom_registration_errors( $validation_error ){
if ( ! isset( $_POST['phone'] ) ){
$validation_error = new WP_Error( 'phone-error', __( 'Please enter a phone number.', 'your-plugin' ) );
}
return $validation_error;
}
Related
I'm very new to payment gateway integration. I learned that, orders can be created programmatically without adding products in woocommerce and done that.
Problem now is, I'm not sure how to automate the payment process once submit order button is clicked.
Currently when the order form is submitted, I create order programmatically into woocommerce and expect the user to redirected to selected(currently by default is billPlz) payment gateway page to make payment.
I already had woocomerce and billPlz payment gateway installed. And WC()->payment_gateways->get_available_payment_gateways() does return me the billPlz.
However the payment form is not shown from the payment gateway for users to submit the payment into the billPlz.
I see 'success' message and redirected to mydomain/order-received/72?key=wc_order_5a0f8f3ead251
I assume this is the Thank you page?
How to redirect to payment gateway when order is created?
Order form (my own, not from woocomerce)
<form action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" method="POST">
<input type="text" name="action" value="createOrder">
<input type="text" name="booking_id" value="123">
<input type="text" name="customer_id" value="1006">
<input type="text" name="order_amount" value="180.00">
<input type="text" name="order_status" value="1">
<input type="submit" value="PROCEED TO MAKE PAYMENT">
</form>
create order function
public function createOrder()
{
$product_id = 222;
$quantity = 1;
$args = array(
'variation' => array( 'attribute_color' => 'red'),
'status' => 'complete',
'customer_id'=> 23
);
$order = wc_create_order();
$order_id = trim(str_replace('#', '', $order->get_order_number()));
$order->add_product( get_product( $product_id ), $quantity, $args );
$order->set_status( $args['status'] );
$order->set_customer_id( is_numeric( $args['customer_id'] ) ? absint( $args['customer_id'] ) : 0 );
$order->set_total( ($discount['amount']/100) , 'order_discount'); // not pennies (use dollar amount)
update_post_meta( $order_id, '_payment_method', 'billplz' );
update_post_meta( $order_id, '_payment_method_title', 'Billplz Payment Gateway' );
$order->calculate_totals();
// Process Payment
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
$result = $available_gateways[ 'billplz' ]->process_payment( $order_id );
// Redirect to success/confirmation/payment page
if ( $result['result'] == 'success' ) {
$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id );
$return_url = $available_gateways[ 'billplz' ]->get_return_url( $order );
wp_redirect($return_url);
exit;
}
}
You can generate a payment URL for unpaid orders like it appears in your My Account page under the Orders TAB by using the following orders function.
$order->get_checkout_payment_url()
I am developing wordpress plugin for Woocommerce payment.
As I can see I have to extend WC_Payment_Gateway and implement method "process_payment". I have looked into some examples and found that this method should return something like:
array(
'result' => 'success',
'redirect' => $redirectUrl
);
and then control is returned to WC_Checkout which will redirect to provided url.
Problem is that our payment provider requires to submit form to his page instead of redirect. Having that API restriction in mind I am asking what is the best way to connect with my payment provider?
Is there a way to submit form instead of redirection?
You can achieve it as illustrated and commented below by extending the WooCommerce WC_Payment_Gateway class with the following methods:
public function __construct() {
$this->id = 'my-payment-gateway';
$this->icon = plugins_url( '/path/to/image.extension', __FILE__ );
$this->has_fields = true;
$this->method_title = __( 'My Payment Gateway', 'txdomain' );
$this->method_description = __( 'Add some descriptions here.', 'txdomain' );
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array(
$this,
'process_admin_options'
) );
// below is the hook you need for that purpose
add_action( 'woocommerce_receipt_' . $this->id, array(
$this,
'pay_for_order'
) );
}
// here, your process payment method, returning the pay for order page
// where you will can submit the form to your payment gateway providers' page
public function process_payment( $order_id ) {
$order = new WC_Order( $order_id );
return array(
'result' => 'success',
'redirect' => $order->get_checkout_payment_url( true )
);
}
// here, prepare your form and submit it to the required URL
public function pay_for_order( $order_id ) {
$order = new WC_Order( $order_id );
echo '<p>' . __( 'Redirecting to payment provider.', 'txtdomain' ) . '</p>';
// add a note to show order has been placed and the user redirected
$order->add_order_note( __( 'Order placed and user redirected.', 'txtdomain' ) );
// update the status of the order should need be
$order->update_status( 'on-hold', __( 'Awaiting payment.', 'txtdomain' ) );
// remember to empty the cart of the user
WC()->cart->empty_cart();
// perform a click action on the submit button of the form you are going to return
wc_enqueue_js( 'jQuery( "#submit-form" ).click();' );
// return your form with the needed parameters
return '<form action="' . 'https://example.com' . '" method="post" target="_top">
<input type="hidden" name="merchant_key" value="">
<input type="hidden" name="success_url" value="">
<input type="hidden" name="cancelled_url" value="">
<input type="hidden" name="deferred_url" value="">
<input type="hidden" name="invoice_id" value="">
<input type="hidden" name="total" value="">
<div class="btn-submit-payment" style="display: none;">
<button type="submit" id="submit-form"></button>
</div>
</form>';
}
I am using theme my login, it is a great plugin. I have used it in many website.
Now, in one of my website I have enabled user moderation module of theme my login. According to it when any new user register on the website, it comes under moderation and when admin approve then only he is able to be a user on the website.
So, I don't want this functionality for subscribers. Or in other words I want this only for authors.
Now I find the solution of this question.
put a dropdown on register-form.php between the form tags like :
<p>
<label for="role<?php $template->the_instance(); ?>"><?php _e( 'Role', 'theme-my-login' ) ?></label>
<select id="role<?php $template->the_instance(); ?>" name="role">
<option value="author">Author</option>
<option value="subscriber">Subscriber</option>
</select>
</p>
then put a function in function.php like :
function set_role_on_registration( $user_id ) {
//$role = sanitize_text_field( $_POST['role'] );
$role = $_POST['role'];
if ( in_array( $role, array( $role, 'bprofessional' ) ) )
add_user_meta( $user_id, 'pending_role', $role );
}
add_action( 'tml_new_user_registered', 'set_role_on_registration' );
then go to plugins/theme-my-login/modules/user-moderation/admin/user-moderation-admin.php and find user_row_actions function. Find case 'admin' : and put the below code in between start of case and its break; like :
$c_u_r = get_user_meta($user_object->ID, 'pending_role', true);
// Add "Approve" link
if($c_u_r != 'subscriber'){
$actions['approve-user'] = sprintf( '%2$s',
add_query_arg( 'wp_http_referer',
urlencode( esc_url( stripslashes( $_SERVER['REQUEST_URI'] ) ) ),
wp_nonce_url( "users.php?action=approve&user=$user_object->ID", 'approve-user' )
),
__('Approve', 'theme-my-login' )
);
}else{
if ( ! self::approve_user( $user_object->ID ) )
wp_die( __( 'You can’t edit that user.' ) );
}
Now the user moderation will not work for the users which registers as a subscriber. Modify the code and use it in your own way.
This may help some one.
Thanks
Sunil
I created a custom meta box where you can choose a value from some radio buttons and save it to the post_meta table in the wordpress database. With the following code I save the value:
function save_value_of_my_custom_metabox ($post_id, $post){
$post_id = get_the_ID();
$new_meta_value = ( isset( $_POST['the_name_of_the_radio_buttons'] ) ? sanitize_html_class( $_POST['the_name_of_the_radio_buttons'] ) : '' );
$meta_key = 'my_key';
update_post_meta( $post_id, $meta_key, $new_meta_value );
}
But if the post will be edited again I want the radio button with the current value to set checked. What is the best way to do that? Here is the function to display the meta box:
function my_custom_meta_box( $object, $box ) {
$post_id=get_the_ID();
$key='my_key';
$the_value_that_should_be_set_to_checked=get_post_meta( $post_id, $key);
//$the_value_that_should_be_set_to_checked[0] returns the value as string
?>
<label for="my_custom_metabox"><?php _e( "Choose value:", 'choose_value' ); ?></label>
<br />
<input type="radio" name="the_name_of_the_radio_buttons" value="value1">Value1<br>
<input type="radio" name="the_name_of_the_radio_buttons" value="value2">Value2<br>
<input type="radio" name="the_name_of_the_radio_buttons" value="value3">Value3<br>
<input type="radio" name="the_name_of_the_radio_buttons" value="value4">Value4<br>
<?php
}
I could write something like if(isset($the_value_that_should_be_set_to_checked[0])=="value of that line") echo "checked='checked'"; in every line but that doesn't seem very elegant to me. Using javascript is also pretty complicated in wordpress because I would have to use the hooks, enqueue the script and just for changing the checked property with one line of javascript it's not worth it. What's the best practice for that?
I am assuming that you are trying to add custom meta box for 'Posts'. Below code will work for you. It will show Radio buttons on add new post or edit post screen. Please read the comments in the code. It will help you in understanding the code.
You can use WordPress's checked function to decide whether to select the radio button or not.
Feel free to ask if you have any doubts.
/**
* Adds a box to the main column on the Post add/edit screens.
*/
function wdm_add_meta_box() {
add_meta_box(
'wdm_sectionid', 'Radio Buttons Meta Box', 'wdm_meta_box_callback', 'post'
); //you can change the 4th paramter i.e. post to custom post type name, if you want it for something else
}
add_action( 'add_meta_boxes', 'wdm_add_meta_box' );
/**
* Prints the box content.
*
* #param WP_Post $post The object for the current post/page.
*/
function wdm_meta_box_callback( $post ) {
// Add an nonce field so we can check for it later.
wp_nonce_field( 'wdm_meta_box', 'wdm_meta_box_nonce' );
/*
* Use get_post_meta() to retrieve an existing value
* from the database and use the value for the form.
*/
$value = get_post_meta( $post->ID, 'my_key', true ); //my_key is a meta_key. Change it to whatever you want
?>
<label for="wdm_new_field"><?php _e( "Choose value:", 'choose_value' ); ?></label>
<br />
<input type="radio" name="the_name_of_the_radio_buttons" value="value1" <?php checked( $value, 'value1' ); ?> >Value1<br>
<input type="radio" name="the_name_of_the_radio_buttons" value="value2" <?php checked( $value, 'value2' ); ?> >Value2<br>
<input type="radio" name="the_name_of_the_radio_buttons" value="value3" <?php checked( $value, 'value3' ); ?> >Value3<br>
<input type="radio" name="the_name_of_the_radio_buttons" value="value4" <?php checked( $value, 'value4' ); ?> >Value4<br>
<?php
}
/**
* When the post is saved, saves our custom data.
*
* #param int $post_id The ID of the post being saved.
*/
function wdm_save_meta_box_data( $post_id ) {
/*
* We need to verify this came from our screen and with proper authorization,
* because the save_post action can be triggered at other times.
*/
// Check if our nonce is set.
if ( !isset( $_POST['wdm_meta_box_nonce'] ) ) {
return;
}
// Verify that the nonce is valid.
if ( !wp_verify_nonce( $_POST['wdm_meta_box_nonce'], 'wdm_meta_box' ) ) {
return;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Check the user's permissions.
if ( !current_user_can( 'edit_post', $post_id ) ) {
return;
}
// Sanitize user input.
$new_meta_value = ( isset( $_POST['the_name_of_the_radio_buttons'] ) ? sanitize_html_class( $_POST['the_name_of_the_radio_buttons'] ) : '' );
// Update the meta field in the database.
update_post_meta( $post_id, 'my_key', $new_meta_value );
}
add_action( 'save_post', 'wdm_save_meta_box_data' );
I found a working solution but I think this is not how you should do it. Still open for better solutions ;)
This code was added under the php code from above:
if(isset($$the_value_that_should_be_set_to_checked[0])){
$the_value_that_should_be_set_to_checked= $the_value_that_should_be_set_to_checked[0];
}
else{
$the_value_that_should_be_set_to_checked='';
}
Here's the code that I added below the radiobuttons:
<script type="text/javascript">
jQuery(document).ready(function () {
var checked_value= <?php echo json_encode($the_value_that_should_be_set_to_checked);?>;
if(checked_value!==''){
jQuery("input[name=the_name_of_the_radio_buttons][value="+checked_value+"]").attr('checked', 'checked');
}
});
</script>
P.S.: The $ selector will not work but that maybe depends on the theme you use.
From what I read in the net, the following code should be adding a "City" field in the user registration form of Wordpress.
Thing is that, it seems to be not working - I don't see the additional "City" field in the user form.
Any help appreciated.
add_action( 'register_form', 'extended_register_form' );
add_filter('registration_errors', 'myplugin_registration_errors', 10, 3);
add_action('user_register', 'myplugin_user_register');
function extended_register_form() {
$city = ( isset( $_POST['city'] ) ) ? $_POST['city']: '';
?>
<p>
<label for="city">City<br />
<input type="text" name="city" id="city" class="input" value="<?php echo esc_attr(stripslashes($city)); ?>" size="25" /></label>
</p>
<?
}
function myplugin_registration_errors ($errors, $sanitized_user_login, $user_email) {
if ( empty( $_POST['city'] ) )
$errors->add( 'city_error', __('<strong>ERROR</strong>: You must include a city.') );
return $errors;
}
function myplugin_user_register ($user_id) {
if ( isset( $_POST['city'] ) )
update_user_meta($user_id, 'city', $_POST['city']);
}
Since Wordpress 3.0.0, the action to call is "signup_extra_fields" instead of "register_form", so you should use:
add_action( 'signup_extra_fields', 'extended_register_form' );
I tried your code and it worked perfectly, perhaps it is because of the <? in line 12... Try <?php instead...
Where have you added the code? As a plugin or in the functions.php of your theme?