Как включить предлагаемые правки?

12 мар. 2013 г., 13:52:38
Просмотры: 2.06K
Голосов: 21

Мне нравится идея включения возможности для любого пользователя моего сайта предлагать правки страниц. Похоже на систему правок в Stack Exchange, но с отличием - правки могут предлагать все, а не только зарегистрированные пользователи. Все правки будут проходить процесс утверждения.

Как я могу это реализовать?

4
Комментарии

Я не знаю, как это реализовать, но думаю, это может вызвать серьёзные проблемы. По-моему, вы получите много спама.

Martin Thoma Martin Thoma
13 мар. 2013 г. 20:39:52

Вы уверены, что для вашего сайта нужна именно установка WordPress? Описываемая функциональность очень напоминает MediaWiki. Вам стоит взвесить все плюсы и минусы обоих решений. MediaWiki — хорошая альтернатива.

Marc Dingena Marc Dingena
15 мар. 2013 г. 11:59:15

Я уже размышлял над подобной идеей. Ближайшим к решению был этот плагин: http://wordpress.org/support/plugin/post-forking Однако он находится на очень ранней стадии разработки. Плагин ограничен только для зарегистрированных пользователей.

Christine Cooper Christine Cooper
5 мая 2013 г. 03:10:49

Мы работали над чем-то подобным. Мы представляли себе редактирование постов в стиле Википедии вместе с виджетом "История": https://github.com/publishpress/Revisionary/issues/13 Мы пока не совсем достигли этой цели, но почти вся структура уже на месте.

steveburge steveburge
20 сент. 2019 г. 18:59:53
Все ответы на вопрос 3
1
11

Сравнение содержимого, заголовка и автора записи

Поскольку мне уже приходилось решать подобную задачу несколько месяцев назад, представляю самый простой и надежный способ (из тех, что я нашел) для проверки изменений в содержимом, заголовке или авторе записи:

// Обновление заголовка
'' !== wp_text_diff(
    $el['post_title'],
    $GLOBALS['post']->post_title
)
    AND $GLOBALS['post']->post_title = $el['post_title'];
// Обновление содержимого
'' !== wp_text_diff(
    $el['post_content'],
    $GLOBALS['post']->post_content
)
    AND $GLOBALS['post']->post_content = $el['post_content'];
// Обновление автора
$GLOBALS['post']->post_author !== $el['post_author']
    AND $GLOBALS['post']->post_author = $el['post_author'];

Кратко объясню мой сценарий: я получал записи с удаленного источника через API, затем возвращал global $post внутри цикла single post, содержащий либо оригинальные данные, либо новые. Таким образом, мне не приходилось вручную устанавливать все остальные значения записи, которые не требовали проверки на изменения.

Предложение правок

Основное, что нужно учитывать при поиске места для временного сохранения предлагаемых правок - это то, что содержимое записи хранится в базе данных как longtext. Поэтому место для сохранения предложенных изменений должно соответствовать этому требованию. Комментарии подходят идеально.

Дополнительный плюс в том, что система комментариев предоставляет API для их удобного отображения в цикле, что обеспечивает плавную интеграцию, высокую степень кастомизации и быструю настройку. Кроме того, большинство тем уже имеют встроенную поддержку комментариев, что позволяет легко подключиться к существующей системе и работать практически с любой темой.

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

<?php
// Добавляем для авторизованных пользователей и гостей:
add_action( 'comment_form_logged_in_after', 'wpse_proposed_edit_textarea' );
add_action( 'comment_form_after_fields', 'wpse_proposed_edit_textarea' );
function wpse_proposed_edit_textarea()
{
    ?>
    <p class="comment-form-title">
        <label for="wpse_propsed_edit">
            <?php _e( 'Предложить правку', 'your_textdomain' ); ?>
        </label>
        <textarea name="wpse_propsed_edit" id="wpse_propsed_edit">
            <?php the_content(); ?>
        </textarea>
    </p>
    <input type="hidden" name="comment_approved" id="comment_approved" value="0" />
    <?php
}

Я добавил скрытое поле comment_approved со значением 0, чтобы отправлять предложения на модерацию. Не уверен, будет ли это работать напрямую или это значение является метаданными комментария и требует использования add_comment_meta() при сохранении. Если нет, можно использовать что-то вроде следующего кода:

add_filter( 'pre_comment_approved' , 'wpse_pre_suggest_edit', 100, 2 );
function wpse_pre_suggest_edit( $approved , $commentdata )
{
    // Возможно, потребуется проверить $commentdata 
    // для определения статуса одобрения, отклонения или спама
    if ( ! empty( $commentdata['wpse_propsed_edit'] ) )
    {
        # Добавляем фильтр к действию сохранения комментария для сохранения метаданных
        add_action( 'comment_post', 'wpse_set_proposed_edit' );
        return 0;
    }

    return 1;
}

// Эта функция упрощает идентификацию комментариев по их мета-значению
function wpse_set_proposed_edit( $comment_id );
{
    // Выполняется только один раз
    remove_filter( current_filter(), __FUNCTION__ );

    add_comment_meta( $comment_id, 'proposed_edit', true, true );
}

