So I'm trying to follow this tutorial but what I want to do is a bit different.
I want to have a unique link per coupon generator and the coupon is per customer and can only be used once (e.g. example.com/coupon/7AD8679adO).
Now I want to have a form for this page and just have a input boxes for users like first_name, last_name, and email. And the email field is the identifier that the current url coupon will be registered to that email.
I also tried to research and I found out that there's URL Coupons feature from Woocommerce (Not sure though if this is exactly what Im looking for), but suddenly, it is not free. So, any idea with this?
I have implemented rewrite rule in "twentytwentyone" theme, but you may implement it elsewhere in wordpress.
For more info, please refer to this.
https://developer.wordpress.org/reference/functions/add_rewrite_rule/
Implement in wordpress Theme
Add the following code to the bottom of next file
~/wp-content/themes/twentytwentyone/functions.php
// wp-content/themes/twentytwentyone/functions.php
...
// rewrite-rule
add_action( 'init', function() {
add_rewrite_rule( 'coupon/([a-zA-Z0-9]+)[/]?$', 'index.php?coupon=$matches[1]', 'top' );
} );
// whitelist "coupon" param
add_filter( 'query_vars', function( $query_vars ) {
$query_vars[] = 'coupon';
return $query_vars;
} );
// set template php file
add_action( 'template_include', function( $template ) {
if ( get_query_var( 'coupon' ) == false || get_query_var( 'coupon' ) == '' ) {
return $template;
}
//You can return wherever you want to go
return get_template_directory() . '/template-coupon.php';
} );
Create ~/wp-content/themes/twentytwentyone/template-coupon.php
// wp-content/themes/twentytwentyone/template-coupon.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo get_query_var( 'coupon' )." from POST".PHP_EOL;
var_dump($_POST);
// check coupon validation here
// $query = $wpdb->prepare("SELECT 1"); // Your query
// $result = $wpdb->get_var($query);
// var_dump($result);
} else {
echo get_query_var( 'coupon' )." from redirection GET".PHP_EOL;
// do something
}
?>
<?php //get_template_part( 'header' ); ?>
<form action="" method="POST">
<label for="first_name">First Name</label><input type="text" name="first_name" id="first_name"><br/>
<label for="last_name">Last Name</label><input type="text" name="last_name" id="last_name"><br/>
<label for="email">Email</label><input type="text" name="email" id="email"><br/>
<input type="submit">
</form>
<?php //get_template_part( 'footer' ); ?>
Implement in wordpress Plugin (Hello Dolly)
Add the above step 1 code to the bottom of next file
~/wp-content/plugins/hello.php
change
return get_template_directory() . '/template-coupon.php';
to
return __DIR__ . '/template-coupon.php';
Add the above step 2 code to ~/wp-content/plugins/template-coupon.php
Refresh permalinks cache
When you add/modify URL part in step1, you need to refresh permalniks cache, otherwise wordress does not apply rewrite rule.
Settings > Permalinks > Save Changes
Result
check http://your-domain/coupon/7AD8679adO/
I'm pretty sure you've seen this answer elsewhere, but I hope this is written clearly enough for you to understand it better.
It seems as though you may need to implement the "add_rewrite_rule()" in order for WordPress to recognise the element (the unique "/coupon/URL") and pass on the resulting code to the right page.
Additionally, it can sometimes be a bit more difficult to verify a coupon code without the user being logged into an account that can be relied on.
Therefore, I would recommend trying to store the uniquely generated "/coupon/URL" in the user's meta data, and then querying for the unique in the user's meta data, and validating the request if the current user and the related user's ID match. This is because the code doesn't just get tied to the email address, but also to a registered user.
Related
I've looked through lots of documents, few of them showed a shortcode to display the avatar using user_id.
The closest one is from Github, and it displays the current logged-in user, like this:
<?php
function shortcode_user_avatar() {
if(is_user_logged_in()) { // check if user is logged in
global $current_user; // get current user's information
get_currentuserinfo();
return get_avatar( $current_user -> ID, 24 ); // display the logged-in user's avatar
}
else {
// if not logged in, show default avatar. change URL to show your own default avatar
return get_avatar( 'http://1.gravatar.com/avatar/ad524503a11cd5ca435acc9bb6523536?s=64', 24 );
}
}
add_shortcode('display-user-avatar','shortcode_user_avatar');
?>
But this isn't enough, what I want is to add a parameter for me to choose the userid, and it will end like this:
[display-user-avatar id="user-id"]
Can anybody show me the way to make it?
Thanks!
I've already solve this problem, here is the code:
function shortcode_user_avatar($atts, $content = null) {
extract( shortcode_atts(
array('id' => '0',), $atts
)
);
return get_avatar( $user_id, 96 ); // display the specific user_id's avatar
}
add_shortcode('avatar','shortcode_user_avatar');
Just paste it to theme's functions.php and enter the shortcode [avatar id="xxx"], and replace "xxx" to the user id.
It's actually my first shortcode, and I'm really happy that it's working!
question regarding Woocommerce payment gateways.
I’ve customized a payment gateway to take purchase orders, and its loading correctly from a plugin, and appearing on the checkout page the way id like it to; I think its a pretty good start.
Anyway, I have a non-standard form entry (purchase order number) that id like people to fill out, but I don’t know how to attach it to my custom payment gateway so that it appears on the resulting admin side page.
This all works fine:
function payment_fields(){
if ( $description = $this->get_description() )
echo wpautop( wptexturize( $description ) );
global $woocommerce;
?>
<form class="form-horizontal" role="form" id="bv-form">
<fieldset>
<!-- Form Name -->
<legend>Purchase Order</legend>
<!-- Text input-->
<div class="form-group">
<label class="control-label" for="po_no">PO Number</label>
<div class="">
<input id="po_no" name="po_no" type="text" placeholder="" class="form-control input-md">
</div>
</div>
...
But when I get here, I don’t know how to modify process_payment( $order_id ) (or what to add to functions.php) to grab the form values from the payment fields. I see that there are $order->billingAddress1 etc., how would I submit the extra couple form fields along with the order, and then secondly, how would I access that to get po_no out of the newly created WC_Order?
WP: 3.9.2
WC: 2.1.11
Thanks for your help!
If you are creating a custom Payment Gateway then you should be implementing process_payment() within it. This code will have access to the $_POST variables were submitted by the payment form, so you can refer to it as:
$po_number = ( isset( $_POST['po_no'] ) )? $_POST['po_no'] : 0;
That said it sounds like from your question you may not be actually writing a custom gateway and are instead trying to attach custom fields to the order. If you want to hook into another gateway (like PayPal, Authorize.net, etc) then you should use the WooCommerce action hooks that are called as part of WC_Order.payment_complete() which is what the gateway calls after it collects payment. The actions are woocommerce_pre_payment_complete which runs before anything else and takes the order id as an argument, and woocommerce_payment_complete after stock/statuses/etc are set.
add_action( 'woocommerce_payment_complete', 'my_woocommerce_payment_complete');
function my_woocommerce_payment_complete( $order_id ){
$po_number = ( isset( $_POST['po_no'] ) )? $_POST['po_no'] : 0;
update_post_meta( $order_id, 'po_number', $po_number );
}
You can then display this custom field on the Order Edit page by adding a meta box. You'll need to hook into save_post and change the po_number to an input if you want to make it editable.
add_action( 'add_meta_boxes', 'po_number_metabox' );
function add_po_number_metabox(){
global $post;
if ( $post->post_type = 'shop_order' ){
add_meta_box( 'po-number', 'Title', 'po_number_metabox', 'shop_order', 'side', 'default');
}
}
function po_number_metabox(){
global $post;
$po_number = get_post_meta( $post->ID, 'po_number', true);
echo "PO:> {$po_number}";
}
Here is my predicament right now, I currently run a Minecraft Server as alot of people in my community like to play it. The way I currently have it set up, users who sign up on the website have access to the Minecraft server. Minecraft connects to the database and checks to see if they have registered or if their name is there at all. But the problem with this is that users have to sign up with their Minecraft username, some user;s do not like to do that. Right now I would just like a column in wp_users to display a customizable text field saying Minecraft username.
Sorry if this is a duplicate at all.
Thank you for the help.
Instead of creating a new column in the wp_users table which I would advise against, you can use user metadata. You can update and get usermeta.
If you are wanting to code this yourself I think you will need to create your own signup form and the accompanying PHP file to handle it as I don't think there are the correct hooks to get everything you need, although I could be wrong. I'm happy to run you through this if required.
Otherwise, you could try some plugins, although I've not done this. Perhaps this or this - Note I've not tried either of these and not 100% sure they will do what you are after.
To save and show user meta fields on the users profile, try this in your functions.php file;
<?php
add_action( 'show_user_profile', 'add_user_meta_fields' );
add_action( 'edit_user_profile', 'add_user_meta_fields' );
add_action( 'personal_options_update', 'update_user_meta_fields' );
add_action( 'edit_user_profile_update', 'update_user_meta_fields' );
function update_user_meta_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) ) { return false; }
update_user_meta( $user_id, 'mincraftUser', $_POST['mincraftUser'] );
}
function add_user_meta_fields( $user ) { ?>
<h3>Extra Custom Meta Fields</h3>
<table class="form-table">
<tr>
<th><label for="mincraftUser">Twitter User Name</label></th>
<td>
<input type="text" id="mincraftUser" name="mincraftUser" size="20" value="<?php echo esc_attr( get_the_author_meta( 'mincraftUser', $user->ID )); ?>">
<span class="description">Please enter your Twitter Account User name, eg: oneTarek</span>
</td>
</tr>
</table>
<?php }
i will create new post type in my wordpress called "Food" , and i need to add any new post in this post type to user register in my site.
so when i add new post in my post type "Food" , i need to select this post for which user.
how can make this.
thankx
you're in luck today as i am currently doing what you are asking :)
wordpress only displays users with a role of author. basically you have to remove authordiv meta box, add another meta box with the same html as the original authordiv, find users with correct role/capability and build a select, so the code below is my implementation, you'll need to modify it to suit your needs:
// add authordiv if user is admin or is allowed to change author of post !important
global $current_user;
if(in_array(array('administrator','change_post_author'), $current_user->allcaps))
add_meta_box('authordiv', 'Change Author', 'my_add_author_metabox', get_post_type(), 'side');
// make new author metabox that contains users that can manage this cpt
function my_add_author_metabox()
{
$post_type_name = isset($_GET['post_type']) ? $_GET['post_type'] : get_post_type($_GET['post']);
$roles = get_editable_roles();
// i unset these as they are never used
unset(
$roles['administrator'],
$roles['contributor'],
$roles['author'],
$roles['editor'],
$roles['subscriber']
);
// get role that manages this cpt
$cpt_name = '';
$cap = 'edit_' . $post_type_name;
foreach($roles as $role_name => $args){
if(array_key_exists($cap, $args['capabilities'])){
$cpt_name = $role_name;
break;
}
}
// get users that can manage this cpt
global $post;
$users = get_users('role=' . $cpt_name);
$author_id = $post->post_author;
$select = '
<label class="screen-reader-text" for="post_author_override">Change Author</label>
<select name="post_author_override" id="post_author_override" class="">
';
foreach($users as $user){
if($user->ID == $author_id)
$select .= "<option value=\"{$user->ID}\" selected=\"selected\">{$user->display_name}</option>";
else
$select .= "<option value=\"{$user->ID}\">{$user->display_name}</option>";
}
$select .= '</select>';
echo $select;
}
now in my cpt i dont support author but if you do then either remove author from supports when you register_post_type() or use
remove_meta_box('authordiv');
hopefully it works for you, it works for me. there probably is a better, and if you ever come across it, post it back here :)
I wanted to create a plugin to batch manage posts' custom field data. I know I can add post meta by adding a meta box in the post edit screen and using add_action('save_post', 'function_to_update_meta') to trigger add meta functions.
But I don't know how to trigger the add_post_meta function in an admin menu page (such as a custom admin menu). How to do that?
Thank you in advance!
The example given in Wordpress' codex is probably the best and most secure in the way of processing information:
Add Meta Box
Copy and paste it and then fiddle around with it to get a good idea on how to control your posts and pages.
The nice part is that you don't need to worry about checking if you need to Add vs Update a given Post Meta field. Using Update Post Meta will ensure that the proper action is taken for you, even if the field doesn't exist.
The same goes for Update Option if you want to add some global controls that your plugin/theme might use.
BREAKDOWN EXAMPLE:
add_action( 'add_meta_boxes', 'myplugin_add_custom_box' );
add_action( 'save_post', 'myplugin_save_postdata' );
These are the action hooks. The first one is executed when meta boxes are being populated within the post editor, and the second is executed when a post is added OR updated.
function myplugin_add_custom_box()
{
add_meta_box(
'myplugin_sectionid',
__( 'My Post Section Title', 'myplugin_textdomain' ),
'myplugin_inner_custom_box',
'post'
);
add_meta_box(
'myplugin_sectionid',
__( 'My Post Section Title', 'myplugin_textdomain' ),
'myplugin_inner_custom_box',
'page'
);
}
This function is called by the 'add_meta_boxes' action hook. Notice the name of the function and the second argument of the action hook are exactly the same. This registers your meta boxes, which post types they're supposed to appear, and what callback is used to generate the form contained inside.
function myplugin_inner_custom_box( $post )
{
wp_nonce_field( plugin_basename( __FILE__ ), 'myplugin_noncename' );
$value = get_post_meta($post->ID, 'myplugin_new_field') ? get_post_meta($post->ID, 'myplugin_new_field') : 'New Field';
echo '<label for="myplugin_new_field">';
_e("Description for this field", 'myplugin_textdomain' );
echo '</label> ';
echo '<input type="text" id="myplugin_new_field" name="myplugin_new_field" value="'.$value.'" size="25" />';
}
This is the function that is called by the registered meta boxes to generate the form automatically. Notice how the function is called 'myplugin_inner_custom_box' and the 3rd argument in your meta box registration is also called 'myplugin_inner_custom_box'.
The wp_nonce_field() generates a hidden field in your form to verify that data being sent to the form actually came from Wordpress, and can also be used to end the function in case other plugins are using the 'save_post' action hook.
Notice also that the $post object is being passed in as an argument. This will allow you to use certain properties from the post object. I've taken the liberty of checking to see if there is get_post_meta() returns anything with the given post ID. If so, the field is filled with that value. If not, it is filled with 'New Field'.
function myplugin_save_postdata( $post_id )
{
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename( __FILE__ ) ) )
return;
if ( 'page' == $_POST['post_type'] )
{
if ( !current_user_can( 'edit_page', $post_id ) )
return;
}
else
{
if ( !current_user_can( 'edit_post', $post_id ) )
return;
}
$mydata = $_POST['myplugin_new_field'];
update_post_meta($post_id, 'myplugin_new_field', $mydata);
}
This is the function that is called by the 'save_post' action hook. Notice how the second argument of the second action hook and this function are both called 'myplugin_save_postdata'. First, there are a series of verifications our plugin must pass before it can actually save any data.
First, we don't want our meta boxes to update every time the given post is auto-updating. If the post is auto-updating, cancel the process.
Secondly, we want to make sure the nonce data is available and verify it. If no nonce data is available or is not verified, cancel the process.
Thirdly, we want to make sure the given user has the edit_page permission. The function first checks the post type, and then checks the appropriate permission. If the user does not have that permission, cancel the process.
Lastly, our plugin has finally been verified and we want to save the information. I took the liberty of adding in the final update_post_meta() line to show you how it all comes together.
Notice how $post_id was passed into the function as an argument. This is one of the pieces needed for the update_post_meta() function. The key was named 'myplugin_new_field' and the value of that metadata is now saved as whatever you input into that custom input field in your custom meta box.
That's about as easy as I can explain the whole process. Just study it, and get your hands dirty with code. The best way to learn is through application rather than theory.
The answer was from the same question I asked somewhere else
And I created my version of example
I added some console.log function for testing, but this is basically doning the same thing as #Chris_() answer:
Menu callback function to generate menu content (PHP):
function ajax_menu_callback() {
?>
<div class="wrap">
<div id="icon-themes" class="icon32"></div>
<h2>Test</h2>
<br />
<form>
<input id="meta" type ="text" name="1" value="<?php echo esc_html( get_post_meta( 1, 'your_key', true) ); ?>" />
<?php submit_button(); ?>
</form>
</div>
<?php
}
Then the javascript to print on the admin side (javascript, don't forget to include a jquery library):
jQuery(document).ready(function() {
$("form").submit(function() {
console.log('Submit Function');
var postMeta = $('input[name="1"]').val();
console.log(postMeta);
var postID = 1;
var button = $('input[type="submit"]');
button.val('saving......');
$.ajax({
data: {action: "update_meta", post_id: postID, post_meta: postMeta, },
type: 'POST',
url: ajaxurl,
success: function( response ) { console.log('Well Done and got this from sever: ' + response); }
}); // end of ajax()
return false;
}); // end of document.ready
}); // end of form.submit
Then the PHP function handle update_post_meta (PHP):
add_action( 'wp_ajax_update_meta', 'my_ajax_callback' );
function my_ajax_callback() {
$post_id = $_POST['post_id'];
$post_meta = $_POST['post_meta'];
update_post_meta( $post_id, 'your_key', $post_meta );
echo 'Meta Updated';
die();
} // end of my_ajax_callback()