Объедините мета-значения в новый ключ (PHP / WordPress)

Вот что мне нужно сделать, говоря простым языком:

Для каждого пользователя wordpress найдите каждый мета-ключ, который начинается с «FOO_», затем объедините все мета-значения в новый ключ с именем «FOO_COMBINED».

Мой вопрос относится к WordPress, но я думаю, что в целом он достаточно применим к PHP или SQL, и я надеюсь, что это подходящий форум.

Я обычно понимаю из связанных ответов, которые я нашел, что мне нужно сделать что-то вроде этого:

function combine_keys() {

    $array = // the array of (all?) user meta

    foreach ($array as $key => $value) {
        if (substr($key, 0, 4) == "FOO_") {
            // grab the $value and append it to another key??
        }
    }

}

Но я не знаю, как это перевести в функции WordPress. Я знаю, что get_users() получит всех пользователей. И get_user_meta($user_id) получит все пользовательские мета-данные для определенного идентификатора пользователя. Но я не знаю, как реализовать их в приведенной выше функции. У нас много пользователей, поэтому нужно делать это качественно.

Другой мой вопрос - когда вызывать функцию. Это делается для экспорта CSV. Я использую пользовательский плагин экспорта, но мне нужно объединить все ключи FOO_ со значениями, разделенными разрывом строки, в один ключ, чтобы нам не пришлось экспортировать миллион столбцов FOO_.

** ОБНОВИТЬ **

Вот мой обновленный код, пытающийся использовать приведенный ниже ответ. Я поместил это в functions.php.

function combine_keys( $user_id ) {

    $array    = array();
    $all_meta = get_user_meta( $user_id );

    foreach( $all_meta as $key => $meta ) {
        if( preg_match('/^WORKSHOP_/', $key) )
            $array[$key] = $meta[0];
    }

    return $array;
}

add_action('personal_options_update', function( $user_id ){
    if ( current_user_can('edit_user', $user_id) )
        update_user_meta( $user_id, 'WORKSHOP_COMBINED', combine_keys( $user_id ) );

});

Это работает для создания нового ключа (называемого WORKSHOP_COMBINED) и успешно объединяет значения в такой массив:

a: 2: {s: 10: "МАСТЕРСКАЯ_5"; s: 43: "Тест, 15 мая 2015 г., оценка: 80, количество часов: 30"; s: 11: "МАСТЕРСКАЯ_30"; s: 68: "Гражданское воспитание в средней школе И экономика, 4 июня 2015 г., оценка: 12, количество часов: 43 ";}

Но есть две проблемы:

  1. Каждый раз, когда я обновляю профиль, он ДОБАВЛЯЕТ другое комбинированное значение в ключ WORKSHOP_COMBINED, а не заменяет это значение. Хотя там написано update_meta, а не add_meta. Вы знаете, почему это происходит?

  2. Я хочу превратить массив в строку. Поэтому вместо "return $ array" я попытался взорвать его вот так:

    $ comma_separated = implode (",", $ массив); вернуть $ comma_separated;

Но это ничего не возвращает, и значение пусто. Что я сделал не так? Спасибо!


person LBF    schedule 28.04.2015    source источник


Ответы (1)


Вот:

function combine_keys( $user_id ) {

    $array    = array();
    $all_meta = get_user_meta( $user_id );

    foreach( $all_meta as $key => $meta ) {
        if( preg_match('/^FOO_/', $key) )
            $array[$key] = $meta[0];
    }

    return $array;
}

Вы можете создать комбинированный ключ следующим образом:

foreach (get_users() as $user) {
    $combined_meta = combine_keys( $user->ID );
    update_user_meta( $user->ID, 'FOO_COMBINED', $combined_meta );
}

Что касается того, когда его вызывать, вы можете сделать это прямо перед экспортом CSV (возможно, используя ловушку, предоставляемую плагином), или вы можете запланируйте его, когда захотите.

