Modifying values with add_action to be sent to db

Correct way of modifying a variable using hooks

If you want to modify a variable or any value using hooks, it’s best to do that using filter hooks (instead of action hooks). Although internally the implementation is almost the same for actions and filters, the convention is:

  1. With action hooks, you do something, echo output etc. inside the callback function, but neither return anything, nor change the arguments outside the scope of that callback function.

  2. With filter hooks, you return a value from the callback function and either use it somewhere or assign it to a variable outside of the callback function.

So use the apply_filters CODE like this:

// using apply_filters() instead of the following do_action_ref_array() line
// do_action_ref_array( 'h5p_alter_user_result', array( &$data, $result_id, $content_id, $user_id ) );
$data = apply_filters( 'h5p_alter_user_result', $data, $result_id, $content_id, $user_id );

To match this, use add_filter and the callback function like this:

// Declare number of parameters to be passed in add_filter.
// According to our apply_filters() call,
// we expect 4 parameters to be passed to the callback function
add_filter( 'h5p_alter_user_result', 'diff_test_callback', 10, 4 );
function diff_test_callback( $data, $result_id, $content_id, $user_id ) {
    // do something with $data
    // remember: manipulation of $data doesn't have any affect
    // outside of this function
    // So we need this return
    return $data;
}

do_action_ref_array issues in your CODE:

From your do_action_ref_array call, looks like you are trying to pass $data as reference:

do_action_ref_array( 'h5p_alter_user_result', array( &$data, $result_id, $content_id, $user_id ) );

However, since PHP 5.4, this behaviour has been changed. do_action_ref_array no longer passes the reference of the argument to the callback function, instead, it passes a copy.

Also, call time pass by reference is not accepted since PHP 5.4. So best is to use the apply_filters method as shown in the above CODE.

Even though not recommended, what you tried to do can be done with reference pointers as function parameters inside an array. Like this:

// add_action without passing the number of parameters
add_action( 'h5p_alter_user_result', 'diff_test_callback' );
// callback function implementation with reference pointer `&`
// for parameters you are expecting with reference
function diff_test_callback( $args ) {
    // we need the reference of $data, so using & operator here.
    $data = &$args[0];
    $result_id = $args[1];
    $content_id = $args[2];
    $user_id = $args[3];

    // now making changes to $data
    // will be reflected outside the scope of this function
    // no return is necessary
}

// at the time of executing the action,
// create the $args array with reference to $data
$args = array( &$data, $result_id, $content_id, $user_id );
do_action_ref_array( 'h5p_alter_user_result', array( $args ) );

Warning: Once again, although do_action_ref_array method works if you carefully handle the references, it’s highly recommended that you use the filter hook method in this scenario.