Verhindern Sie eine AJAX-Endlosschleife, wenn Sie eine eigene API verwenden

Lesezeit: 4 Minuten

Benutzeravatar von Chris O'Kelly
Chris O’Kelly

Ich versuche derzeit, eine Integration zwischen zwei WordPress-Plugins zu finden: dem WooCommerce Follow-Up-E-Mail-Plugin und dem Ninja-Formular-Plugin (mit dem Endziel, dass wir eine manuelle Follow-up-E-Mail-Vorlage als Antwort auf die Übermittlung von Ninja-Formularen senden können ). Wir verwenden Ninja Forms 3, für das, was es wert ist.

Beim Definieren der Optionen für die Aktionsklasse Ich stelle dem Benutzer eine Liste der Vorlagen zur Verfügung, damit er beim Definieren der Aktion die zu sendende Vorlage auswählen kann. Um die E-Mail-Vorlagen aus dem Follow-up-E-Mail-Plugin zu erhalten, verwende ich deren API-Clientspeziell die get_emails() Methode (die wiederum in einen GET-Aufruf an die /emails Endpunkt unter ihrer API-URL).

Das Problem ist folgendes: Laden Sie auf jeder Seite die ninja_forms_register_actions action wird aufgerufen, währenddessen ich meine Aktionsklasse instanziiere. Während der __construct aufrufen, füllen wir die Einstellungen für die Aktion aus und rufen dazu die Follow-up-E-Mail-API auf. Dadurch wird ein Seitenladevorgang initiiert, während dessen die ninja_forms_register_actions Aktion heißt…

Obwohl ich dieses Problem erwartet hatte, half meine geplante Lösung nicht: Das heißt, ich hatte geplant, Transienten zu verwenden, um das Ergebnis des API-Aufrufs wie folgt zu speichern:

private static function _get_templates()
    {
        error_log('_get_templates() started - ' . microtime(true));
        if (false === ($templates = get_transient(self::TEMPLATE_TRANSIENT))) {
            error_log('_get_templates() fetching - ' . microtime(true));
            $fue_api = self::fue_api();
            $templates = $fue_api->get_emails();
            set_transient(self::TEMPLATE_TRANSIENT, $templates, self::TEMPLATE_TRANSIENT_EXPIRY);
            error_log('_get_templates() fetched - ' . microtime(true));
        }
        error_log('_get_templates() done - ' . microtime(true));

        return $templates;
    }

Das Ergebnis in meinen Protokollen ist jedoch Folgendes:

[22-May-2016 23:53:33 UTC] _get_templates() started - 1463961213.692187
[22-May-2016 23:53:33 UTC] _get_templates() fetching - 1463961213.694222
[22-May-2016 23:53:34 UTC] _get_templates() started - 1463961214.05998
[22-May-2016 23:53:34 UTC] _get_templates() fetching - 1463961214.061054
[22-May-2016 23:53:38 UTC] _get_templates() started - 1463961218.660683
[22-May-2016 23:53:38 UTC] _get_templates() fetching - 1463961218.661265
[22-May-2016 23:53:40 UTC] _get_templates() started - 1463961220.772228
[22-May-2016 23:53:40 UTC] _get_templates() fetching - 1463961220.774142
[22-May-2016 23:53:41 UTC] _get_templates() started - 1463961221.150277
[22-May-2016 23:53:41 UTC] _get_templates() fetching - 1463961221.654757
[22-May-2016 23:53:45 UTC] _get_templates() started - 1463961225.306565
[22-May-2016 23:53:45 UTC] _get_templates() fetching - 1463961225.308898
[22-May-2016 23:53:46 UTC] _get_templates() started - 1463961226.281794
[22-May-2016 23:53:46 UTC] _get_templates() fetching - 1463961226.283803

Dies wird fortgesetzt, bis ich den Webserverprozess oder etwas anderes Drastisches wie das Löschen/Umbenennen des Plugin-Ordners beende, woraufhin der Transient mit einem HTTP-Fehlercode gefüllt wird (was an sich nicht überraschend ist). Meine transiente Lösung funktioniert also eindeutig nicht, da der Transient bis nach der Anfrage noch nicht festgelegt ist.

In manchen Situationen wie dieser würde ich eine Überprüfung für hinzufügen DOING_AJAXaber das passt aus zwei Gründen nicht – ich brauche diese Daten immer noch, um für die Ninja Forms AJAX-Prozesse verfügbar zu sein, und ich bin mir auch nicht sicher, ob DOING_AJAX hier tatsächlich gesetzt wäre, da die FUE-API nicht verwendet wird admin-ajax.php. Ich hatte überlegt, auf folgendes umzustellen:

private static function _get_templates()
        {
            error_log('_get_templates() started - ' . microtime(true));
            if (false === get_option(self::TEMPLATE_LOCK_OPTION, false) && false === ($templates = get_transient(self::TEMPLATE_TRANSIENT))) {
                delete_option(self::TEMPLATE_LOCK_OPTION);
                add_option(self::TEMPLATE_LOCK_OPTION, true, '', 'no');
                error_log('_get_templates() fetching - ' . microtime(true));
                $fue_api = self::fue_api();
                $templates = $fue_api->get_emails();
                delete_option(self::TEMPLATE_LOCK_OPTION);
                set_transient(self::TEMPLATE_TRANSIENT, $templates, self::TEMPLATE_TRANSIENT_EXPIRY);
                error_log('_get_templates() fetched - ' . microtime(true));
            }
            error_log('_get_templates() done - ' . microtime(true));

            return $templates;
        }

Aber die Verwendung von Optionen als Sperren fühlt sich schmutzig und falsch an, und ich habe das Gefühl, dass es Raum für Fehler lässt, wenn Objekt-Caching verwendet wird (z. B. WPEngine et al.). Gibt es einen besseren/normalen Weg, damit umzugehen, oder gibt es alternativ kein wirkliches Problem mit dem oben Genannten?

Bearbeiten: Die Sperrlösung funktioniert also auch nicht zu 100% – ich habe dies am Ende mit einem WP Cron-Job gemacht – alle zehn Minuten rufen wir die Liste der Vorlagen ab, anstatt nach Bedarf, und speichern sie in einer Option. Mir gefällt diese Lösung nicht besonders gut – aber mir ist noch keine bessere eingefallen. Trotzdem interessiert, ob es eine gemeinsame Lösung für dieses Problem gibt.

  • Haben Sie versucht, WordPress zu aktualisieren? immer noch das Problem?

    – Kelvin Mariano

    31. Oktober 2019 um 8:28 Uhr

Eine der Methoden/Funktionen zwischen dem zuletzt gedruckten und dem ersten erwarteten error_log ruft Ihre Methode erneut auf. Um einen Hinweis zu erhalten, wo die Schleife/Rekursion beginnt, können Sie debug_backtrace() verwenden, um den Aufrufstapel und damit den Punkt zu erhalten, an dem Ihre Schleife/Rekursion beginnt.

Der beste Ausgangspunkt ist, den debug_backtrace direkt nach Ihrem letzten funktionierenden error_log zu platzieren.

Einige der folgenden Funktionen rufen auf _get_templates()

$fue_api = self::fue_api();
$templates = $fue_api->get_emails();
delete_option(self::TEMPLATE_LOCK_OPTION);
set_transient(self::TEMPLATE_TRANSIENT, $templates, self::TEMPLATE_TRANSIENT_EXPIRY);

1392730cookie-checkVerhindern Sie eine AJAX-Endlosschleife, wenn Sie eine eigene API verwenden

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy