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

EP YFORM_DATA_UPDATED enthält in $old_data nicht alte Daten, wenn per YOrm gespeichert #1443

Open
alxndr-w opened this issue Jul 29, 2023 · 1 comment

Comments

@alxndr-w
Copy link
Contributor

https://github.com/yakamara/redaxo_yform/blob/1fad431332911e8921b3f3c213d382d2125247f1/plugins/manager/lib/yform/manager/dataset.php#L554

Ich habe einen EP, der wie folgt aufgebaut ist:

    public static function yform_ticket_mail($ep) :void
    {
        $subject = $ep->getSubject();
        $table = $subject->objparams['main_table'];

        if ($table == "rex_dance_event_ticket") {

            $old_status = $ep->getParams()['old_data']['status'];
            $new_status = $ep->getParams()['data']->getValue('status');

            $subject->getForm();

            if ($old_status !== $new_status && $new_status !== 0) {
                $yform = new rex_yform();
                $yform->setObjectparams('csrf_protection', false);
                $yform->setValueField('hidden', ['event_date_id',$ep->getParams()['data']->getValue('event_date_id'), null, true]);
                $yform->setValueField('hidden', ['event_name',$ep->getParams()['data']->getRelatedDataset('event_date_id')->getName(), null, true]);
                $yform->setValueField('hidden', ['event_date',$ep->getParams()['data']->getRelatedDataset('event_date_id')->intlDate('startDate'), null, true]);
                $yform->setValueField('hidden', ['name',$ep->getParams()['data']->getValue('name')]);
                $yform->setValueField('hidden', ['email',$ep->getParams()['data']->getValue('email')]);
                $yform->setValueField('hidden', ['number',$ep->getParams()['data']->getValue('number')]);
                $yform->setValueField('hidden', ['status',$ep->getParams()['data']->getValue('status')]);

                $email_templates = [
                    -1 => 'dance_event_ticket_cancelled',
                    1 => 'dance_event_ticket_confirmed'
                ];
                $yform->setActionField('tpl2email', [$email_templates[(int) $new_status], 'email']);
                $yform->setActionField('tpl2email', [$email_templates[(int) $new_status], '[email protected]']);

                $yform->getForm();
                $yform->setObjectparams('send', 1);
                $yform->executeActions();
            }
        }

    }

Dieser wird grundsätzlich erfolgreich getriggert, wenn der Datensatz sich ändert - egal, ob über das Table Manager Backend, oder per YOrm-Aufruf, gelöst über eine rex_api.

Wie zu entnehmen ist, möchte ich, dass eine Mail versendet wird, wenn der Status sich von 0 auf nicht-0 ändert. Das klappt auch über den Table Manager. Ich erhalte in $old_status den bisherigen Wert und anschließend den neu gespeicherten.

Hingegen über das direkte Speichern mit YOrm erhalte ich reproduzierbar sowohl als alten, als auch als neuen Wert denselben.

<?php

class rex_api_dance_event_ticket extends rex_api_function
{
    protected $published = true;



    public function execute()
    {
        rex_response::cleanOutputBuffers();

        $api_key = rex_request('api_key', 'string', "");
        $status = rex_request('status', 'string', '0');

        $ticket = dance_event_ticket::query()->where('api_key', $api_key)->findOne();

        $old_status = $ticket->getValue('status');
        if ($ticket) {
            $ticket->setValue('status', $status);
            if (!$ticket->save()) { //
                rex_logger::factory()->log('Error', 'error: API Call: rex_api_dance_event_ticket status not saved');
                rex_response::setStatus(rex_response::HTTP_BAD_REQUEST);
            } else {
                    if($status == 1) {
                        echo "✅ bestätigt, Mail wurde versendet.";
                    } elseif($status == -1) {
                        echo "❌ storniert, Mail wurde versendet.";
                    } else {
                        echo "🤔 bereits bearbeitet? Keine Mail wurde versendet.";
                    }
                }

                rex_response::setStatus(rex_response::HTTP_OK);
            }
        } else {
            rex_logger::factory()->log('Error', 'error: API Parameter not correct');
            rex_response::setStatus(rex_response::HTTP_BAD_REQUEST);
        }
        exit();
    }
}

Ich speichere mit $ticket->save() das Ticket, der EP wird ordnungsgemäß aufgerufen.

@michael-kreatif
Copy link
Contributor

michael-kreatif commented Aug 11, 2023

Kanns leider auch reproduzieren und ist unangenehm, weil man den Fehler leider nicht sofort findet.
Hatte das Problem auch schon ein paar Mal, sobald man auf Datenänderung in Yform reagieren möchte.

Also so wie bei Alex -> wenn im Redaxo Backend im YForm Formular gespeichert wird, dann enthält oldData die ursprünglichen Daten. Wenn aber direkt über YOrm gespeichert, dann enthält oldData immer die aktuellen Daten, da das selbe Objekt verwendet wird, wo man bereits die Values über setValue gesetzt hat.

Somit ist oldData bei direkter YOrm Speicherung aktuell sinnlos, weil man doch nicht abfragen kann, ob sich die Werte geändert haben oder nicht.

/** @var rex_yform_manager_dataset|null $modelClass */
$modelClass = rex_yform_manager_dataset::get($data_id, $table);
if ($modelClass) {
$modelClass->setValue('status', (int) $status);
$modelClass->save();
}

https://github.com/yakamara/redaxo_yform/blob/master/plugins/manager/lib/yform/manager/dataset.php#L517

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants