web-dev-qa-db-de.com

Ändern von Werten mit add_action, die an db gesendet werden sollen

Ich kämpfe jetzt seit Stunden mit diesem Problem, was passiert ist, dass irgendwo vor dem Einfügen der Werte in die Datenbank diese Aktion aufgerufen wird.

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

Es folgen die Werte und wie sie ausgefüllt werden.

$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;

was ich versuche, ist, dass ich diese Werte ändern möchte, bevor sie in der Datenbank gespeichert werden (und ja, dieser Hook wird vor dem Speichern in der Datenbank aufgerufen). Dafür habe ich die folgenden Funktionen in meinem Plugin erstellt.

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;
}

Aber die Werte werden nicht geändert, stimmt etwas nicht?

2
hede

Richtige Art, eine Variable mit Hilfe von Hooks zu ändern

Wenn Sie eine Variable oder einen Wert mithilfe von Hooks ändern möchten, verwenden Sie dazu am besten Filter-Hooks (anstelle von Aktions-Hooks). Obwohl die Implementierung für Aktionen und Filter intern fast identisch ist, lautet die Konvention:

  1. Mit Aktions-Hooks können Sie innerhalb der Rückruffunktion etwas tun, eine Echoausgabe usw., aber weder etwas zurückgeben noch die Argumente außerhalb des Bereichs dieser Rückruffunktion ändern.

  2. Mit Filter-Hooks geben Sie einen Wert aus der Rückruffunktion zurück und verwenden ihn entweder irgendwo oder weisen ihn einer Variablen außerhalb der Rückruffunktion zu.

Verwenden Sie also den apply_filters CODE wie folgt:

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

Verwenden Sie dazu add_filter und die Rückruffunktion wie folgt:

// 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 Probleme in Ihrem CODE:

In Ihrem do_action_ref_array-Aufruf sehen Sie so aus, als würden Sie versuchen, $data als Referenz zu übergeben:

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

Seit PHP 5.4 wurde dieses Verhalten jedoch geändert. do_action_ref_array übergibt nicht mehr die Referenz des Arguments an die Rückruffunktion, sondern eine Kopie.

Außerdem wird Call Time Pass by Reference nicht akzeptiert seit PHP 5.4. Verwenden Sie am besten die apply_filters-Methode, wie im obigen CODE gezeigt.

Obwohl nicht empfohlen , können Sie das, was Sie versucht haben, mit Referenzzeigern als Funktionsparameter innerhalb eines Arrays tun. So was:

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

Warnung: Obwohl die do_action_ref_array-Methode funktioniert, wenn Sie sorgfältig mit den Verweisen umgehen, wird in diesem Szenario dringend empfohlen, die Filter-Hook-Methode zu verwenden.

1
Fayaz