Или вы можете позволить одному пользователю сохранять свой личный комбинированный ключ при обновлении своего профиля:

add_action('personal_options_update', function( $user_id ){
    if ( current_user_can('edit_user', $user_id) )
        update_user_meta( $user_id, 'FOO_COMBINED', combine_keys( $user_id ) );
});

ОБНОВЛЕНИЕ

Отвечая на новые вопросы:

  1. Это происходит потому, что даже FOO_COMBINED начинается с FOO_, поэтому он добавляется в массив (извините, моя ошибка :). Замена шаблона поиска на /^FOO_(?!COMBINED)/ исключает этот ключ.
  2. Он должен работать, я не понимаю, почему это не так.

Я обновил код в соответствии с вашими новыми требованиями и протестировал его:

function combine_keys( $user_id ) {

    $array    = array();
    $all_meta = get_user_meta( $user_id );

    foreach( $all_meta as $key => $meta ) {
        if( preg_match('/^FOO_(?!COMBINED)/', $key) )
            $array[$key] = $meta[0];
    }

    return implode(',', $array);
}

add_action('personal_options_update', function( $user_id ){
    if ( current_user_can('edit_user', $user_id) )
        update_user_meta( $user_id, 'FOO_COMBINED', combine_keys( $user_id ) );

});
person d79    schedule 29.04.2015
comment
@ Линдси Привет, вы случайно не пробовали? Мне любопытно узнать, все ли прошло так, как ожидалось :) - person d79; 29.04.2015
comment
Хорошо, я попробовал, и это вроде сработало. У меня было два ключа с именами WORKSHOP_30 и WORKSHOP_5. И функция создала два новых ключа с одинаковыми значениями, которые называются WORKSHOP_COMBINED_WORKSHOP_30 и WORKSHOP_COMBINED_WORKSHOP_5. Я использовал ваш первый блок кода, а затем третий блок, чтобы вызвать его во время обновления личных параметров. Это было правильно? - person LBF; 30.04.2015
comment
Странно, только что перепроверил и работает. Вы уверены, что использовали точно такой же код? Вы добавили немного для цикла? Строка для обновления должна быть update_user_meta( $user_id, 'WORKSHOP_COMBINED', combine_keys( $user_id ) );. - person d79; 30.04.2015
comment
Хорошо, у меня получилось объединить ключи ... удалив мета и начав заново. СПАСИБО. Однако у меня возникла новая проблема, которую я обновил в приведенном выше коде. Он добавляет еще одно комбинированное значение каждый раз, когда я нажимаю на профиль обновления, а не заменяю. - person LBF; 30.04.2015
comment
Я не знаю, почему у меня это не работает, но новый код не может создать / обновить ключ. Я верю вам, что это работает, поэтому я не знаю, что не так. Ваш исходный код все еще работает (за исключением удвоения значений), поэтому я вернулся к этому и изменил имя нового ключа, чтобы он не использовал WORKSHOP_, и это решило повторение. Однако я все еще не могу заставить взорваться. Как только я добавлю это, значение будет пустым. Сумасшедший. Есть ли другой способ превратить его в строку? Я отмечу это как правильное, хотя для меня это еще не совсем работает. Спасибо за вашу помощь! - person LBF; 01.05.2015
comment
Единственное, что я могу думать, это то, что созданный массив не содержит только строки (возможно, также массив), поэтому implode не работает. - person d79; 01.05.2015
comment
У меня он работает (все еще использую ваш исходный код). Я полностью удалил старые ключи WORKSHOP_ (а не только значения). А затем воссоздал их, а затем запустил функцию объединения. Теперь, похоже, все работает. Значит, должно быть, что-то перепутали. Спасибо, что придерживаетесь этого, и за большую помощь. - person LBF; 01.05.2015
comment
Хорошо, рада это слышать и всегда рада помочь :) - person d79; 01.05.2015