Отображение комментариев в админке

Здесь я бы использовал простое расширение класса и пользовательскую страницу в админке:

function wpse_add_proposed_edits_admin_page()
{
    add_menu_page(
        'Предложенные правки',
        'Предложенные правки',
        'activate_plugins',
        'proposed_edits',
        'wpse_proposed_edits_page_cb'
    );
}
add_action( 'admin_menu', 'wpse_add_proposed_edits_admin_page' );

function wpse_proposed_edits_page_cb()
{
    $proposed_edits_table = new WP_Proposed_Edits_Table();
    $proposed_edits_table->prepare_items(); 
    $proposed_edits_table->display(); 
}

class WP_Proposed_Edits_Table extends WP_List_Table
{
    // Переопределяем стандартную логику таблицы здесь
}

Больше информации можно найти на WPEngineer.

Утверждение правок

Вы можете добавить пользовательские действия и обрабатывать предложенные правки, используя первый показанный код, чтобы проверить наличие изменений и затем просто обновить запись. Сам комментарий содержит значение с ключом comment_post_ID, что упрощает идентификацию ID редактируемой записи.

Заключительное замечание

Буду рад увидеть готовый плагин. Пожалуйста, оставьте ссылку здесь :)

7 мая 2013 г. 18:03:26
Комментарии

Я назначаю награду за этот вопрос за идею использовать метаданные комментария для хранения предлагаемого редактирования и wp_text_diff() для фактического сравнения. Голосую за другие ответы.

fuxia fuxia
8 мая 2013 г. 22:26:53
1

Моя идея довольно проста.

  • Вы можете добавить ссылку Предложить правку внизу записей, которая использует пользовательский шаблон. В этом шаблоне разместите текстовое поле (возможно, с редактором), связанное с пользовательской таксономией, где значением по умолчанию будет содержание записи.

  • Любые изменения в содержании будут сравниваться с оригинальным содержимым записи после отправки (как черновик) и ввода кода CAPTCHA с использованием алгоритмов сравнения, таких как пакет PHP inline-diff или Text-Diff из PEAR или альтернативно с помощью PHP-функции согласно этому для не слишком длинных текстов в сочетании с CSS.

  • Затем сохраните значения в 3 пользовательских метабоксах (на странице редактирования/добавления этой таксономии в админке), которые будут отображать:

    1. Оригинальное содержимое
    2. Отредактированную версию
    3. Никнейм пользователя и его Email

    и сохраните ID записи, возможно, с помощью функции update_option() для дальнейшего использования.

  • После проверки отредактированной версии и подтверждения администратором, оригинальная запись будет заменена, как вы прописали в functions.php.

15 мар. 2013 г. 11:56:57
Комментарии

Несколько замечаний: (A) "как вы закодировали в functions.php" - не согласен с этим. Это материал для плагина. (B) "связано с пользовательской таксономией со значением по умолчанию в виде содержимого записи" - У термина таксономии есть только одно возможное место, куда могло бы подойти содержимое: описание. И тогда вам понадобится место для хранения ID записи. Где это могло бы быть? Из-за ограничений системы таксономий WordPress для этого нет места, поэтому можно сохранить только ID термина. В этом случае это (ограниченная) односторонняя система: Запись > Данные термина.

kaiser kaiser
9 мая 2013 г. 18:05:03
0

Это довольно сложная задача, и для полного ответа потребуется значительное время. Поэтому это не настоящий ответ, а лишь некоторые мысли..

Использование встроенной функции WordPress wp_update_post через ajax даст вам историю изменений, но не предоставит возможности утверждать правки.

Создание черновиков из правок по умолчанию невозможно, но этот вопрос обсуждался здесь: Есть ли способ создать черновик из опубликованной страницы или записи? Какие обходные решения вы использовали?

Можно попробовать использовать Front-end Editor, но у вас не будет контроля над публикацией правок, поэтому попробуйте совместить его с другим плагином, например Revisionary, который позволяет управлять правками на основе разрешений. Правда, я не знаю, будут ли они работать вместе.

Если нет, вам придётся модифицировать плагин на основе двух вышеуказанных или написать что-то с нуля.

Мой подход "с нуля" заключался бы в кнопке, которая ведёт на другую страницу, выводящую содержимое/данные записи в формате JSON (с ним проще работать при использовании Ajax и WYSIWYG-редакторов). Кнопка сохранения отправляла бы данные как черновик, а не публикацию, что дало бы контроль над правками (см. обсуждение выше на WPSE о том, как этого добиться — задача нетривиальная).

Дополнительные сложности включают санитизацию, кодирование, защиту от спама, работу с медиафайлами, пользовательские поля, временные метки, память и т.д. Хорошая новость в том, что в WordPress уже есть система ревизий, к которой можно подключиться, и неплохая поддержка множества редакторов.

P.S. Это была бы отличная идея для плагина.

2 мая 2013 г. 02:13:51