How To fix 'Adding An element to array rather than replacing it'? - php

I'm trying to write a function where logged in users can add favorite properties and store it as an array in user meta table, but instead of adding multiple values it just stores one value and keeps on replacing it. What am I doing wrong here? I was also unsuccessful to add it manually in the database, how to read the structure?
This is for WordPress
function wms_add_to_usermeta( $post_id )
{
$favorites = $this->wms_get_user_meta();
$favorites[] = $post_id;
$this->wms_update_user_meta( $favorites );
return true;
}
WMS GET USER META Function
function wms_get_user_meta( $user = "" )
{
if( ! empty( $user ) ) {
$userdata = $this->get_user_by( 'login', $user );
$user_id = $userdata->ID;
return get_user_meta( $user_id, $this->favorites_meta_key, true );
}
else {
return get_user_meta( $this->wms_get_user_id(), $this>favorites_meta_key, true );
}
}
Update User Meta
function wms_update_user_meta( $arr )
{
return update_user_meta( $this->wms_get_user_id(), $this->favorites_meta_key, $arr );
}
table data structure a:1:{i:0;i:7;} it keeps on replacing i:7; with 7 being the $post_id

You define $favorites when you call mws_get_user_meta in your class. Then you re-declare $favorites as an array when you add the brackets after it, but that is ignored because it is already an array, or as Alex suggests your array might lose it's format when you do that. Then with the = you push the post_id so it ends up at the end of the array.
So you end up with:
$this->wms_update_user_meta( array('stuff returned from wms_get_user_meta, $post_id);
That would explain why your 7 is always at the end of your data.
I would take a look at the mws_get_user_meta function and make sure you are sending the right arguments. The core requires 3 arguments and I suspect your class' function does as well. Here is the core function:
function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
return update_metadata( 'user', $user_id, $meta_key, $meta_value, $prev_value );
}
Note that $user_id, $meta_key, $meta_value are all required or it will return false.

Related

Custom map_meta_cap filter does not return ['do_not_allow']

I have created a custom role that only has access to certain pages and their children/parents. I have used map_meta_cap filter to solve this. However even though it goes through my function correctly it will not function properly, return ['do_not_allow']; is not working as intended and I don't know why, it seemingly does not do anything.
//Role cap for different pages
function staby_map_meta_cap( $caps, $cap, $user_id, $args ) {
// // If the capability being filtered isn't of our interest, just return current value
if ( in_array($cap, ['edit_pages']) ) {
// First item in $args array should be page ID
if (!staby_role_can_edit( $user_id, $args[0] ) ) {
// User is not allowed, let's tell that to WP
return ['do_not_allow'];
}
}
// Otherwise just return current value
return $caps;
}
add_filter( 'map_meta_cap', 'staby_map_meta_cap', 10, 4 );
//See if role can edit correspondent page
function staby_role_can_edit( $user_id, $page_id) {
$page = get_post( $page_id );
// let's find the topmost page in the hierarchy
while( $page && (int) $page->parent ) {
$page = get_post( $page->parent );
}
if ( ! $page ) {
return false;
}
$user = new WP_User($user_id);
if ($user->allcaps['pages_id']) {
$user_pages = $user->allcaps['pages_id'];
if (!in_array($page->ID, $user_pages)) {
return false;
}
}
return true;
}
The only thing I have noticed is that the map_meta_cap filter runs multiple times, and the $args variable is always empty but it somehow still retrieves the $args[0] (page id) in my custom function staby_role_can_edit( $user_id, $page_id ) (but when I call it in that function it's null?). I have no idea why it's not working at all.
Any help is very appreciated! Thanks.

What's wrong with my update_post_meta function?

When I save an acf post, I want to grab an ACF user field called contrib-id for the current user, and save it into a relationship field called contrib-meme. This is giving me a syntax error. What am I missing?
function my_acf_save_post($post_id)
{
if ( is_user_logged_in() ) {
update_post_meta( $post_id, 'contrib-meme', (get_user_meta ( get_current_user_id() ), $key = 'contrib-id', $single = true )) ;
}
}
add_action('acf/save_post', 'my_acf_save_post');
Try this:
function my_acf_save_post($post_id){
if ( is_user_logged_in() ) {
update_post_meta( $post_id, 'contrib-meme', get_user_meta( get_current_user_id(), 'contrib-id', true ));
}
}
add_action('acf/save_post', 'my_acf_save_post');
Hope this helps

Is there a way to update a user role and update ACF fields on the user profile in WordPress at the same time using WooCommerce actions?

I've been trying to combine the following two functions, but can only successfully perform either one or the other, not both at the same time. I was wondering if anyone knew what might be causing the conflict. These are executed upon the creation of a customer via a WooCommerce registration form, via the woocommerce_created_customer action.
Function: 1 (purpose is to update two fields which already exist on the user page thanks to ACF Pro)
function school_info_save( $customer_id ) {
if( isset( $_POST['school_name'] ) ) {
update_user_meta( $customer_id, 'school_name', sanitize_text_field($_POST['school_name']) );
}
if( isset( $_POST['school_email'] ) ) {
update_user_meta( $customer_id, 'school_email', sanitize_email($_POST['school_email']) );
}
}
add_action('woocommerce_created_customer', 'school_info_save', 20);
Function 2: (purpose is to then update the user role to student)
function update_to_student_role( $customer_id ) {
if( isset( $_POST['school_name']) && isset( $_POST['school_email']) ) {
wp_update_user( array( 'ID' => $customer_id, 'role' => 'student' ) );
}
}
add_action('woocommerce_created_customer', 'update_to_student_role', 10);
I've tried these both at different priorities. Generally, if both are active, only the student role function will succeed. Just wondering if anyone can explain to me why wp_update_user prevents update_user_meta from working - if that's actually what is occurring.
Additionally, I've also tried running the above functionality all within one function too, with the same result.
function school_info_save( $customer_id ) {
$metas = array(
'wp_capabilities' => array('student' => true),
'school_name' => sanitize_text_field($_POST['school_name']),
'school_email' => sanitize_email($_POST['school_email'])
);
if( isset( $_POST['school_name']) && isset( $_POST['school_email']) ) {
foreach($metas as $key => $value) {
update_user_meta( $customer_id, $key, $value );
}
}
}
add_action('woocommerce_created_customer', 'school_info_save', 20);
Thank you.
you can instead change your Function 2. Like this:
function update_to_student_role( $new_customer_data ) {
if( isset( $_POST['school_name']) && isset( $_POST['school_email']) ) {
$new_customer_data['role'] = 'student';
}
return $new_customer_data;
}
add_action('woocommerce_new_customer_data', 'update_to_student_role');
Nevermind... I had forgotten to actually modify the ACF field rules so that those two student fields appeared on a user profile which had a role of "student" ... the functions were working, but the fields weren't there to receive the data upon role change I believe.

Having trouble adding validation errors to ACF form

I'm using ACF with WordPress and I have a form that I am trying to add a validation error to, but it doesn't appear to be working (I think I know why)...
My code:
function my_acf_update_value( $value, $post_id, $field ) {
// Get the users numerical user id
$user_id = str_replace('user_', '', $post_id);
$value = sanitize_text_field($value);
/** #noinspection PhpParamsInspection */
$user_data = wp_update_user(array('ID' => $user_id, 'user_email' => $value ) );
if ( is_wp_error( $user_data ) ) {
$wp_error = $user_data->get_error_message();
$input = $field['prefix'] . '[' . $field['key'] . ']';
acf_add_validation_error($input, $wp_error);
}
return $value;
}
add_filter('acf/update_value/key=field_5c121023e119f', 'my_acf_update_value', 10, 3);
As you may be able to tell I am attempting to update the users email address field (default WP one) based off the email provided by a user in an email field on a frontend ACF Form.
I then check to see if the update caused any errors and obviously if it did I want to add to the ACF validation errors, but it passers through successfully.
I assume this is because the update function runs AFTER the validation and this is why it isn't working?
Because of this I thought about doing the update in the validation function such as:
function my_acf_validate_value( $valid, $value, $field, $input ){
// bail early if value is already invalid
if( !$valid ) {
return $valid;
}
// Some code...
// Return error here?
return $valid;
}
add_filter('acf/validate_value/key=field_5c121023e119f', 'my_acf_validate_value', 10, 4);
...but I don't seem to have access to the $post_id here, nor does this seem like the best way to handle it?
Is there a way to handle this better?
You can use var_dump to see what data you have within the function - either in one of the existing function attributes, or by using get_the_ID() or global $post; to access the current Post object. Beware when trying to manipulate the Post object here, though.

Change Wordpress user role on gravityforms submission

I am using Gravityforms along with User registration add-on and have a form which when submitted should change the role of the current user to a new role without any underlying conditions.
Using the gravity\forms docs https://docs.gravityforms.com/gform_user_updated/#1-update-user-role and trying this:
add_action( 'gform_user_updated_3', 'change_role', 10, 3 );
function change_role( $user_id, $feed, $entry, $user_pass ) {
global $current_user;
get_currentuserinfo();
$user_id = $current_user->ID;
echo $user_id;
if( ! $user_id ) {
return;
}
$user = new WP_User( $user_id );
$user->set_role( 'role' ); // update 'role' to the name of the desired role
}
But its not working! Does anyone have any idea why this is incorrect or any other modifications to the code?
There's a couple things I see with your code when comparing it to the Gravity Forms doc.
Here's your code with some added comments:
add_action( 'gform_user_updated_3', 'change_role', 10, 3 );
function change_role( $user_id, $feed, $entry, $user_pass ) {
global $current_user; // you probably don't need this
get_currentuserinfo(); // you probably don't need this
$user_id = $current_user->ID; // $user_id should already be a numeric value passed in to the function containing the logged in user's ID so you shouldn't need to do this. You're resetting the $user_id variable here to whatever is being pulled out of the get_currentuserinfo() function, and I'm guessing that's the problem
//I would get rid of this echo and if statement
echo $user_id;
if( ! $user_id ) {
return;
}
$user = new WP_User( $user_id );
$user->set_role( 'role' ); // the word "role" here needs to be the role name
}
I think you can simplify it some. Try this instead:
add_action( 'gform_user_updated_3', 'change_role', 10, 3 );
function change_role( $user_id, $feed, $entry, $user_pass ) {
$user = new WP_User( $user_id );
$user->set_role( 'new_role_name_here' ); // Add an existing role here to update the user too
}

Categories