@@ -382,64 +382,82 @@ public function path(string $dir): void
382382 * Processes each routes middleware.
383383 *
384384 * @param Route $route The route to process the middleware for.
385- * @param string $event_name If this is the before or after method.
385+ * @param string $eventName If this is the before or after method.
386386 */
387- protected function processMiddleware (Route $ route , string $ event_name ): bool
387+ protected function processMiddleware (Route $ route , string $ eventName ): bool
388388 {
389- $ at_least_one_middleware_failed = false ;
389+ $ atLeastOneMiddlewareFailed = false ;
390390
391- $ middlewares = $ event_name === Dispatcher::FILTER_BEFORE ? $ route ->middleware : array_reverse ($ route ->middleware );
391+ // Process things normally for before, and then in reverse order for after.
392+ $ middlewares = $ eventName === Dispatcher::FILTER_BEFORE
393+ ? $ route ->middleware
394+ : array_reverse ($ route ->middleware );
392395 $ params = $ route ->params ;
393396
394397 foreach ($ middlewares as $ middleware ) {
395- $ middleware_object = false ;
396-
397- if ($ event_name === Dispatcher::FILTER_BEFORE ) {
398- // can be a callable or a class
399- $ middleware_object = (is_callable ($ middleware ) === true
400- ? $ middleware
401- : (method_exists ($ middleware , Dispatcher::FILTER_BEFORE ) === true
402- ? [$ middleware , Dispatcher::FILTER_BEFORE ]
403- : false
404- )
405- );
406- } elseif ($ event_name === Dispatcher::FILTER_AFTER ) {
407- // must be an object. No functions allowed here
408- if (
409- is_object ($ middleware ) === true
410- && !($ middleware instanceof Closure)
411- && method_exists ($ middleware , Dispatcher::FILTER_AFTER ) === true
412- ) {
413- $ middleware_object = [$ middleware , Dispatcher::FILTER_AFTER ];
398+
399+ // Assume that nothing is going to be executed for the middleware.
400+ $ middlewareObject = false ;
401+
402+ // Closure functions can only run on the before event
403+ if ($ eventName === Dispatcher::FILTER_BEFORE && is_object ($ middleware ) === true && ($ middleware instanceof Closure)) {
404+ $ middlewareObject = $ middleware ;
405+
406+ // If the object has already been created, we can just use it if the event name exists.
407+ } elseif (is_object ($ middleware ) === true ) {
408+ $ middlewareObject = method_exists ($ middleware , $ eventName ) === true ? [ $ middleware , $ eventName ] : false ;
409+
410+ // If the middleware is a string, we need to create the object and then call the event.
411+ } elseif (is_string ($ middleware ) === true && method_exists ($ middleware , $ eventName ) === true ) {
412+ $ resolvedClass = null ;
413+
414+ // if there's a container assigned, we should use it to create the object
415+ if ($ this ->dispatcher ->mustUseContainer ($ middleware ) === true ) {
416+ $ resolvedClass = $ this ->dispatcher ->resolveContainerClass ($ middleware , $ params );
417+ // otherwise just assume it's a plain jane class, so inject the engine
418+ // just like in Dispatcher::invokeCallable()
419+ } elseif (class_exists ($ middleware ) === true ) {
420+ $ resolvedClass = new $ middleware ($ this );
421+ }
422+
423+ // If something was resolved, create an array callable that will be passed in later.
424+ if ($ resolvedClass !== null ) {
425+ $ middlewareObject = [ $ resolvedClass , $ eventName ];
414426 }
415427 }
416428
417- if ($ middleware_object === false ) {
429+ // If nothing was resolved, go to the next thing
430+ if ($ middlewareObject === false ) {
418431 continue ;
419432 }
420433
421- $ use_v3_output_buffering =
434+ // This is the way that v3 handles output buffering (which captures output correctly)
435+ $ useV3OutputBuffering =
422436 $ this ->response ()->v2_output_buffering === false &&
423437 $ route ->is_streamed === false ;
424438
425- if ($ use_v3_output_buffering === true ) {
439+ if ($ useV3OutputBuffering === true ) {
426440 ob_start ();
427441 }
428442
429- // It's assumed if you don't declare before, that it will be assumed as the before method
430- $ middleware_result = $ middleware_object ($ params );
443+ // Here is the array callable $middlewareObject that we created earlier.
444+ // It looks bizarre but it's really calling [ $class, $method ]($params)
445+ // Which loosely translates to $class->$method($params)
446+ $ middlewareResult = $ middlewareObject ($ params );
431447
432- if ($ use_v3_output_buffering === true ) {
448+ if ($ useV3OutputBuffering === true ) {
433449 $ this ->response ()->write (ob_get_clean ());
434450 }
435451
436- if ($ middleware_result === false ) {
437- $ at_least_one_middleware_failed = true ;
452+ // If you return false in your middleware, it will halt the request
453+ // and throw a 403 forbidden error by default.
454+ if ($ middlewareResult === false ) {
455+ $ atLeastOneMiddlewareFailed = true ;
438456 break ;
439457 }
440458 }
441459
442- return $ at_least_one_middleware_failed ;
460+ return $ atLeastOneMiddlewareFailed ;
443461 }
444462
445463 ////////////////////////
@@ -475,7 +493,7 @@ public function _start(): void
475493 }
476494
477495 // Route the request
478- $ failed_middleware_check = false ;
496+ $ failedMiddlewareCheck = false ;
479497
480498 while ($ route = $ router ->route ($ request )) {
481499 $ params = array_values ($ route ->params );
@@ -506,18 +524,18 @@ public function _start(): void
506524
507525 // Run any before middlewares
508526 if (count ($ route ->middleware ) > 0 ) {
509- $ at_least_one_middleware_failed = $ this ->processMiddleware ($ route , 'before ' );
510- if ($ at_least_one_middleware_failed === true ) {
511- $ failed_middleware_check = true ;
527+ $ atLeastOneMiddlewareFailed = $ this ->processMiddleware ($ route , 'before ' );
528+ if ($ atLeastOneMiddlewareFailed === true ) {
529+ $ failedMiddlewareCheck = true ;
512530 break ;
513531 }
514532 }
515533
516- $ use_v3_output_buffering =
534+ $ useV3OutputBuffering =
517535 $ this ->response ()->v2_output_buffering === false &&
518536 $ route ->is_streamed === false ;
519537
520- if ($ use_v3_output_buffering === true ) {
538+ if ($ useV3OutputBuffering === true ) {
521539 ob_start ();
522540 }
523541
@@ -527,17 +545,17 @@ public function _start(): void
527545 $ params
528546 );
529547
530- if ($ use_v3_output_buffering === true ) {
548+ if ($ useV3OutputBuffering === true ) {
531549 $ response ->write (ob_get_clean ());
532550 }
533551
534552 // Run any before middlewares
535553 if (count ($ route ->middleware ) > 0 ) {
536554 // process the middleware in reverse order now
537- $ at_least_one_middleware_failed = $ this ->processMiddleware ($ route , 'after ' );
555+ $ atLeastOneMiddlewareFailed = $ this ->processMiddleware ($ route , 'after ' );
538556
539- if ($ at_least_one_middleware_failed === true ) {
540- $ failed_middleware_check = true ;
557+ if ($ atLeastOneMiddlewareFailed === true ) {
558+ $ failedMiddlewareCheck = true ;
541559 break ;
542560 }
543561 }
@@ -558,7 +576,7 @@ public function _start(): void
558576 $ response ->clearBody ();
559577 }
560578
561- if ($ failed_middleware_check === true ) {
579+ if ($ failedMiddlewareCheck === true ) {
562580 $ this ->halt (403 , 'Forbidden ' , empty (getenv ('PHPUNIT_TEST ' )));
563581 } elseif ($ dispatched === false ) {
564582 $ this ->notFound ();
0 commit comments