Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

history rework #1502

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
vendor/
.phpunit.result.cache
.php-cs-fixer.cache
/.idea/*
205 changes: 205 additions & 0 deletions plugins/manager/fragments/yform/manager/history.diff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
<?php

/**
* @var rex_fragment $this
* @psalm-scope-this rex_fragment
*/

$historyId = $this->getVar('history_id', null);
$datasetId = $this->getVar('dataset_id', null);
$currentDataset = $this->getVar('current_dataset', null);

/** @var rex_yform_manager_table|null $table */
$table = $this->getVar('table', null);

$sql = rex_sql::factory();
$timestamp = $sql->setQuery(sprintf('SELECT `timestamp` FROM %s WHERE id = :id', rex::getTable('yform_history')), [':id' => $historyId])->getValue('timestamp');

$data = $sql->getArray(sprintf('SELECT * FROM %s WHERE history_id = :history_id', rex::getTable('yform_history_field')), [':history_id' => $historyId]);
$data = array_column($data, 'value', 'field');

if(null !== $historyId && null !== $table):

$diffs = [
'changed' => ['icon' => 'fas fa-not-equal', 'count' => 0, 'rows' => ''],
'added' => ['icon' => 'fas fa-layer-plus', 'count' => 0, 'rows' => ''],
'removed' => ['icon' => 'far fa-layer-minus', 'count' => 0, 'rows' => ''],
'unchanged' => ['icon' => 'fas fa-equals', 'count' => 0, 'rows' => ''],
// 'prev_changed' => ['icon' => 'fas fa-not-equal', 'count' => 0, 'rows' => ''],
];

$fieldsInDataset = [];

$tableFields = $table->getFields();

foreach ($table->getValueFields() as $field) {
if (!array_key_exists($field->getName(), $data)) {
if($currentDataset->hasValue($field->getName())) {
++$diffs['added']['count'];
$diffs['added']['rows'] .= '
<tr>
<th>' . rex_yform_history_helper::getFieldTypeIcon($field) . ' ' . $field->getLabel() . '</th>
<td>' . rex_yform_history_helper::getFieldValue($field, $currentDataset, $table) . '</td>
<td><em>' . rex_i18n::msg('yform_history_diff_not_yet_existing') . '</em></td>
</tr>';
}

continue;
}

$change = 'unchanged';

$fieldsInDataset[] = $field->getName();
$historyValue = $data[$field->getName()];
$currentValue = ($currentDataset->hasValue($field->getName()) ? $currentDataset->getValue($field->getName()) : '-');

$class = 'rex_yform_value_' . $field->getTypeName();

// count diffs
if(!$currentDataset->hasValue($field->getName())) {
$change = 'deleted';
} elseif('' . $historyValue !== '' . $currentValue) {
$change = 'changed';
}

++$diffs[$change]['count'];

if (is_callable([$class, 'getListValue']) && !in_array($field->getTypeName(), ['text', 'textarea'], true)) {
// to ensure correct replacement with list value, ensure datatype by current dataset
if(gettype($currentValue) !== gettype($historyValue)) {
settype($historyValue, gettype($currentValue));
}

// get (formatted) value for history entry
$historyValue = $class::getListValue([
'value' => $historyValue,
'subject' => $historyValue,
'field' => $field->getName(),
'params' => [
'field' => $field->toArray(),
'fields' => $this->table->getFields(),
],
]);

// get (formatted) value for current entry
if($currentDataset->hasValue($field->getName())) {
$currentValue = $class::getListValue([
'value' => $currentValue,
'subject' => $currentValue,
'field' => $field->getName(),
'params' => [
'field' => $field->toArray(),
'fields' => $tableFields,
],
]);
} else {
$currentValue = '-';
}
} else {
$historyValue = rex_escape($historyValue);
$currentValue = rex_escape($currentValue);
}

// diff values for specific fields
if('changed' === $change) {
switch($field->getTypeName()) {
case 'text':
case 'textarea':
$diff = rex_yform_history_helper::diffStringsToHtml($currentValue, $historyValue);
$historyValue = $diff;
break;

default:
if($historyValue !== $currentValue) {
$historyValue = '<span class="diff">' . $historyValue . '</span>';
}
break;
}
}

$diffs[$change]['rows'] .= '
<tr>
<th>' . rex_yform_history_helper::getFieldTypeIcon($field) . ' ' . $field->getLabel() . '</th>
<td>' . $currentValue . '</td>
<td>' . $historyValue . '</td>
</tr>';

// remove field from dataset to collect meanwhile deleted fields
unset($data[$field->getName()]);
}

foreach ($data as $field => $value) {
++$diffs['removed']['count'];
$diffs['removed']['rows'] .= '
<tr>
<th><i data-toggle="tooltip" data-placement="top" title="" class="rex-icon fas fa-question" data-original-title="' .
rex_i18n::msg('yform_manager_type_name') . ': ' . rex_i18n::msg('yform_manager_type_unknown') . '"></i> ' . $field . '</th>
<td><em>' . rex_i18n::msg('yform_history_diff_no_longer_existing') . '</em></td>
<td>' . $value . '</td>
</tr>';
}

