Spoova 2.6 Shutter
Route shutters have now been improved for better rendering and page control. The new added features are discussed below.
Header Restrictions
Header restrictions are important in situation where we need to prevent certain response codes from having access to a particular list of routes or to allow only a particular set of response header codes. There are two methods that make this achievable. These are the acceptHeaders() and rejectHeaders() method that enforces a certain type of header restriction on route shutters. The code below is an example of how to ensure that a route only accepts specified response headers.
  <?php

  namespace \spoova\mi\windows\Routes;

  use Window;

  class Home extends Window {

     function __construct(){
         
        self::acceptHeaders([200, 202]); //accept only specified headers

        self::call($this, [ 'home' => 'home' ]);

     }

     function home() {

         //This method is available under permitted response headers.

     }

  }
                                            
In the sample above, the headers accepted are only the 200 and the 204 response codes. If any other response code is detected, this will force the shutter to terminate leading to a default 404 error page. Similary, we can also tell the shutter to reject some response header codes as shown below.
  <?php

  namespace \spoova\mi\windows\Routes;

  use Window;

  class Home extends Window {

     function __construct(){
         
        self::rejectHeaders([401, 405, 406]); //reject only specified headers

        self::call($this, [ 'home' => 'home' ]);

     }

     function home() {

         //This method is available under permitted response headers.

     }

  }
                                            

Transmuting Header Codes To Template
The transmutation of header codes is the process in which response header codes are converted to template files which may be more useful in helping to pass a better response message to web users whenever an error occur. The code below is an example of how to transmute header codes to template files using headers.
  <?php

  use Window;

  class Home extends Window {

     function __construct(){
         
        //$paid is some value available only when a payment is made

        if(!$paid) {
            response(401, 'This page requires payment to be viewed');
        }

        self::transmute([401 => '401-template']);

        self::call($this, [ 'home' => 'home' ]);

     }

     function home() {

         //This method is available after payment.
        self::load('home', fn() => compile());

     }

  }
                                        
In the sample above, when a user has not paid for an item, a response code of 401 is sent to the header. This response will force the self::call() to shutdown. However, since an earlier directive has been forwarded through self::transmute() method to render a 401 response with a different template file named 401-template the call() method will shutdown using the specified template file while also returning the response header. This makes it easier to handle response messages easily as it can be used for multiple response codes.

Shutter Shutdown Controller
The shutter methods have now been assigned a new shutdown controller argument. Once this argument is defined, it allows shutter methods to be able to register a shutdown function that is called shortly before a route shuts down. The example below is a sample of how shutdowns can be applied.
  <?php

  use Window;

  class Home extends Window {

     function __construct(){
         
        //$paid is some value available only when a payment is made

        if(!$paid) {
            response(401, 'This page requires payment to be viewed');
        }

        self::call($this, 
            [ 
                window(':')    => 'home', // route: home
                window(':pro') => 'paid', // route: home/pro

                SELF::ONCALL => function() {

                    if(invoked(window(':pro'))) {

                        self::rejectHeaders([401]);

                    }

                }

                SELF::ONSHUT => function() {

                    if(invoked(window(':pro'))) {

                        // on shutdown, transmute 401 response to custom template file.
                        self::transmute([401 => '401-template']);

                    }

                }
                
            ]
            
        );

     }

     public function home() {

         //This route method is available when visited.

     }

     public function paid() {

         //This route method is available only after payment.

     }

  }
                                        
In the sample above, both the home and the home/pro is sent a response of 401 if a payment is not yet made. However as in the case of home/pro, when it is visited, the SELF::ONCALL() function is triggered. However, since this function has restricted the 401 response code, rather than the page should continue, instead, it will trigger the SELF::ONSHUT method if it exists. The SELF::ONSHUT will head on to display the 401-template for the specified 401 code. It is important to note that SELF::ONSHUT is always triggered event for urls that may not exist under this window which is why the invoked() condition was applied.
Shutter Polyfills
The shutter polyfills are used to resolve reserved Window methods. By default, when a reserved method is called using window shutters, this will trigger an error. This new update ensures that such methods will only return a 404 error response page. However, these methods can be handled by using the polyfill() method as shown below:
  <?php

  use Window;

  class Home extends Window {

     function __construct(){
         
        //$paid is some value available only when a payment is made

        if(!$paid) {
            response(401, 'This page requires payment to be viewed');
        }

        self::call($this, 
            [ 
                window(':')    => 'home', // route: home
                window(':api') => 'integrateAPI', // route: home/pro

            ]
            
        );

     }

     public function home() {

         //This route method is available when visited.

     }

     public function polyfill() : array {

        return [
            
            'integrateAPI' => function() {
                //do something ...
            }

        ];

     }

  }
                                        
In the sample above, the integrateAPI() method is a reserved method. When it is triggered, the shutter will return a 404 error page. However, to prevent this from happening, we can either use a another method which is the best approach or we can use a polyfill just as shown above. Once major thing to note is that polyfills do not support automatic dependency injection which means that the arguments needs to be explicitly defined.