Wordpress add_meta_box does not do anything - php

I can't seem to get the Wordpress add_meta_box to work.
It is adding the boxes in the edit page, but it isn't reflected in the input boxes anywhere.
How can I get this to work? Is there anything I'm doing wrong? I followed this tutorial.
// Add support for header images
if(function_exists('add_theme_support')){
add_theme_support('post-thumbnails'); // Adds this for both pages and posts, For posts/page only, see https://codex.wordpress.org/Function_Reference/add_theme_support
}
// Callback for adding metaboxes
function actionblock_add_meta_box(){
$screens = array( 'post', 'page' );
foreach ( $screens as $screen ) {
add_meta_box('action_block', 'Action Block', 'actionblock_meta_box_callback', $screen, 'normal'); // Add the action block to both post and page screens
}
}
// Add meta boxes for action section on each post/page
add_action('add_meta_boxes', 'actionblock_add_meta_box');
function actionblock_meta_box_callback($post){
// Security check
wp_nonce_field('actionblock_save_meta_box_data', 'actionblock_meta_box_nonce');
// Get values of the action block fields
$action_prompt_text = get_post_meta($post->ID, 'actionblock_meta_prompt_text', true);
$action_button_text = get_post_meta($post->ID, 'actionblock_meta_button_text', true);
$action_button_link = get_post_meta($post->ID, 'actionblock_meta_button_link', true);
// Display and populate fields from the database if it exists
?>
<p>
<label for="action_prompt_text">Action Prompt</label><br>
<input class="widefat" type="text" name="action_prompt_text" id="action_prompt_text" placeholder="This should be short, to the point and less salesy." value="<?php echo esc_attr($action_prompt_text); ?>">
</p>
<p>
<label for="action_button_text">Action Button Text</label><br>
<input class="widefat" type="text" name="action_button_text" id="action_button_text" placeholder="This should prompt the visitor to take an action." value="<?php echo esc_attr($action_button_text); ?>">
</p>
<p>
<label for="action_button_link">Action Button Link</label><br>
<input class="widefat" type="url" name="action_button_link" id="action_button_link" placeholder="Copy and paste the link from the intended page." value="<?php echo esc_attr($action_button_link); ?>">
</p>
<?php
// Callback for saving metaboxes
function actionblock_save_meta_box_data($post_id) {
// Security checks
if(!isset($_POST['actionblock_meta_box_nonce'])) return;
if(!wp_verify_nonce($_POST['actionblock_meta_box_nonce'], 'actionblock_save_meta_box_data')) return;
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
// Do the save/update
if(isset($_POST['action_prompt_text'])){
update_post_meta($post_id, 'actionblock_meta_prompt_text', sanitize_text_field($_POST['action_prompt_text']));
}
if(isset($_POST['action_button_text'])){
update_post_meta($post_id, 'actionblock_meta_button_text', sanitize_text_field($_POST['action_button_text']));
}
if(isset($_POST['action_prompt_link'])){
update_post_meta($post_id, 'actionblock_meta_button_link', esc_url($_POST['action_prompt_link']));
}
}
// Save action block details when the post is saved/updated
add_action('save_post', 'actionblock_save_meta_box_data');

Try Below code :
// Add support for header images
if(function_exists('add_theme_support')){
add_theme_support('post-thumbnails'); // Adds this for both pages and posts, For posts/page only, see https://codex.wordpress.org/Function_Reference/add_theme_support
}
// Callback for adding metaboxes
function actionblock_add_meta_box(){
$screens = array( 'post', 'page' );
foreach ( $screens as $screen ) {
add_meta_box('action_block', 'Action Block', 'actionblock_meta_box_callback', $screen, 'normal'); // Add the action block to both post and page screens
}
}
// Add meta boxes for action section on each post/page
add_action('add_meta_boxes', 'actionblock_add_meta_box');
function actionblock_meta_box_callback($post){
// Security check
wp_nonce_field('actionblock_save_meta_box_data', 'actionblock_meta_box_nonce');
// Get values of the action block fields
$action_prompt_text = get_post_meta($post->ID, 'actionblock_meta_prompt_text', true);
$action_button_text = get_post_meta($post->ID, 'actionblock_meta_button_text', true);
$action_button_link = get_post_meta($post->ID, 'actionblock_meta_button_link', true);
// Display and populate fields from the database if it exists
?>
<p>
<label for="action_prompt_text">Action Prompt</label><br>
<input class="widefat" type="text" name="action_prompt_text" id="action_prompt_text" placeholder="This should be short, to the point and less salesy." value="<?php echo esc_attr($action_prompt_text); ?>">
</p>
<p>
<label for="action_button_text">Action Button Text</label><br>
<input class="widefat" type="text" name="action_button_text" id="action_button_text" placeholder="This should prompt the visitor to take an action." value="<?php echo esc_attr($action_button_text); ?>">
</p>
<p>
<label for="action_button_link">Action Button Link</label><br>
<input class="widefat" type="url" name="action_button_link" id="action_button_link" placeholder="Copy and paste the link from the intended page." value="<?php echo esc_attr($action_button_link); ?>">
</p>
<?php
}
// Callback for saving metaboxes
function actionblock_save_meta_box_data($post_id) {
// Security checks
if(!isset($_POST['actionblock_meta_box_nonce'])) return;
if(!wp_verify_nonce($_POST['actionblock_meta_box_nonce'], 'actionblock_save_meta_box_data')) return;
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
// Do the save/update
if(isset($_POST['action_prompt_text'])){
update_post_meta($post_id, 'actionblock_meta_prompt_text', sanitize_text_field($_POST['action_prompt_text']));
}
if(isset($_POST['action_button_text'])){
update_post_meta($post_id, 'actionblock_meta_button_text', sanitize_text_field($_POST['action_button_text']));
}
if(isset($_POST['action_button_link'])){
update_post_meta($post_id, 'actionblock_meta_button_link', esc_url($_POST['action_button_link']));
}
}
// Save action block details when the post is saved/updated
add_action('save_post', 'actionblock_save_meta_box_data');

Related

Adding/removing filter from another filter in Wordpress

I'm trying add/remove Wordpress search filter according to the page author of the page I'm currently on. The search bar is in the theme header and therefore independent of the page I am on. I would like to use the author ID of the current page to add a filter for the next search I would do in the search bar.
This is an e-commerce site. The search bar is in the header (independent of the page). I'm on the shop page. I'd like to search products (i.e. posts with the same author ID) related to the shop page I was on before the search action.
I have written the code for functions.php however it doesn't work, i.e "my_search_filter" is not added (nor deleted). What I'm missing?
function search_filter_by_page_author()
{
$author_id = get_the_author_meta('ID');
#echo $author_id;
if (in_array($author_id, array("1", "2"))
{
add_filter( 'pre_get_posts', 'my_search_filter' );
}
else
{
remove_filter( 'pre_get_posts', 'my_search_filter' );
}
}
add_action( 'wp_head', 'search_filter_by_page_author' );
function my_search_filter( $query )
{
if ( $query->is_search && !is_admin())
{
$query->set( 'author', '1, 2' );
}
return $query;
}
Here is an answer that may be what you're after. In my opinion, you should
Set a new searchform.php
Add your pre_get_posts (which by the way is an action, and not a filter)
searchform.php (example) - This goes in your theme or child theme root folder.
<?php
global $post;
$author_id = $post->post_author;?>
<form method="get" id="searchform" action="<?php echo esc_url( home_url( '/' ) ); ?>" role="search" class="searchform search">
<div class="form-group">
<input type="text" class="form-control" name="s" value="<?php echo esc_attr( get_search_query() ); ?>" id="s" placeholder="<?php esc_attr_e( 'Search …', 'text_domain' ); ?>"/>
<input type="hidden" name="author" value="<?php echo $author_id;?>">
</div>
<button type="submit" class="btn btn-default"><i class="fa fa-search"></i></button>
</form>
Search filter (put in functions.php)
add_action('pre_get_posts', 'search_filter_by_page_author');
function search_filter_by_page_author($query){
if ($query->is_search && !is_admin() && isset($_GET['author'])) {
$query->set('author', $_GET['author']);
}
return $query;
}
This may not do exactly what you're looking for, but I think you should be able to get a positive result from this as a starting point.

Allow customer to remove order items in Woocommerce

hello i have this code which is supposed to remove an item from an order
add_action( 'woocommerce_order_item_meta_end', 'display_remove_order_item_button', 10, 3 );
function display_remove_order_item_button( $item_id, $item, $order ){
// Avoiding displaying buttons on email notification
if( ! ( is_wc_endpoint_url( 'view-order' ) || is_wc_endpoint_url( 'order-received' ) ) ) return;
if( isset($_POST["remove_item_$item_id"]) && $_POST["remove_item_$item_id"] == 'Remove this item' ){
wc_delete_order_item( $item_id );
$order->calculate_totals();
}
echo '<form class="cart" method="post" enctype="multipart/form-data" style= "margin-top:12px;">
<input type="submit" class="button" name="remove_item_'.$item_id.'" value="Complete Cancellation" />
</form>';
}
But when i press complete cancellation page refresh but nothing is removed & i refresh again nothing is removed
what am i doing wrong?
There are multiple mistakes in your code like:
the condition $_POST["remove_item_$item_id"] == 'Remove this item' is always false.
You need to remove the item using a hook before page start to load, to get the refresh. If not you will not see that the item has been removed and you will need to reload the page once.
So try the following instead:
// Displaying the form fields (buttons and hidden fields)
add_action( 'woocommerce_order_item_meta_end', 'display_remove_order_item_button', 10, 3 );
function display_remove_order_item_button( $item_id, $item, $order ){
// Avoiding displaying buttons on email notification
if( ! ( is_wc_endpoint_url( 'view-order' ) || is_wc_endpoint_url( 'order-received' ) ) )
return;
echo '<form class="cart item-'.$item_id.'" method="post" style= "margin-top:12px;">
<input type="hidden" name="item_id" value="'.$item_id.'" />
<input type="hidden" name="order_id" value="'.$order->get_id().'" />
<input type="submit" class="button" name="remove_item_'.$item_id.'" value="Complete Cancellation" />
</form>';
}
// Processing the request
add_action( 'template_redirect', 'process_remove_order_item' );
function process_remove_order_item(){
// Avoiding displaying buttons on email notification
if( ! ( is_wc_endpoint_url( 'view-order' ) || is_wc_endpoint_url( 'order-received' ) ) )
return;
if( isset($_POST['item_id']) && isset($_POST['remove_item_'.$_POST['item_id']]) && isset($_POST['order_id'])
&& is_numeric($_POST['order_id']) && get_post_type($_POST['order_id']) === 'shop_order' ) {
// Get the WC_Order Object
$order = wc_get_order( absint($_POST['order_id']) );
// Remove the desired order item
if( is_a($order, 'WC_Order') && is_numeric($_POST['item_id']) ) {
$order->remove_item( absint($_POST['item_id']) );
$order->calculate_totals();
// Optionally display a notice
wc_add_notice( __('Order item removed successfully'), 'success' );
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.

Hide Coupon notice form in Woocommerce checkout page

On my website the checkout page containing "Have a coupon? Click here to enter your code" box. I don't want this field on checkout page.I applying coupon via URl. I want to remove this box from checkout page by CSS. I attached the screenshot of that box in my checkout page.
Is this possible?
I have already tried this:
function hide_coupon_field_on_checkout( $enabled ) {
if ( is_checkout() ) {
$enabled = false;
}
return $enabled;
}
add_filter( 'woocommerce_coupons_enabled', 'hide_coupon_field_on_checkout' );
But it disable coupons functionality in checkout page.
Any help will be appreciated.
You can use a custom function hooked in woocommerce_before_checkout_form action hook that will remove the notice coupon form without disabling coupon functionality in checkout page:
add_action( 'woocommerce_before_checkout_form', 'remove_checkout_coupon_form', 9 );
function remove_checkout_coupon_form(){
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works.
This tag seems not having an unique id/class assigned. But something like this should be able to do it:
$(".showcoupon").closest(".woocommerce-info").hide();
You can override the coupon template file at wp-content/themes/yourtheme/woocommerce/checkout/form-coupon.php and comment wc_print_notice and set display of the form to none.
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! wc_coupons_enabled() ) {
return;
}
if ( empty( WC()->cart->applied_coupons ) ) {
$info_message = apply_filters( 'woocommerce_checkout_coupon_message', __( 'Have a coupon?', 'woocommerce' ) . ' ' . __( 'Click here to enter your code', 'woocommerce' ) . '' );
//wc_print_notice( $info_message, 'notice' );
}
?>
<form class="checkout_coupon" method="post" style="display:none">
<p class="form-row form-row-first">
<input type="text" name="coupon_code" class="input-text" placeholder="<?php esc_attr_e( 'Coupon code', 'woocommerce' ); ?>" id="coupon_code" value="" />
</p>
<p class="form-row form-row-last">
<input type="submit" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>" />
</p>
<div class="clear"></div>
</form>

Wordpress in foreach loop updating meta values

I have done foreach loop to get custom post type to frontend. And i have one custom field called 'order_staatus'. When i look in front end my list in loop, i want to add one button what would change this certain post 'order_staatus' to different value.. my code..
<? foreach ( $postslist as $post ) :
setup_postdata( $post );
?>
<div class="profile_order_row">
<?php the_author(); ?> <?php the_title(); ?>
<?php
Global $post;
if ( isset( $_POST['submit'] ) )
{
if( ! isset( $post ) ) {
echo 'Post not set';
die();
}
else if( ! isset( $_POST['staatus'] ) && ! empty( $_POST['staatus'] ) ){
echo 'Error';
die();
}
$postid = $_POST['post_id'];
update_post_meta($postid,'order_staatus','1');
}
$staatus = get_post_meta($post->ID, 'order_staatus', true);
echo print_r($staatus);
?>
<form method="post" action="">
<input type="hidden" name="post_id" value="'.$post->ID.'" />
<input type='text' name='staatus' value='<? echo $staatus ?>' />
<input type='submit' value='save' />
</form>
</div>
<?php endforeach; wp_reset_postdata(); ?>
I don't think the issue is with the function update_post_meta. I think the more likely issue is that $_POST['submit'] is not set. When submitting a form, the value of the submit button is not sent. The value attribute is simply for assigning the text of the button.
I would rewrite the IF block of code like this:
if ( isset( $_POST ) )
{
if( ! isset( $_POST['staatus'] ) && ! empty( $_POST['staatus'] ) ){
echo 'Error';
die();
}
$postid = sanitize_text_field($_POST['post_id']);
update_post_meta($postid,'order_staatus','1');
}
Note, that I removed the isset($post) check because you are running this code inside of foreach ( $postslist as $post ) which defines $post so it will always be set within that loop.
I also added the function sanitize_text_field() to sanitize the post_id. This is an important security measure to avoid SQL injection. All user input, including $_POST, can contain dangerous data and needs to be sanitized before use.
Hope this helps!

ACF update_field associated with a User

I've created some custom fields on the user profile page in WordPress.
I've managed to build a front end editor for the user to change some e-mail preferences:
<?php if( isset($_POST['preferences']) ) :
update_field('planner-reminders', $_POST['planner-reminders'], 'user_'.$user_id.'');
update_field('event-suggestions', $_POST['event-suggestions'], 'user_'.$user_id.'');
update_field('woa-updates', $_POST['woa-updates'], 'user_'.$user_id.'');
echo '<p class="success">E-Mail Prefereneces Updated<p>';
endif; ?>
<form action="<?php the_permalink(); ?>" method="POST" class="user-email-settings">
<!-- planner reminders -->
<?php
$field = get_field('planner-reminders', 'user_'.$user_id.'');
if( $field == true ) {
$field = '1';
$checked = true;
}
?>
<input type="checkbox" id="planner-reminders" name="planner-reminders" class="pref"
value="<?php echo $field; ?>" <?php if($checked) :?> checked <?php endif;?> />
<label for="planner-reminders">I don't want to revieve reminders about events I've added to my planner.</label>
<?php $checked = false; ?>
<!-- event suggestions from WOA -->
<?php
$field = get_field('event-suggestions', 'user_'.$user_id.'');
if( $field == true ) {
$field = '1';
$checked = true;
}
?>
<input type="checkbox" id="event-suggestions" name="event-suggestions" class="pref"
value="<?php echo $field; ?>" <?php if($checked) :?> checked <?php endif;?> />
<label for="event-suggestions">I don't want to recieve suggestions about events I may be interested in.</label>
<?php $checked = false; ?>
<!-- updates from WOA -->
<?php
$field = get_field('woa-updates', 'user_'.$user_id.'');
if( $field == true ) {
$field = '1';
$checked = true;
}
?>
<input type="checkbox" id="woa-updates" name="woa-updates" class="pref"
value="<?php echo $field; ?>" <?php if($checked) :?> checked <?php endif;?> />
<label for="woa-updates">I don't want to recieve e-mail updates from What's On Advisor.</label>
<?php $checked = false; ?>
<input type="submit" value="Save Preferences" name="preferences" id="preferences" />
</form>
Now, this actually seems to work. If I update a checkbox it shows and checked/unchecked as it should, and it shows correctly in the front end and the back end.
But, when I try to query this setting with a wp_query to actually send the e-mails to those who haven't opted out, it bug out a little.
If the user opts out, then opts back in, the wp_query doens't pick them up. It only picks them up when I go into the wp-admin area and update their user profile. I don't actually have to change anything, just open the user up and click update.
Here's the wp_query just incase:
<?php $args = array(
'role' => 'Subscriber',
'meta_key' => 'planner-reminders',
'meta_value' => '0',
'meta_compare' => '=='
); ?>
<?php $user_query = new WP_User_Query( $args ); ?>
<?php if ( ! empty( $user_query->results ) ) : ?>
etc. etc.
Any ideas how I can get this working properly? Is there a function to fake a click on the 'Update User' button in wp-admin?
Thanks.
When the user opts out, the $field value will be empty, and therefore the value-attribute of the checkboxes will be empty. I haven't fully tested it, but this can yield unexpected behaviour in your setup. When a form with an unchecked checkbox is submitted through a POST request, the checkbox name will not be set in the $_POST array, which is why you should, in this case, set the value-attribute of the checkboxes to "1", so it is properly stored via update_field.
Could you try changing the checkbox values in the code posted above to "1" for the checkbox input elements? That would be value="1" instead of value="<?php echo $field; ?>".
To prevent PHP notices being generated for inexistent array keys, I would advise to change
update_field('planner-reminders', $_POST['planner-reminders'], 'user_'.$user_id.'');
to
update_field('planner-reminders', empty( $_POST['planner-reminders'] ) ? '0' : '1', 'user_'.$user_id.'');
as well.

Categories