UPDATE_USER_META为多个值,但具有相同的元密钥

时间:2020-11-17 作者:freedom667

我有这个密码。当我保存它时,用户会增加级别并在旁边提供时间选择输入。但当我给级别分配不同的时间时,例如:级别1:2周,级别2:9个月

如果只保存最后一个元素,则所有输入都显示该值。如何节省不同的时间?我错在哪里?

//USER EDIT IN ADMIN DASHBOARD
add_action( \'show_user_profile\', \'crf_show_extra_profile_fields\' );
add_action( \'edit_user_profile\', \'crf_show_extra_profile_fields\' );

function crf_show_extra_profile_fields( $user ) {
    $user_levels = rua_get_user($user->ID)->get_level_ids();
    $elements = array();
    foreach ($user_levels as $user_level) {
        $present_date = date("Y-m-d");
        $end_time = get_the_author_meta( $user_level, $user->ID);
        $effectiveDate = strtotime($end_time, strtotime(date("Y-m-d")));
        $time = date("d/m/y", $effectiveDate);
        $elements[] = get_the_title($user_level) . 
        \' ->  <select name="\' .$user_level. \'" id="time-selector" style="width:180px;">
              <option value="default">Süre Seçiniz</option>
              <option value="+14 day" \'.selected( $end_time, "+14 day"). \'>2 Hafta</option>
              <option value="+9 months" \'.selected( $end_time, "+9 months"). \'>9 Ay</option>
              <option value="+12 months" \' .selected( $end_time, "+12 months"). \'>12 Ay</option>
              <option value="+7 day" \' .selected( $end_time, "+7 day"). \'>Uzat</option>
              </select>\'  . $present_date . \'   \' . $time .  \'<br><br>\';
    }
}


//SAVING DATE OF EACH LEVEL    
add_action( \'personal_options_update\', \'crf_update_profile_fields\' );
add_action( \'edit_user_profile_update\', \'crf_update_profile_fields\' );

function crf_update_profile_fields( $user_id ) {
    $user_levels = rua_get_user($user_id)->get_level_ids();
    foreach ($user_levels as $user_level) {
        update_user_meta( $user_id, $user_level, $_POST[ $user_level ] );
    }
}

//DELETING LEVEL
function my_demo_cronjob_action () {
    $present_date = date("Y-m-d");
    $user = get_user_by(\'id\',26);
    $user_levels = rua_get_user($user)->get_level_ids(false, false, true);

    foreach ($user_levels as $level) {
      $end_time = get_the_author_meta( $level, $user->ID);
      $effectiveDate = strtotime($end_time, strtotime(date("Y-m-d")));
      $time = date("d/m/y", $effectiveDate);
      if ($present_date > $time) {
        rua_get_user($user)->remove_level($level);
      }
    }
}
add_action(\'my_demo_cronjob_action\', \'my_demo_cronjob_action\');

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

每个级别的HTML select标记都具有相同的名称和ID,并且会相互覆盖。他们must独一无二。You will need separate names, IDs, and meta for each user level input.

同样,用户元密钥需要是唯一的。代码还需要使用get_user_meta 相反(get_the_author_meta 仅在post循环中使用)。

我建议使用类似的方法:

    foreach ($user_levels as $user_level) {
        update_user_meta( $user_id, \'time-selector-\' . $user_level, $_POST[ \'time-selector\' . $user_level ] );
    }
然后相应地更改输入名称和ID。e、 g。<select name=\'time-selector-\' . $user_level . \'您还需要调整get_user_meta 调用以使用新键

然而,您的代码中还有另一个错误。selected 不返回字符串,而是将其输出,因此selected="selected" HTML将输出到错误的位置。您需要传递第三个参数false 否则,HTML标记将不正确,并且在显示输入标记之前将显示选定属性。

以下是一个示例:

保存元:

$rua_user = rua_get_user( $user->ID );
$user_levels = $rua_user->get_level_ids();

// save existing values if they exist
foreach ( $user_levels as $level ) {
    $metakey = \'time-selector-\' . $level;
    if ( isset( $_POST[ $metakey ] ) ) {
        update_user_meta( $user_id, $metakey, $_POST[ $metakey ] );
    }
}
显示输入:

$choices = [
    \'two\'  => \'Two Weeks\',
    \'nine\' => \'9 months\',
];

$rua_user = rua_get_user( $user->ID );
$user_levels = $rua_user->get_level_ids();

foreach ( $user_levels as $level ) {
    $metakey = \'time-selector-\' . $level;
    $time    = get_user_meta( $user->ID, $metakey, true );
    ob_start();
    echo esc_html( get_the_title( $level ) ) . \' -> \';
    ?>
    <select
        name=\'time-selector-<?php echo esc_attr( $level ); ?>\'
        id=\'time-selector-<?php echo esc_attr( $level ); ?>\'
        style=\'width:180px;\'
    >
        <option value=\'default\'>Select time</option>
        <?php
        foreach ( $choices as $value => $label ) {
            ?>
            <option
                value="<?php echo esc_attr( $value ); ?>"
                <?php selected( $value, $time ); ?>
            >
                <?php echo esc_html( $label ); ?>
            </option>
            <?php
        }
        ?>
    </select>
    <br>
    <br>
    <?php
    $html = ob_get_clean();
    $elements[] = $html;
}
// ... etc
请注意以下几点:

所有级别都有唯一且独立的HTML标记,post meta每个字段之间都没有共享内容,如果共享了内容,它们就不会分开。我使用了输出缓冲区,使HTML更易于读取和生成。我添加了转义,这是一个重要的安全功能。时间列表不再是硬编码的,并被移动到一个单独的数组中,以简化代码并减少重复。这也意味着可以对其进行筛选、添加等。保存代码位于单独的代码段中,处理post/用户保存不应与显示数据发生在同一挂钩上<通过将保存代码放在原始问题的显示代码中,您可能引入了一个错误,因为用户元密钥已更改,所有以前的数据都需要重新保存。这不应该是一个问题,因为先前的数据由于原始代码的工作方式而被破坏。在编写问题之前,可能发生的任何数据丢失都已发生