88use GT \DomTemplate \PartialExpander ;
99use GT \Routing \Assembly ;
1010use GT \Routing \Path \DynamicPath ;
11+ use GT \WebEngine \View \HeaderFooterPartialConflictException ;
1112
1213class HTMLDocumentProcessor extends ViewModelProcessor {
1314 function processDynamicPath (
@@ -30,7 +31,16 @@ function processDynamicPath(
3031
3132 function processPartialContent (
3233 HTMLDocument $ model ,
34+ ?Assembly $ viewAssembly = null ,
3335 ):LogicAssemblyComponentList {
36+ if ($ viewAssembly
37+ && $ this ->containsPartialExtends ($ model )
38+ && $ this ->containsHeaderOrFooterView ($ viewAssembly )) {
39+ throw new HeaderFooterPartialConflictException (
40+ "Header/footer view files cannot be combined with partial views. "
41+ );
42+ }
43+
3444 $ componentList = new LogicAssemblyComponentList ();
3545
3646 try {
@@ -81,4 +91,54 @@ function processPartialContent(
8191
8292 return $ componentList ;
8393 }
94+
95+ private function containsHeaderOrFooterView (Assembly $ viewAssembly ):bool {
96+ foreach ($ viewAssembly as $ viewFile ) {
97+ $ fileName = pathinfo ($ viewFile , PATHINFO_FILENAME );
98+ if ($ fileName === "_header " || $ fileName === "_footer " ) {
99+ return true ;
100+ }
101+ }
102+
103+ return false ;
104+ }
105+
106+ private function containsPartialExtends (HTMLDocument $ model ):bool {
107+ return $ this ->containsPartialExtendsInNode ($ model ->documentElement );
108+ }
109+
110+ /** @return ?array<string, array<string, string>|string> */
111+ private function parseCommentIni (string $ data ):?array {
112+ set_error_handler (
113+ static fn () => true
114+ );
115+
116+ try {
117+ $ parsed = parse_ini_string ($ data , true );
118+ }
119+ finally {
120+ restore_error_handler ();
121+ }
122+
123+ return is_array ($ parsed )
124+ ? $ parsed
125+ : null ;
126+ }
127+
128+ private function containsPartialExtendsInNode (\DOMNode $ node ):bool {
129+ if ($ node ->nodeType === XML_COMMENT_NODE ) {
130+ $ parsed = $ this ->parseCommentIni (trim ($ node ->textContent ));
131+ if (isset ($ parsed ["extends " ])) {
132+ return true ;
133+ }
134+ }
135+
136+ foreach ($ node ->childNodes as $ childNode ) {
137+ if ($ this ->containsPartialExtendsInNode ($ childNode )) {
138+ return true ;
139+ }
140+ }
141+
142+ return false ;
143+ }
84144}
0 commit comments