web-dev-qa-db-fra.com

Modification des valeurs avec add_action à envoyer à la base de données

Je lutte avec ce problème depuis des heures maintenant. Ce qui se passe, c'est qu'avant d'insérer les valeurs dans la base de données, cette action est appelée.

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

Vous trouverez ci-dessous les valeurs et leur composition.

$user_id = get_current_user_id();
    $result_id = $wpdb->get_var($wpdb->prepare(
        "SELECT id
        FROM {$wpdb->prefix}h5p_results
        WHERE user_id = %d
        AND content_id = %d",
        $user_id,
        $content_id
    ));

$table = $wpdb->prefix . 'h5p_results';
$data = array(
  'score' => filter_input(INPUT_POST, 'score', FILTER_VALIDATE_INT),
  'max_score' => filter_input(INPUT_POST, 'maxScore', FILTER_VALIDATE_INT),
  'opened' => filter_input(INPUT_POST, 'opened', FILTER_VALIDATE_INT),
  'finished' => filter_input(INPUT_POST, 'finished', FILTER_VALIDATE_INT),
  'time' => filter_input(INPUT_POST, 'time', FILTER_VALIDATE_INT)
);
if ($data['time'] === NULL) {
  $data['time'] = 0;
}
$format = array(
  '%d',
  '%d',
  '%d',
  '%d',
  '%d'
);

$content_id = 1;

ce que j'essaie de faire, c'est que je veuille modifier ces valeurs avant qu'elles ne soient enregistrées dans la base de données (et oui, ce hook est appelé avant l'enregistrement dans la base de données), pour cela j'ai créé la fonctionnalité suivante dans mon plugin.

add_action( 'h5p_alter_user_result',           'diff_test_callback' );

function diff_test_callback($args)
{
    global $wpdb;
  $user_id = 1;
    $result_id = 1;
$content_id = 1;
    $table = $wpdb->prefix . 'h5p_results';
    $data = array(
      'score' => 777,
      'max_score' => 189,
      'opened' => 333,
      'finished' => 222,
      'time' => 111
    );
    if ($data['time'] === NULL) {
      $data['time'] = 0;
    }
    $args = array( $data, $result_id, $content_id, $user_id );
    return $args;
}

Mais les valeurs ne sont pas modifiées, y a-t-il quelque chose qui ne va pas?

2
hede

Manière correcte de modifier une variable à l'aide de crochets

Si vous souhaitez modifier une variable ou une valeur à l'aide de points d'ancrage, il est préférable de le faire à l'aide de points d'ancrage de filtre (au lieu de points d'action). Bien qu'en interne, la mise en œuvre soit presque la même pour les actions et les filtres, la convention est la suivante:

  1. Avec les crochets d'action, vous faites quelque chose, obtenez une sortie d'écho, etc. à l'intérieur de la fonction de rappel, mais vous ne retournez rien et ne modifiez pas les arguments en dehors de la portée de cette fonction de rappel.

  2. Avec les crochets de filtre, vous renvoyez une valeur à partir de la fonction de rappel et vous l'utilisez quelque part ou vous l'affectez à une variable en dehors de la fonction de rappel.

Utilisez donc le code apply_filters comme ceci:

// 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 );

Pour faire correspondre cela, utilisez add_filter et la fonction de rappel comme ceci:

// 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 questions dans votre CODE:

De votre appel do_action_ref_array, on dirait que vous essayez de passer $data comme référence:

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

Cependant, depuis PHP 5.4, ce comportement a été modifié. do_action_ref_array ne transmet plus la référence de l'argument à la fonction de rappel, mais une copie.

De plus, le temps d'appel passé par référence n'est pas accepté depuis PHP 5.4. Il est donc préférable d’utiliser la méthode apply_filters comme indiqué dans le code ci-dessus.

Même si non recommandé , ce que vous avez essayé de faire peut être fait avec des pointeurs de référence comme paramètres de fonction dans un tableau. Comme ça:

// 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 ) );

Avertissement: Encore une fois, bien que la méthode do_action_ref_array fonctionne si vous manipulez les références avec précaution, il est vivement recommandé d'utiliser la méthode du filtre de filtrage dans ce scénario.

1
Fayaz