Вопрос или проблема
У меня есть пользовательский тип записи, который позволяет зарегистрированным пользователям добавлять видео на мой сайт. Я изменил скрипт так, чтобы незарегистрированные (гостевые) пользователи также могли добавлять видео. Я добавил метаполя для имени, фамилии и электронной почты в запись, чтобы я мог фиксировать, кто разместил её, и отображать эту информацию в колонке “Автор” в админке. Любое видео, опубликованное зарегистрированным пользователем, также будет отображаться в колонке “Автор” соответствующим образом. Я настроил все виды на фронтенде так, чтобы показывались либо метаданные гостевого пользователя, либо информация о зарегистрированном авторе.
Проблема возникает, когда дело доходит до редактирования записи, что должны делать администраторы для её утверждения, отметки как избранной и т.д. Эти записи имеют идентификатор автора 0, и когда администратор выполняет какие-либо действия с записью, автор обновляется на идентификатор пользователя администратора, который вошёл в систему.
Давайте немного отступим. Сначала, когда я собирался редактировать одну из этих гостевых записей видео, я заметил, что в поле автора было выбрано имя администратора, потому что фактический автор (гость без учётной записи пользователя) не был доступен в списке. С помощью jQuery я добавил опцию “Гость” в начало метабокса автора и установил значение 0 (я даже пробовал оставить значение пустым). Идея состояла в том, чтобы, если запись от гостя, оставить это значение неизменным и вносить изменения в запись, сохраняя автора как 0 ИЛИ я могу вручную переопределить автора и назначить его конкретному пользователю.
Проблема в том, что даже с jQuery на месте и оставляя выбор на “Гость”, запись всё равно обновляется и приписывается текущему авторизованному администратору.
function add_null_author_option() {
global $post;
$post_id = $post->ID;
if(!$post->post_author) {
$first_name = get_post_meta($post_id, 'first-name', true);
$last_name = get_post_meta($post_id, 'last-name', true);
echo "<script>
jQuery(document).ready( function() {
var post_id = $post_id,
first_name=\"$first_name\",
last_name=\"$last_name\";
console.log('Post: ' + post_id);
console.log('First Name: ' + first_name);
jQuery( '#post_author_override' ).prepend( '<option value=\"\" selected>Guest - ' + first_name + ' ' + last_name + '</option>' );
});
</script>";
}
}
add_action('admin_footer-post.php', 'add_null_author_option');
add_action('admin_footer-post-new.php', 'add_null_author_option');
Я не уверен, является ли это проблемой функции wp_update_post()
, которая по умолчанию устанавливает текущий идентификатор пользователя, когда значение post_author равно 0 или пустое. Если да, есть ли способ обойти это только для моего пользовательского типа записи?
function preserve_anonymous_author($data, $postarr) {
// Проверьте, является ли это обновлением (не новой записью)
if (!empty($postarr['ID'])) {
$existing_author = get_post_field('post_author', $postarr['ID']);
// Если существующий автор равен 0, сохраните его 0
if ($existing_author == 0) {
$data['post_author'] = 0;
}
}
return $data;
}
add_filter('wp_insert_post_data', 'preserve_anonymous_author', 10, 2);
Ответ или решение
Для решения проблемы необходимости сохранения идентификатора автора в 0 при обновлении поста гостем в WordPress, необходимо разобраться в том, как WordPress обрабатывает посты, созданные и обновляемые через админку, особенно когда речь идет о пользователях, не имеющих регистрации. Давайте разберем вашу ситуацию более детально, используя методику TEA (Теория, Пример, Применение).
Теория
В стандарте WordPress функция wp_update_post()
предназначена для обновления информации о постах в базе данных, и она по умолчанию устанавливает идентификатор текущего пользователя как автора, если post_author
передается как 0 или отсутствует. Это связано с тем, что система контент-менеджмента должна знать, кто несет ответственность за изменения, чтобы поддерживать целостность и безопасность базы данных.
Пример
Ваш сценарий: у вас есть пользовательская запись, предоставляющая возможность гостевым пользователям загружать видео. Для регистрации авторства гостей вы добавили дополнительные мета поля, такие как имя и фамилия, которые потом отображаются в колонке «Автор» в админке. Проблема возникает, когда администратор редактирует запись: авторство перезаписывается на идентификатор администратора, даже если вы предварительно добавили поле "Гость" с идентификатором 0 в выбор автора.
Ваш подход с использованием jQuery был направлен на добавление параметра "Гость" в метабокс для автора. Однако препятствием стало поведение WordPress при обновлении постов, которое автоматически присваивает идентификатор текущего пользователя, если post_author
равен 0.
Применение
Для обхода этой проблемы мы внедрим фильтр wp_insert_post_data
. Вы уже начали использовать его в своей функции preserve_anonymous_author
. Вы находитесь на правильном пути, однако есть несколько аспектов, которые необходимо учесть для полной реализации:
-
Проверка существующего ID автора: Когда пост обновляется, мы должны убедиться, что если
post_author
был 0, он сохраняет это значение. Вы корректно используете функциюget_post_field
для этого. -
Корректное применение фильтра: Убедитесь, что фильтр
wp_insert_post_data
правильно сформулирован и включен перед вызовомwp_update_post()
в любом из ваших кастомных скриптов. -
Инициализация checkboxes и условий: Если у администратора есть возможность изменить автора на другого зарегистрированного пользователя, это изменение должно вступать в силу только при явном действии администратора, и не должно быть по умолчанию.
-
Учет форматов данных: Если вы используете пустую строку или ноль в качестве значений, убедитесь, что они не пересекаются с другими возможными ID авторов и обрабатываются корректно во всех функциях WordPress.
-
Обработка ошибок и уведомлений: Хорошей практикой будет добавление логирования и обработки исключений, чтобы можно было отслеживать, когда и почему изменения аутентификации не происходят ожидаемым образом.
Таким образом, реализация концентрации на сохранении авторства как 0 при взаимодействии админа с постом может выглядеть примерно так:
function preserve_anonymous_author($data, $postarr) {
// Check if this is an update (not a new post)
if (!empty($postarr['ID'])) {
$existing_author = get_post_field('post_author', $postarr['ID']);
// If the existing author is 0, keep it 0
if ($existing_author == 0) {
$data['post_author'] = 0;
}
elseif (isset($postarr['post_author'])) {
$data['post_author'] = $postarr['post_author'];
}
}
return $data;
}
add_filter('wp_insert_post_data', 'preserve_anonymous_author', 10, 2);
В дополнение, убедитесь, что при редактировании поста в WordPress админ панели добавлен соответствующий код для предотвращения смены автора без необходимости. Для этого можно использовать JavaScript, но важно помнить, что это только клиентская проверка и всегда должна сопровождаться серверной.
Следуя этой стратегии, вы сможете избежать ненужного изменения авторства для постов, загруженных гостевыми пользователями, когда эти посты обновляются администраторами сайта в WordPress.