1
1
<?php
2
2
namespace Breadlesscode \ErrorPages \ViewHelpers ;
3
3
4
- use Neos \FluidAdaptor \ Core \ ViewHelper \ AbstractViewHelper ;
4
+ use Neos \ContentRepository \ Domain \ Model \ Node ;
5
5
use Neos \ContentRepository \Domain \Service \ContextFactoryInterface ;
6
6
use Neos \Eel \FlowQuery \FlowQuery ;
7
7
use Neos \Flow \Annotations as Flow ;
8
- use Neos \Neos \ View \ FusionView ;
8
+ use Neos \FluidAdaptor \ Core \ ViewHelper \ AbstractViewHelper ;
9
9
use Neos \Neos \Routing \FrontendNodeRoutePartHandler ;
10
-
10
+ use Neos \Neos \View \FusionView ;
11
+ use Breadlesscode \ErrorPages \Utility \PathUtility ;
11
12
12
13
class PageViewHelper extends AbstractViewHelper
13
14
{
@@ -36,11 +37,16 @@ class PageViewHelper extends AbstractViewHelper
36
37
*/
37
38
public function render ($ exception )
38
39
{
39
- $ statusCode = $ exception ->getStatusCode ();
40
- $ dimension = $ this ->getCurrentDimension ();
41
- $ errorPage = $ this ->findErrorPage ($ statusCode , $ dimension );
40
+ $ requestPath = PathUtility::cutLastPart (
41
+ $ this ->controllerContext
42
+ ->getRequest ()
43
+ ->getHttpRequest ()
44
+ ->getUri ()
45
+ ->getPath ()
46
+ );
47
+ $ errorPage = $ this ->findErrorPage ($ requestPath , $ exception ->getStatusCode ());
42
48
43
- if ($ errorPage === null ) {
49
+ if ($ errorPage === null ) {
44
50
throw new \Exception ("Please setup a error page of type " .self ::ERROR_PAGE_TYPE ."! " , 1 );
45
51
}
46
52
// render error page
@@ -58,23 +64,49 @@ public function render($exception)
58
64
* @param string $dimension
59
65
* @return Neos\ContentRepository\Domain\Model\Node
60
66
*/
61
- protected function findErrorPage ($ statusCode , $ dimension )
67
+ protected function findErrorPage ($ requestPath , $ statusCode )
62
68
{
69
+ $ dimension = $ this ->getDimensionOfPath ($ requestPath );
63
70
$ errorPages = collect ($ this ->getErrorPages ($ dimension ));
64
71
$ statusCode = (string ) $ statusCode ;
65
72
// find the correct error page
66
- return $ errorPages
73
+ $ errorPages = $ errorPages
67
74
// filter invalid status codes
68
- ->filter (function ($ page ) use ($ statusCode ) {
75
+ ->filter (function ($ page ) use ($ statusCode ) {
69
76
$ supportedStatusCodes = $ page ->getProperty ('statusCodes ' );
70
-
71
77
return $ supportedStatusCodes !== null && \in_array ($ statusCode , $ supportedStatusCodes );
72
78
})
73
79
// filter invalid dimensions
74
- ->filter (function ($ page ) use ($ dimension ) {
80
+ ->filter (function ($ page ) use ($ dimension ) {
75
81
return \in_array ($ dimension , $ page ->getDimensions ()['language ' ]);
76
82
})
77
- ->first ();
83
+ // filter all pages which not in the correct path
84
+ ->sortBy (function ($ page ) use ($ requestPath , $ dimension ) {
85
+ return PathUtility::compare (
86
+ $ this ->getPathWithoutDimensionPrefix ($ requestPath ),
87
+ PathUtility::cutLastPart ($ this ->getPathWithoutDimensionPrefix ($ this ->getUriOfNode ($ page )))
88
+ );
89
+ });
90
+ return $ errorPages ->first ();
91
+ }
92
+ /**
93
+ * return path without the dimension prefix
94
+ *
95
+ * @param string $path
96
+ * @param string $dimension
97
+ * @return string
98
+ */
99
+ protected function getPathWithoutDimensionPrefix ($ path )
100
+ {
101
+ $ presets = collect ($ this ->contentDimensionsConfig ['presets ' ]);
102
+ $ matches = [];
103
+ preg_match (FrontendNodeRoutePartHandler::DIMENSION_REQUEST_PATH_MATCHER , ltrim ($ path , '/ ' ), $ matches );
104
+
105
+ if ($ presets ->pluck ('uriSegment ' )->contains ($ matches ['firstUriPart ' ])) {
106
+ return substr (ltrim ($ path , '/ ' ), strlen ($ matches ['firstUriPart ' ]));
107
+ }
108
+
109
+ return $ path ;
78
110
}
79
111
/**
80
112
* collects all error pages from the site
@@ -111,14 +143,13 @@ protected function getContext($dimension)
111
143
*
112
144
* @return string dimension preset key
113
145
*/
114
- protected function getCurrentDimension ( )
146
+ protected function getDimensionOfPath ( $ path )
115
147
{
116
148
$ matches = [];
117
- $ requestPath = ltrim ($ this ->controllerContext ->getRequest ()->getHttpRequest ()->getUri ()->getPath (), '/ ' );
118
- preg_match (FrontendNodeRoutePartHandler::DIMENSION_REQUEST_PATH_MATCHER , $ requestPath , $ matches );
149
+ preg_match (FrontendNodeRoutePartHandler::DIMENSION_REQUEST_PATH_MATCHER , ltrim ($ path , '/ ' ), $ matches );
119
150
120
151
$ presets = collect ($ this ->contentDimensionsConfig ['presets ' ])
121
- ->filter (function ($ value , $ key ) use ($ matches ) {
152
+ ->filter (function ($ value , $ key ) use ($ matches ) {
122
153
$ uriSegment = data_get ($ value , 'uriSegment ' );
123
154
return (
124
155
$ uriSegment !== null && (
@@ -128,15 +159,32 @@ protected function getCurrentDimension()
128
159
);
129
160
});
130
161
131
- if ($ presets ->count () > 0 ) {
162
+ if ($ presets ->count () > 0 ) {
132
163
return $ presets ->keys ()->first ();
133
164
}
134
165
135
- if ($ this ->supportEmptySegmentForDimensions ) {
166
+ if ($ this ->supportEmptySegmentForDimensions ) {
136
167
return $ this ->contentDimensionsConfig ['defaultPreset ' ];
137
168
}
138
169
139
170
return null ;
140
171
}
172
+ /**
173
+ * get the uri of a node
174
+ *
175
+ * @param Node $node
176
+ * @return string
177
+ */
178
+ protected function getUriOfNode (Node $ node )
179
+ {
180
+ static $ uriBuilder = null ;
141
181
182
+ if ($ uriBuilder === null ) {
183
+ $ uriBuilder = $ this ->controllerContext ->getUriBuilder ();
184
+ $ uriBuilder ->setRequest ($ this ->controllerContext ->getRequest ()->getMainRequest ());
185
+ $ uriBuilder ->reset ();
186
+ }
187
+
188
+ return $ uriBuilder ->uriFor ('show ' , ['node ' => $ node ], 'Frontend \\Node ' , 'Neos.Neos ' );
189
+ }
142
190
}
0 commit comments