// build restore url
$restoreUrl = http_build_query([
'table_name' => $table->getTableName(),
'func' => 'history',
'subfunc' => 'restore',
'data_id' => $datasetId,
'history_id' => $historyId,
]) . http_build_query(rex_csrf_token::factory($this->getVar('csrf_key', ''))->getUrlParams());

$content = '
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
' . rex_i18n::msg('yform_history_dataset_id') . ': ' . $datasetId . '
<small>[' . date('d.m.Y H:i:s', strtotime($timestamp)) . ']</small>
</h4>
</div>
<div class="modal-body panel-default">
';

foreach ($diffs as $change => $diff) {
$content .= '
<header class="panel-heading" ' . ('' !== $diff['rows'] ? 'data-toggle="collapse" data-target="#collapse-history-table-' . $change . '"' : '') . '>
<div class="panel-title"><i class="rex-icon ' . $diff['icon'] . '"></i> ' . rex_i18n::msg('yform_history_diff_headline_' . $change) .
' [' . ($diff['count'] > 0 ? '<b>' : '') . $diff['count'] . ($diff['count'] > 0 ? '</b>' : '') . ']' . '
</div>
</header>
<div id="collapse-history-table-' . $change . '" ' . ('' !== $diff['rows'] ? 'class="panel-collapse collapse ' . ('changed' === $change ? 'in' : '') . '"' : '') . '>';

if('' !== $diff['rows']) {
$content .= '
<table class="table history-diff-table" data-change-mode="' . $change . '">
<thead>
<tr>
<th class="rex-table-width-7 field-name"><i class="rex-icon-"></i>' . rex_i18n::msg('yform_tablefield') . '</th>
<th class="rex-table-width-10">' . rex_i18n::msg('yform_history_dataset_current') . '</th>
<th class="rex-table-width-10">' . date('d.m.Y H:i:s', strtotime($timestamp)) . '</th>
</tr>
</thead>
<tbody>' . $diff['rows'] . '</tbody>
</table>';
}

$content .= '</div>';
}

$content .= '
</div>
<div class="modal-footer">
<a href="index.php?page=yform/manager/data_edit?' . $restoreUrl . '" class="btn btn-warning" onclick="return confirm(\'' . rex_i18n::msg('yform_history_restore_confirm') . '\')">' .
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kein onclick bitte, sondern js in Dateien auslagern. CSP macht da sonst Probleme

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wird gemacht

rex_i18n::msg('yform_history_restore_this') .
'</a>
<button type="button" class="btn btn-default" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<script>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hier müsste noch nonce="' . rex_response::getNonce() . '" noch rein, aber lieber noch, wenn das ausgelagert wird, in die yform js Dateien, oder ein eigenes für historie anlegen

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich leg ne .js an

// init bootstrap tooltips
$(".modal#rex-yform-history-modal [data-toggle=\"tooltip\"]").tooltip({
html: true
})
</script>
';

echo $content;
endif;
21 changes: 18 additions & 3 deletions plugins/manager/lang/de_de.lang
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
yform_function_button = Aktion

yform_manager = Table Manager

navigation_manager = Tabellen
Expand All @@ -14,7 +12,7 @@ yform_errors_occurred = Es sind Fehler aufgetreten
yform_help_empty = Leereinträge können mit <br />"(empty)" gesucht werden
yform_help_multipleselect = Mehrfachauswahl mit gedrückter CTRL/CMD Taste
yform_updatetable_with_delete = mit Feldlöschung
yform_updatetable_with_delete_confirm = Wirklich aktualisieren mit Feldlöschung ?
yform_updatetable_with_delete_confirm = Wirklich aktualisieren mit Feldlöschung?

yform_relation_move_first_data = Ausgewählten Datensatz an den Anfang verschieben
yform_relation_move_up_data = Ausgewählten Datensatz nach oben verschieben
Expand Down Expand Up @@ -93,6 +91,7 @@ yform_manager_table_features = Aktivierte Optionen

yform_manager_type_id = Typ
yform_manager_type_name = Typname
yform_manager_type_unknown = unbekannt

yform_manager_tableset = Tableset
yform_manager_table = Tabelle
Expand Down Expand Up @@ -234,8 +233,10 @@ yform_manager_import_error_duplicatefielddefinition = Es gibt Felder, welche ide

