What hook do I need to save a setting? - php

I've added a new field onto the discussion's section on the /wp-admin/options-discussion.php page that outputs along with this:
<?php do_settings_sections('discussion'); ?>
How can I hook the Save Changes button so that I can handle saving my new setting's fields?
I've tried updated_option like so:
add_action('updated_option', [__CLASS__, 'sanitize_settings'], 11, 3);
But I don't think this is what I need.

for saving data in wp_options you should set the name and value together
for example first we can add new options with add_option function and see this link
add_option( 'nameOfYourOption', 'value', '', 'yes' );
then you can easily access your data with the get_option function and see this link
$yourOption = get_option( 'nameOfYourOption' );
var_dump($yourOption)
and if you want to change the value you can do that with update_option function and see this link
update_option( 'nameOfYourOption', 'newValue' );
With these three functions, you can manage your option
but if you try just using the hook for update_option see this link
do_action( 'update_option', string $option, mixed $old_value, mixed $value )
Updated
When you try to click on a Save button to using those functions, you can handle that with a form or with WordPress ajax
<form method="post">
<button name="uniqName" type="submit">Save Changes</button>
</form>
in wordpress/php
<?PHP
if(isset($_POST['uniqName'])){
//do something
}
and if you try to send data with ajax, just see this link

Related

Custom "Post Author" Input Instead of Dropdown

I have a site with over 20,000 users. Occasionally I need to update the author of a post. However, the sheer amount of users makes the "Author" metabox on the edit post screen unusable. I'm trying to make a custom box where I can input the desired author's ID and change the post author to that ID. Ideally, I would like to do this within the box itself, rather than by way of saving/updating the post.
Here's my custom meta box code:
//Get the post data
$id = get_the_ID();
$author_id= $post->post_author;
<div class="update-author">
<p><strong>Current Author ID:</strong> <?php echo $author_id;?></p>
<p><strong>CHANGE AUTHOR ID TO:</strong></p>
<form id="update-author-form" method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" >
<input type="hidden" name="action" value="update_author_form">
<input type="hidden" name="post-id" value="<?php echo $id; ?>">
<input type="number" id="update-author-id" name="update-author-id" value="" />
<button id="update-author-button" class="button button-primary button-large">Update Author ID</button>
</form>
</div>
Next, I have my form function built as follows:
function handle_update_author_form() {
$post_id = $_POST['post-id'];
$update_id = $_POST['update-author-id'];
$my_post = array(
'ID' => $post_id,
'post_author' => $update)_id,
);
wp_update_post( $my_post );
}
At this stage, my form button does nothing but refresh the page and send it to the posts screen (I know, I need to change the redirect URL).
Like in comments - I would go for a another approach of removing the original meta_box and replacing it with a new one - or alternatively just use a JS to turn the dropdown list into a searchable field ( for example the excellent select2 plugins - but have others - and also pure JS is quite easy - see example below )
Anyhow - in your code that you posted you are missing the hook where you can apply and invoke your code, for example:
'add_action( 'save_post', 'handle_update_author_form', 10, 1 ); '
Have a look at wp filters and actions.
The suggested (simple) JS solution :
Now, for the simple approach of just using JS to pseudo-search inside the dropdown and therefor there is no real need to interfere with the query or post injections.....
myPlugin.php / myTHeme,php
function admin_enqueue_scripts_callback(){
// We are using select2.js from CDN here ..
//This will add Select2 CSS
wp_enqueue_style( 'select2-css', 'https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css', array(), '4.1.0-rc.0');
////This will add Select2 JS
wp_enqueue_script( 'select2-js', 'https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js', 'jquery', '4.1.0-rc.0');
// Now we need a JavaScript file to initialize the Select2 elements
// here it is staged as a plugin - but a theme would be the same .
wp_enqueue_script( 'select2-init', '/wp-content/plugins/select2-init.js', 'jquery', '4.1.0-rc.0');
}
add_action( 'admin_enqueue_scripts', 'admin_enqueue_scripts_callback' );
select2-init.js
// initialize select2 on author dropdown field with jQuery
jQuery(document).ready(function($) {
$('#post_author_override').select2();
});
voilà !
At this point you will have the pseudo-search implemented that would resolve your problem in a practical way without any new ->queries or $objects and with minimum coding.
Possible / potential caveats
I am not sure what would be the efficiency of filtering 20,000 items.
It would be interesting to know how the select2 JS would perform with such a long list...
But if it is already loaded to the DOM i guess it would be ok ( might take a few seconds to react though )
Please let me know how it performing if you implement the solution.

How to send form data to woocommerce add_to_cart from custom template?

