[BUGFIX] PageTree: Re-introduce queueing 91/51591/8
authorAndreas Fernandez <a.fernandez@scripting-base.de>
Wed, 8 Feb 2017 17:52:35 +0000 (18:52 +0100)
committerSusanne Moog <susanne.moog@typo3.org>
Fri, 10 Feb 2017 16:20:15 +0000 (17:20 +0100)
With the removal of the ExtJS state providers, the polyfill
`TYPO3ExtJSStateProviderBridge` with a limited functional subset was
introduced. Previously, changes were queued to reduce the amount of
requests, which got lost since then. This was a complex workaround in
first place and the real issue that the same data is sent *per node*
lies somewhere deep in ExtJS and was never fixed.

As we aim to get rid of the last pieces of ExtJS sooner than later, the
queueing mechanism is added again keep the load low and to worship our
servers.

Resolves: #79693
Related: #79227
Releases: master
Change-Id: Ibcccd9be183437192027cbfab634515f710728c6
Reviewed-on: https://review.typo3.org/51591
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Thomas Hohn <thomas@hohn.dk>
Tested-by: Thomas Hohn <thomas@hohn.dk>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Mona Muzaffar <mona.muzaffar@gmx.de>
Reviewed-by: Markus Sommer <markussom@posteo.de>
Tested-by: Markus Sommer <markussom@posteo.de>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
typo3/sysext/backend/Classes/Controller/BackendController.php

index a8570b0..4960865 100644 (file)
@@ -293,10 +293,31 @@ class BackendController
         $this->pageRenderer->addJsInlineCode('BackendInlineJavascript', $this->js, false);
         $this->loadResourcesForRegisteredNavigationComponents();
         // @todo: remove this when ExtJS is removed
+        $states = $this->getBackendUser()->uc['BackendComponents']['States'];
         $this->pageRenderer->addExtOnReadyCode('
             var TYPO3ExtJSStateProviderBridge = function() {};
             Ext.extend(TYPO3ExtJSStateProviderBridge, Ext.state.Provider, {
+                state: {},
+                queue: [],
+                dirty: false,
                 prefix: "BackendComponents.States.",
+                initState: function(state) {
+                    if (Ext.isArray(state)) {
+                        Ext.each(state, function(item) {
+                            this.state[item.name] = item.value;
+                        }, this);
+                    } else if (Ext.isObject(state)) {
+                        Ext.iterate(state, function(key, value) {
+                            this.state[key] = value;
+                        }, this);
+                    } else {
+                        this.state = {};
+                    }
+                    var me = this;
+                    window.setInterval(function() {
+                        me.submitState(me)
+                    }, 750);
+                },
                 get: function(name, defaultValue) {
                     return TYPO3.Storage.Persistent.isset(this.prefix + name) ? TYPO3.Storage.Persistent.get(this.prefix + name) : defaultValue;
                 },
@@ -304,11 +325,56 @@ class BackendController
                     TYPO3.Storage.Persistent.unset(this.prefix + name);
                 },
                 set: function(name, value) {
-                    TYPO3.Storage.Persistent.set(this.prefix + name, value);
+                    if (!name) {
+                        return;
+                    }
+                    this.queueChange(name, value);
+                },
+                queueChange: function(name, value) {
+                    var o = {};
+                    var i;
+                    var found = false;
+
+                    var lastValue = this.state[name];
+                    for (i = 0; i < this.queue.length; i++) {
+                        if (this.queue[i].name === name) {
+                            lastValue = this.queue[i].value;
+                        }
+                    }
+                    var changed = undefined === lastValue || lastValue !== value;
+
+                    if (changed) {
+                        o.name = name;
+                        o.value = value;
+                        for (i = 0; i < this.queue.length; i++) {
+                            if (this.queue[i].name === o.name) {
+                                this.queue[i] = o;
+                                found = true;
+                            }
+                        }
+                        if (false === found) {
+                            this.queue.push(o);
+                        }
+                        this.dirty = true;
+                    }
+                },
+                submitState: function(context) {
+                    if (!context.dirty) {
+                        return;
+                    }
+                    for (var i = 0; i < context.queue.length; ++i) {
+                        TYPO3.Storage.Persistent.set(context.prefix + context.queue[i].name, context.queue[i].value).done(function() {
+                            if (!context.dirty) {
+                                context.queue = [];
+                            }
+                        });
+                    }
+                    context.dirty = false;
                 }
             });
             Ext.state.Manager.setProvider(new TYPO3ExtJSStateProviderBridge());
-               ');
+            Ext.state.Manager.getProvider().initState(' . (!empty($states) ? json_encode($states) : []) . ');
+            ');
         // Set document title:
         $title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . ' [TYPO3 CMS ' . TYPO3_version . ']' : 'TYPO3 CMS ' . TYPO3_version;
         // Renders the module page