Визуальное сравнение текстов через Bitrix\Main\Text\Diff

09.12.2025

При работе с инфоблоками в режиме документооборота накапливается история версий элементов. Стандартный интерфейс Битрикс показывает список версий, но не позволяет увидеть конкретные изменения между ними. Класс Bitrix\Main\Text\Diff решает эту задачу.

Класс реализует алгоритм Майерса и предоставляет метод getDiffHtml(), который принимает две версии текста и возвращает HTML с подсветкой: удалённые фрагменты выделены красным перечёркнутым текстом, добавленные — зелёным жирным.

Сравнение версий элемента инфоблока

        use Bitrix\Main\Text\Diff;

/**
 * Получает историю версий элемента через скомпилированный ORM класс
 */
function getElementHistory(int $elementId)
{
    return \Bitrix\Iblock\Elements\ElementNewsTable::getList([
        'select' => [
            'ID',
            'NAME',
            'PREVIEW_TEXT',
            'DETAIL_TEXT',
            'TIMESTAMP_X',
            'WF_COMMENTS',
            'WF_STATUS_ID',
            'WF_PARENT_ELEMENT_ID',
            'MODIFIER_' => 'MODIFIED_BY_USER',
        ],
        'filter' => [
            'WF_PARENT_ELEMENT_ID' => $elementId,
        ],
        'order' => ['ID' => 'ASC'],
    ])->fetchCollection();
}


$elementId = 37; // ID элемента в режиме документооборота
$history = getElementHistory($elementId);

if ($history->count() >= 2) {
    $items = $history->getAll();
    $prev = $items[count($items) - 2];
    $curr = $items[count($items) - 1];

    $diff = new Diff();

    echo '<div class="version-diff">';
    echo '<p>Версия #' . $curr->getId() . ' от ' . $curr->getTimestampX() . '</p>';
    echo '<p>Автор: ' . $curr->getModifiedByUser()->getLogin() . '</p>';

    if ($curr->getWfComments()) {
        echo '<p>Комментарий: ' . htmlspecialchars($curr->getWfComments()) . '</p>';
    }

    echo '<h4>Название:</h4>';
    echo $diff->getDiffHtml($prev->getName(), $curr->getName());

    echo '<h4>Описание:</h4>';
    echo $diff->getDiffHtml(
        $prev->getDetailText() ?? '',
        $curr->getDetailText() ?? ''
    );
    echo '</div>';
}

    

Вывод diff для всей истории элемента

        // Формируем полную историю изменений с diff
$history = getElementHistory($elementId);
$diff = new Diff();
$items = $history->getAll();

echo '<div class="history-timeline">';
for ($i = 1; $i < count($items); $i++) {
    $prev = $items[$i - 1];
    $curr = $items[$i];

    printf(
        '<div class="history-item">
            <div class="meta">%s | %s | Статус: %d</div>
            <div class="comment">%s</div>
            <div class="changes">%s</div>
        </div>',
        $curr->getTimestampX()->format('d.m.Y H:i'),
        $curr->getModifiedByUser()?->getLogin() ?? 'N/A',
        $curr->getWfStatusId(),
        htmlspecialchars($curr->getWfComments() ?? ''),
        $diff->getDiffHtml(
            $prev->getDetailText() ?? '',
            $curr->getDetailText() ?? ''
        )
    );
}
echo '</div>';

    

Для программного анализа используйте метод getDiffScript(), который возвращает массив операций с ключами startA, startB, deletedA, insertedB.

Опубликовано 1 неделю назад