I have a created a new template inside theme's folder named Pre-Checkout Customer Details where there is a form. and the page looks like:
<?php /* Template Name: Pre-Checkout Customer Details */ ?>
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
get_header(); ?>
<form action="/checkout/?">
<input type="name" name="name">
<input type="date" name="start_date">
<input type="submit" name="Next">
</form>
<?php get_footer(); ?>
Along with that, this page's URL will always contain some parameters such as
?add-to-cart=608&subscribe='weight_loss_plan'
which will look somewhat:
https://challengecenter-q8.com/pre-checkout-customer-details/?add-to-cart=608&subscribe=%D8%A8%D9%86%D8%A7%D8%A1%20%D8%B9%D8%B6%D9%84%20%D8%A3%D8%B4%D8%AA%D8%B1%D8%A7%D9%83%20%D8%A7%D8%B3%D8%A8%D9%88%D8%B9%D9%8A%D9%86%20%D9%88%D8%AC%D8%A8%D8%AA%D9%8A%D9%86
Now when I am clicking on submit, it is showing page not found instead of moving to the cart page. Also, I want the form details to show on the checkout page like: https://challengecenter-q8.com/checkout/?name='value 1'&date='04-04-2021'
How can I achieve that?
Thank you in advance!
Note: “Enable AJAX add to cart buttons on archives” is enabled and “Redirect to the cart page after successful addition”. is disabled.
I would look into using actions to accomplish what you're trying to do. You can use the template_redirect action to check for your URL parameter and programmatically add that item to the cart then redirect to which ever page you would like.
You can simply create an anchor link for the page you're currently on that has the parameter you're needing (in my case 'atc').
Here's a piece of code I use to do this.
add_action('template_redirect', 'mks_add_to_cart');
function mks_add_to_cart(){
$pid = filter_input( INPUT_GET, 'atc', FILTER_VALIDATE_INT );
if( !empty( $pid ) ) {
global $woocommerce;
$woocommerce->cart->add_to_cart( $pid );
wp_redirect( site_url() . '/cart' );
exit;
}}
Use another action for your second part to display on the checkout page. I use Business Bloomer Visual Hook Guide often to reference where I want information to show.

Multisite - passing ACF values from current site to Gravity Forms form from another site on multisite

I'm trying to pass data from Advance Custom Fields into my Gravity Forms form. The problem I'm running into is that the form is being generated from another site on the multisite via:
<?php switch_to_blog(1);?>
<?php echo do_shortcode( '[gravityform id="3" title="false"
description="false"]' ); ?>
<?php restore_current_blog(); ?>
In my functions.php file (for both blog 1 and the current site), I have:
add_filter( 'gform_field_value_lead_source_detail', 'populate_lead_source_detail' );
function populate_lead_source_detail( $value ) {
$leadsourcedetail = get_field('lead_source_detail', $post->ID);
return $leadsourcedetail;
}
add_filter( 'gform_field_value_lifecycle_status', 'populate_lifecycle_status' );
function populate_lifecycle_status( $value ) {
$lifecycle = get_field('lifecycle_status', $post->ID);
return $lifecycle;
}
add_filter( 'gform_field_value_lead_source', 'populate_lead_source' );
function populate_lead_source( $value ) {
$leadsource = get_field('lead_source', $post->ID);
return $leadsource;
}
add_filter( 'gform_field_value_channel', 'populate_channel' );
function populate_channel( $value ) {
$channel = get_field('channel', $post->ID);
return $channel;
}
add_filter( 'gform_field_value_expected_op_type', 'populate_expected_op_type' );
function populate_expected_op_type( $value ) {
$expected = get_field('expected_op_type', $post->ID);
return $expected;
}
The ACF fields work perfectly on blog 1, where the Gravity Form is being generated from, but I can't get them to pass the data to the form on the current current blog.
To make sure the ACF fields work (in general), I tested <?php the_field(); ?> for each of them, and the data is definitely there... so I'm assuming it has something to do with the fact that I'm pulling the form from a different site on the multisite.
Anyone have any ideas on how to pass data from my current site to the blog 1 form? Thanks in advance!
Store your data using options and then try accessing it.
Site 1 --> Site1_only_plugin --> Site1_only_plugin_function()--> add_option( 'Site1_only_plugin_option', $var )
You should refer Brent Leavitt's comment in the below link. That is where I found this.
https://developer.wordpress.org/reference/functions/switch_to_blog/
Probably this is what you need.
Hope it helps.
Went about this a completely different way. Found this in the Gravity Forms docs: https://docs.gravityforms.com/using-dynamic-population/ -- under shortcodes:
[gravityform id=1 field_values=’parameter_name1=value1&parameter_name2=value2′]
Wish I would've found this before I spent a whole day on this. Lol... Here were my steps after that:
I exported/imported the Gravity Form onto another site in the
multisite that shared the same theme (so I wasn't working on two
different functions.php files; this is why the blog id and Gravity Forms id are different below).
I removed all of the functions I originally created in the functions.php
file that I stated earlier. (populate_lead_source_detail,
populate_lifecycle_status, etc.)
I created variables from the ACF fields for that page.
<?php $lead_source_detail = get_field('lead_source_detail');
$lifecycle_status = get_field('lifecycle_status');
$lead_source = get_field('lead_source');
$channel = get_field('channel');
$expected_op_type = get_field('expected_op_type'); ?>
I called the variables in the shortcode. (See below for my final code.)
<?php switch_to_blog(11);?>
<?php echo do_shortcode( '[gravityform id="1" title="false" description="false" field_values="lead_source_detail='.$lead_source_detail.'&lifecycle_status='.$lifecycle_status.'&lead_source='.$lead_source.'&channel='.$channel.'&expected_op_type='.$expected_op_type.'"]' ); ?>
<?php restore_current_blog(); ?>

