.= 'tag.htm'; break; case 'flag': $pre .= $default_pre .= 'flag.htm'; break; case 'my': $pre .= $default_pre .= 'my.htm'; break; case 'my_password': $pre .= $default_pre .= 'my_password.htm'; break; case 'my_bind': $pre .= $default_pre .= 'my_bind.htm'; break; case 'my_avatar': $pre .= $default_pre .= 'my_avatar.htm'; break; case 'home_article': $pre .= $default_pre .= 'home_article.htm'; break; case 'home_comment': $pre .= $default_pre .= 'home_comment.htm'; break; case 'user': $pre .= $default_pre .= 'user.htm'; break; case 'user_login': $pre .= $default_pre .= 'user_login.htm'; break; case 'user_create': $pre .= $default_pre .= 'user_create.htm'; break; case 'user_resetpw': $pre .= $default_pre .= 'user_resetpw.htm'; break; case 'user_resetpw_complete': $pre .= $default_pre .= 'user_resetpw_complete.htm'; break; case 'user_comment': $pre .= $default_pre .= 'user_comment.htm'; break; case 'single_page': $pre .= $default_pre .= 'single_page.htm'; break; case 'search': $pre .= $default_pre .= 'search.htm'; break; case 'operate_sticky': $pre .= $default_pre .= 'operate_sticky.htm'; break; case 'operate_close': $pre .= $default_pre .= 'operate_close.htm'; break; case 'operate_delete': $pre .= $default_pre .= 'operate_delete.htm'; break; case 'operate_move': $pre .= $default_pre .= 'operate_move.htm'; break; case '404': $pre .= $default_pre .= '404.htm'; break; case 'read_404': $pre .= $default_pre .= 'read_404.htm'; break; case 'list_404': $pre .= $default_pre .= 'list_404.htm'; break; default: $pre .= $default_pre .= theme_mode_pre(); break; } if ($config['theme']) { $conffile = APP_PATH . 'view/template/' . $config['theme'] . '/conf.json'; $json = is_file($conffile) ? xn_json_decode(file_get_contents($conffile)) : array(); } !empty($json['installed']) and $path_file = APP_PATH . 'view/template/' . $config['theme'] . '/htm/' . ($id ? $id . '_' : '') . $pre; (empty($path_file) || !is_file($path_file)) and $path_file = APP_PATH . 'view/template/' . $config['theme'] . '/htm/' . $pre; if (!empty($config['theme_child']) && is_array($config['theme_child'])) { foreach ($config['theme_child'] as $theme) { if (empty($theme) || is_array($theme)) continue; $path_file = APP_PATH . 'view/template/' . $theme . '/htm/' . ($id ? $id . '_' : '') . $pre; !is_file($path_file) and $path_file = APP_PATH . 'view/template/' . $theme . '/htm/' . $pre; } } !is_file($path_file) and $path_file = APP_PATH . ($dir ? 'plugin/' . $dir . '/view/htm/' : 'view/htm/') . $default_pre; return $path_file; } function theme_mode_pre($type = 0) { global $config; $mode = $config['setting']['website_mode']; $pre = ''; if (1 == $mode) { $pre .= 2 == $type ? 'portal_category.htm' : 'portal.htm'; } elseif (2 == $mode) { $pre .= 2 == $type ? 'flat_category.htm' : 'flat.htm'; } else { $pre .= 2 == $type ? 'index_category.htm' : 'index.htm'; } return $pre; } ?>php - update_user_meta as multiple value but with same meta key
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - update_user_meta as multiple value but with same meta key

programmeradmin0浏览0评论

I have this code. When I save it, the user levels adding and gives time select input next to it. But when I give different time to levels, for example: Level 1: 2 weeks, Level 2: 9 Months

If saves only the last element, then all inputs display that value. How can I save different times? Where do I wrong?

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

I have this code. When I save it, the user levels adding and gives time select input next to it. But when I give different time to levels, for example: Level 1: 2 weeks, Level 2: 9 Months

If saves only the last element, then all inputs display that value. How can I save different times? Where do I wrong?

//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');
Share Improve this question edited Nov 26, 2020 at 6:39 freedom667 asked Nov 17, 2020 at 15:24 freedom667freedom667 56 bronze badges 21
  • A side-note, you should use get_user_meta rather than get_the_author_meta – Tom J Nowell Commented Nov 17, 2020 at 15:59
  • I did not understand. get_user_meta will solve it directly? – freedom667 Commented Nov 17, 2020 at 20:33
  • No, if it did I would have left an answer rather than a comment, you should still use get_user_meta instead, get_the_author_meta is innapropriate for this use case – Tom J Nowell Commented Nov 18, 2020 at 10:27
  • my problem is, how can I store the meta as multiple – freedom667 Commented Nov 18, 2020 at 13:31
  • I know, as I said it was a comment, not an answer. Note that get_user_meta can do things that get_the_author_meta cannot. Technically get_the_author_meta shouldn't work here as the field parameter should not be able t accept arbitrary meta key values as there's a predefined whitelist, which means any answer will likely require get_user_meta, if not for that reason but because of its 3rd parameter. It is not possible to store the same meta key multiple times then retrieve them with get_the_author_meta, but it is with get_user_meta. – Tom J Nowell Commented Nov 18, 2020 at 13:38
 |  Show 16 more comments

1 Answer 1

Reset to default 0

Your HTML select tags for each level all have the same name and ID, and will overwrite each other. They must be unique. You will need separate names, IDs, and meta for each user level input.

Likewise, the user meta keys need to be unique. The code also needs to use get_user_meta instead ( get_the_author_meta is only to be used inside a post loop ).

I suggest using something similar to this:

    foreach ($user_levels as $user_level) {
        update_user_meta( $user_id, 'time-selector-' . $user_level, $_POST[ 'time-selector' . $user_level ] );
    }

Then changing your input names and IDs accordingly. e.g. <select name='time-selector-' . $user_level . 'You will also need to adjust your get_user_meta call to use the new keys

There is another mistake in your code however. selected does not return a string, it outputs it, so the selected="selected" HTML will be output in the wrong place. You need to pass a 3rd parameter false to make it return, otherwise your HTML markup will be incorrect, and the selected attribute will be displayed before the input markup is displayed.

Here is an example:

Saving the meta:

$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 ] );
    }
}

Displaying the input:

$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

Note several important things:

  • All levels have unique and independent HTML markup, and post meta
  • Nothing is shared between each field, if things were shared they would not be separate
  • I used an output buffer to make the HTML easier to read and generate
  • I added escaping, an important security feature
  • The list of times is no longer hardcoded, and was moved to a separate array to simplify the code and reduce repetition. This also means they can be filtered, added to, etc
  • The save code is in a separate snippet, handling post/user save should not happen on the same hook as displaying the data.
    • By putting the save code inside the display code in your original question, you may have introduced a bug
  • Because the user meta keys have changed, all prior data will need to be re-saved. This should not be an issue as the prior data is broken due to the way your original code worked. Any data loss that could occurred already happened before you wrote the question.
  • If you try to use this snippet, you will not see the full list of times. I deliberately limited the array to 2 entries to prevent people using this as a copy paste solution. Anybody with beginner level PHP skills can update the array to add the other choices
发布评论

评论列表(0)

  1. 暂无评论