@@ -50,6 +50,8 @@ class AssetService implements SingletonInterface
5050
5151 protected static bool $ typoScriptAssetsBuilt = false ;
5252 protected static ?array $ typoScriptCache = null ;
53+ protected static array $ pagesWithSavedTypoScript = [];
54+ protected static bool $ currentlyBuildingCacheable = true ;
5355 protected static array $ cachedDependencies = [];
5456 protected static bool $ cacheCleared = false ;
5557
@@ -71,51 +73,59 @@ public function usePageCache(object $caller, bool $shouldUsePageCache): bool
7173
7274 public function buildAll (array $ parameters , object $ caller , bool $ cached = true , ?string &$ content = null ): void
7375 {
74- if ($ content === null ) {
75- $ content = &$ caller ->content ;
76+ $ wasBuildingCacheableBefore = static ::$ currentlyBuildingCacheable ;
77+ if ($ caller instanceof TypoScriptFrontendController && $ caller ->isINTincScript ()) {
78+ static ::$ currentlyBuildingCacheable = false ;
7679 }
80+ try {
81+ if ($ content === null ) {
82+ $ content = &$ caller ->content ;
83+ }
7784
78- $ settings = $ this ->getSettings ();
79- $ buildTypoScriptAssets = (
80- !static ::$ typoScriptAssetsBuilt
81- && ($ cached || $ this ->readCacheDisabledInstructionFromContext ())
82- );
83- if ($ buildTypoScriptAssets && isset ($ settings ['asset ' ]) && is_array ($ settings ['asset ' ])) {
84- foreach ($ settings ['asset ' ] as $ name => $ typoScriptAsset ) {
85- if (!isset ($ GLOBALS ['VhsAssets ' ][$ name ]) && is_array ($ typoScriptAsset )) {
86- if (!isset ($ typoScriptAsset ['name ' ])) {
87- $ typoScriptAsset ['name ' ] = $ name ;
88- }
89- if (isset ($ typoScriptAsset ['dependencies ' ]) && !is_array ($ typoScriptAsset ['dependencies ' ])) {
90- $ typoScriptAsset ['dependencies ' ] = GeneralUtility::trimExplode (
91- ', ' ,
92- (string ) $ typoScriptAsset ['dependencies ' ],
93- true
94- );
85+ $ settings = $ this ->getSettings ();
86+ $ buildTypoScriptAssets = (
87+ !static ::$ typoScriptAssetsBuilt
88+ && ($ cached || $ this ->readCacheDisabledInstructionFromContext ())
89+ );
90+ if ($ buildTypoScriptAssets && isset ($ settings ['asset ' ]) && is_array ($ settings ['asset ' ])) {
91+ foreach ($ settings ['asset ' ] as $ name => $ typoScriptAsset ) {
92+ if (!isset ($ GLOBALS ['VhsAssets ' ][$ name ]) && is_array ($ typoScriptAsset )) {
93+ if (!isset ($ typoScriptAsset ['name ' ])) {
94+ $ typoScriptAsset ['name ' ] = $ name ;
95+ }
96+ if (isset ($ typoScriptAsset ['dependencies ' ]) && !is_array ($ typoScriptAsset ['dependencies ' ])) {
97+ $ typoScriptAsset ['dependencies ' ] = GeneralUtility::trimExplode (
98+ ', ' ,
99+ (string ) $ typoScriptAsset ['dependencies ' ],
100+ true
101+ );
102+ }
103+ Asset::createFromSettings ($ typoScriptAsset );
95104 }
96- Asset::createFromSettings ($ typoScriptAsset );
97105 }
106+ static ::$ typoScriptAssetsBuilt = true ;
98107 }
99- static ::$ typoScriptAssetsBuilt = true ;
100- }
101- if (empty ($ GLOBALS ['VhsAssets ' ]) || !is_array ($ GLOBALS ['VhsAssets ' ])) {
102- return ;
103- }
104- $ assets = $ GLOBALS ['VhsAssets ' ];
105- $ assets = $ this ->sortAssetsByDependency ($ assets );
106- $ assets = $ this ->manipulateAssetsByTypoScriptSettings ($ assets );
107- $ buildDebugRequested = (isset ($ settings ['asset ' ]['debugBuild ' ]) && $ settings ['asset ' ]['debugBuild ' ] > 0 );
108- $ assetDebugRequested = (isset ($ settings ['asset ' ]['debug ' ]) && $ settings ['asset ' ]['debug ' ] > 0 );
109- $ useDebugUtility = (isset ($ settings ['asset ' ]['useDebugUtility ' ]) && $ settings ['asset ' ]['useDebugUtility ' ] > 0 )
110- || !isset ($ settings ['asset ' ]['useDebugUtility ' ]);
111- if ($ buildDebugRequested || $ assetDebugRequested ) {
112- if ($ useDebugUtility ) {
113- DebuggerUtility::var_dump ($ assets );
114- } else {
115- echo var_export ($ assets , true );
108+ if (empty ($ GLOBALS ['VhsAssets ' ]) || !is_array ($ GLOBALS ['VhsAssets ' ])) {
109+ return ;
110+ }
111+ $ assets = $ GLOBALS ['VhsAssets ' ];
112+ $ assets = $ this ->sortAssetsByDependency ($ assets );
113+ $ assets = $ this ->manipulateAssetsByTypoScriptSettings ($ assets );
114+ $ buildDebugRequested = (isset ($ settings ['asset ' ]['debugBuild ' ]) && $ settings ['asset ' ]['debugBuild ' ] > 0 );
115+ $ assetDebugRequested = (isset ($ settings ['asset ' ]['debug ' ]) && $ settings ['asset ' ]['debug ' ] > 0 );
116+ $ useDebugUtility = (isset ($ settings ['asset ' ]['useDebugUtility ' ]) && $ settings ['asset ' ]['useDebugUtility ' ] > 0 )
117+ || !isset ($ settings ['asset ' ]['useDebugUtility ' ]);
118+ if ($ buildDebugRequested || $ assetDebugRequested ) {
119+ if ($ useDebugUtility ) {
120+ DebuggerUtility::var_dump ($ assets );
121+ } else {
122+ echo var_export ($ assets , true );
123+ }
116124 }
125+ $ this ->placeAssetsInHeaderAndFooter ($ assets , $ cached , $ content );
126+ } finally {
127+ static ::$ currentlyBuildingCacheable = $ wasBuildingCacheableBefore ;
117128 }
118- $ this ->placeAssetsInHeaderAndFooter ($ assets , $ cached , $ content );
119129 }
120130
121131 public function buildAllUncached (array $ parameters , object $ caller , ?string &$ content = null ): void
@@ -151,26 +161,27 @@ public function getSettings(): array
151161 protected function getTypoScript (): array
152162 {
153163 if (static ::$ typoScriptCache !== null ) {
164+ $ this ->saveTypoScriptIfNecessary (static ::$ typoScriptCache );
154165 return static ::$ typoScriptCache ;
155166 }
156167
157- $ cache = $ this ->cacheManager ->getCache ('vhs_main ' );
158- $ pageUid = $ this ->readPageUidFromContext ();
159- $ cacheId = 'vhs_asset_ts_ ' . $ pageUid ;
160- $ cacheTag = 'pageId_ ' . $ pageUid ;
161-
162168 try {
163169 $ allTypoScript = $ this ->configurationManager ->getConfiguration (
164170 ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
165171 );
166172 $ typoScript = GeneralUtility::removeDotsFromTS ($ allTypoScript ['plugin. ' ]['tx_vhs. ' ] ?? []);
167- $ cache -> set ( $ cacheId , $ typoScript, [ $ cacheTag ] );
173+ $ this -> saveTypoScriptIfNecessary ( $ typoScript );
168174 } catch (\RuntimeException $ exception ) {
169175 if ($ exception ->getCode () !== 1666513645 ) {
170176 // Re-throw, but only if the exception is not the specific "Setup array has not been initialized" one.
171177 throw $ exception ;
172178 }
173179
180+ $ pageUid = $ this ->readPageUidFromContext ();
181+ $ cache = $ this ->cacheManager ->getCache ('vhs_main ' );
182+ $ cacheId = 'vhs_asset_ts_ ' . $ pageUid ;
183+ $ cacheTag = 'pageId_ ' . $ pageUid ;
184+
174185 // Note: this case will only ever be entered on TYPO3v13 and above. Earlier versions will consistently
175186 // produce the necessary TS array from ConfigurationManager - and will not raise the specified exception.
176187
@@ -196,6 +207,34 @@ protected function getTypoScript(): array
196207 return $ typoScript ;
197208 }
198209
210+ /**
211+ * Save page TypoScript if required to prevent the
212+ * "Setup array has not been initialized" error when serving the next
213+ * request from cache.
214+ */
215+ private function saveTypoScriptIfNecessary (array $ typoScript ): void
216+ {
217+ // We don't need to save the TypoScript if we're rendering uncached
218+ // content, because the next request won't be answered from cache as no
219+ // cache entry will be created.
220+ if (!static ::$ currentlyBuildingCacheable ) {
221+ return ;
222+ }
223+
224+ $ pageUid = $ this ->readPageUidFromContext ();
225+
226+ // We don't need to save the TypoScript if we already did.
227+ if (in_array ($ pageUid , static ::$ pagesWithSavedTypoScript , true )) {
228+ return ;
229+ }
230+
231+ $ cache = $ this ->cacheManager ->getCache ('vhs_main ' );
232+ $ cacheId = 'vhs_asset_ts_ ' . $ pageUid ;
233+ $ cacheTag = 'pageId_ ' . $ pageUid ;
234+ $ cache ->set ($ cacheId , $ typoScript , [$ cacheTag ]);
235+ static ::$ pagesWithSavedTypoScript [] = $ pageUid ;
236+ }
237+
199238 /**
200239 * @param AssetInterface[]|array[] $assets
201240 */
0 commit comments