How to display data from cmb2 option page?

I have created a repeatable field with CMB2, and created a normal field. This is the function of https://pastebin.com/XUQgkvbi
If you use foreach for repeatable using a post or page then you can show data as: https://pastebin.com/C35vWGDs
And Call normal field without repeatable, then
<?php $ entries = get_post_meta (get_the_ID (), 'yourprefix_group_demo', true); ?>
<?php echo $ entries; ?>
also work.
But the problem is, I do not want to use the above function on any page or post. I want to use it in the Options Page. The above Function option has been added to the option page, but I can not do the data show of those files in any way.
I've tried get_post_meta () and get_option () with two functions, but in no way can I show data from the option page. How can I get the data from the above fields (option page) to the show in the frontend? Please help with a little bit.
I got solution, The options are stored in a single option field. You would loop through the news-section groups with something like this:
$settings = get_option( 'repeatable-news-options.php', array() );
if ( ! empty( $settings['news-section'] ) ) {
foreach ( $settings['news-section'] as $section ) {
echo $section['title'] . '<br/>';
}
}
that link https://wordpress.org/support/topic/how-to-display-data-from-cmb2-option-page/
problem solved.

do_action passing a variable with T_OBJECT_OPERATOR(->) PHP

I have a plugin that uses a custom checkout form. In this checkout form there is a "create account" checkbox identical to the default Wordpress one. I am trying to write some code to add another checkbox that allows the user to choose a role for this new account. The plugin that creates this checkout form has a do_action that I want to hook into. It even has a variable that I need. Sadly, I'm uncertain how to use this.
The do_action:
do_action( 'woocommerce_after_checkout_validation', $woocommerce_checkout->posted );
As you can see this uses $woocommerce_checkout->posted
My code has the following
add_action('woocommerce_after_checkout_validation', 'validate_professional_field' 10,1);
And In my function I try to use this with the following code:
function validate_professional_field( $woocommerce_checkout->posted ) {}
This does not work And I have no clue what to do here..
How can I use the variables sent with the action?
In the end I want to use $woocommerce_checkout->posted['createprofessional'] to get the value that should be the value of my checkbox.
Other details
This checkbox was made with the following code:
add_action('woocommerce_before_checkout_registration_form' , 'define_telesales_fields', 3);
<?php function define_telesales_fields() { ?>
<p class="form-row form-row-wide create-professional">
<div class="create-account">
<input class="input-checkbox" id="createprofessional" type="checkbox" name="createprofessional" value="1" />
<label for="createprofessional" class="checkbox"><?php _e( 'Create a professional', 'woocommerce' ); ?></label>
</div>
</p>
<?php }?>
Solved
A comma was missing in the add_action
add_action('woocommerce_after_checkout_validation', 'validate_professional_field', 10,1);
Just use $woocommerce_checkout as the parameter name in the function declaration; if you're passing the whole object into the function, you can then use $woocommerce_checkout->posted within the function itself.
eg:
function validate_professional_field( $woocommerce_checkout ) {
//$woocommerce_checkout->posted is valid here
}
//and you'd call it like this:
validate_professional_field( $woocommerce_checkout );
Alternatively, if you know you only want to use posted in the function, you could limit the argument to just that, which seems to be what you want to do. In this case, give it a valid variable name in the function declaration, like so:
function validate_professional_field( $posted ) {
//$posted is valid here, and will be contain the data from $woocommerce_checkout->posted that you're passing into the function.
}
//and you'd call it like this:
validate_professional_field( $woocommerce_checkout->posted );

Categories