# history
yform_history = Historie
yform_history_title = Historie für
yform_history_dataset_id = Datensatz-ID
yform_history_dataset = Datensatz
yform_history_dataset_current = Aktuelle Version
yform_history_action = Aktion
yform_history_action_create = erstellt
yform_history_action_update = bearbeitet
Expand All @@ -244,6 +245,7 @@ yform_history_user = Benutzer
yform_history_timestamp = Zeitstempel
yform_history_view = ansehen
yform_history_restore = zurücksetzen
yform_history_restore_confirm = Wirklich auf diese Version zurücksetzen?
yform_history_restore_this = Datensatz auf diese Version zurücksetzen
yform_history_restore_success = Datensatz wurde zurückgesetzt.
yform_history_restore_error = Datensatz konnte nicht zurückgesetzt werden.
Expand All @@ -252,6 +254,19 @@ yform_history_delete_all = komplett
yform_history_delete_older_3_months = älter als 3 Monate
yform_history_delete_confirm = Historie wirklich löschen?
yform_history_delete_success = Die Historien-Datensätze wurden gelöscht.
yform_history_revision = Revision/Änderung
yform_history_dataset_missing = Es wurde keine (gültige) Datensatz-ID übergeben! Der Vergleich mit einem ausgewählten Eintrag der Historie ist daher nicht möglich.
yform_history_diff_headline_changed = Geänderte Werte
yform_history_diff_headline_unchanged = Unveränderte Werte
yform_history_diff_headline_added = Hinzugefügte Felder
yform_history_diff_headline_removed = Entfernte Felder
yform_history_diff_headline_prev_changed = Änderungen gegenüber vorheriger Version
yform_history_diff_to_current = Änderungen (zu aktuell)
yform_history_diff_to_previous = Änderungen (zu vorherig)
yform_history_diff_added = neu
yform_history_diff_removed = entfernt
yform_history_diff_not_yet_existing = noch nicht vorhanden
yform_history_diff_no_longer_existing = nicht mehr vorhanden

yform_manager_show_form_notation = Formular-Code

Expand Down
38 changes: 35 additions & 3 deletions plugins/manager/lang/en_gb.lang
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ yform_manager_table_features = Activated options

yform_manager_type_id = Type
yform_manager_type_name = Type name
yform_manager_type_unknown = unknown

yform_manager_tableset = Table set
yform_manager_table = Table
Expand Down Expand Up @@ -125,6 +126,9 @@ yform_manager_table_hidden = Visibility
yform_hidden = hidden
yform_visible = visible

yform_manager_actions_all = all actions
yform_manager_users_all = all users
yform_manager_history_date_notice = all entries before and equal to this date are displayed

# edit.inc.php
yform_thankyouforupdate = Record updated.
Expand Down Expand Up @@ -163,9 +167,11 @@ yform_dataset_delete = Delete result reset
yform_dataset_deleted = Result set deleted
yform_dataset_delete_confirm = Delete result set?

yform_data = Record
yform_datas = Records
yform_manager_search = Search
yform_dataset_edit_confirm = Should all selected data records really be edited?

yform_data = data record
yform_datas = data records
yform_manager_search = search

yform_data_view = show

Expand Down Expand Up @@ -227,8 +233,10 @@ yform_manager_import_error_duplicatefielddefinition = There are identical fields

# history
yform_history = History
yform_history_title = Historie for
yform_history_dataset_id = Record ID
yform_history_dataset = Record
yform_history_dataset_current = current version
yform_history_action = Action
yform_history_action_create = created
yform_history_action_update = updated
Expand All @@ -237,6 +245,7 @@ yform_history_user = User
yform_history_timestamp = Timestamp
yform_history_view = view
yform_history_restore = revert
yform_history_restore_confirm = Really revert to this version?
yform_history_restore_this = Revert record to this version
yform_history_restore_success = Record reverted
yform_history_restore_error = Record could not be reverted.
Expand All @@ -245,6 +254,19 @@ yform_history_delete_all = completely
yform_history_delete_older_3_months = older than 3 months
yform_history_delete_confirm = Delete History?
yform_history_delete_success = History records deleted.
yform_history_revision = revision/change
yform_history_dataset_missing = No (valid) data record ID was transferred! A comparison with a selected entry in the history is therefore not possible.
yform_history_diff_headline_changed = changed values
yform_history_diff_headline_unchanged = unchanged values
yform_history_diff_headline_added = added fields
yform_history_diff_headline_removed = removed fields
yform_history_diff_headline_prev_changed = changes compared to previous version
yform_history_diff_to_current = changes (to current)
yform_history_diff_to_previous = changes (to previous)
yform_history_diff_added = added
yform_history_diff_removed = removed
yform_history_diff_not_yet_existing = not yet existing
yform_history_diff_no_longer_existing = no longer existing

yform_manager_show_form_notation = Form code

Expand Down Expand Up @@ -285,3 +307,13 @@ yform_will_set_to = will be
yform_field_add = Add field
yform_field_update = Update field
yform_field_db_type = Database field type

yform_manager_table_data_view_roles = Data view limited to
yform_manager_table_data_edit_roles = Data editing limited to

yform_manager_table_nopermission = No permission for this table

yform_manager_tables_edit = Tables with editing permission
yform_manager_tables_view = Tables with view permission

yform_structure_article_could_not_be_deleted = The article could not be deleted because it is used by the following data records:
Loading
Loading