15

Returning an HTTP error

Create site9 by copying site8.

  1. /cms
    1. ...
    2. site8
    3. site9

In this chapter, we are going to program HTTP error responses.

To test the result online, enter http://www.frasq.org/cms/site9 in the address bar of your navigator. Try an invalid URL in English and another one in French to display the error pages Not Found and Non trouvé.

Create the folder error in the folder actions then the file notfound.php in the folder actions/error with the following content:

  1. /cms/site9
    1. actions
      1. error
        1. notfound.php
  1. function notfound($lang) {
  2.     head('title', translate('http_not_found:title', $lang));
  3.     head('robots', 'noindex, nofollow');
  4.  
  5.     $contact=true;
  6.     $banner = build('banner', $lang, compact('contact'));
  7.  
  8.     $contact_page=url('contact', $lang);
  9.     $content = view('error/notfound', $lang, compact('contact_page'));
  10.  
  11.     $output = layout('standard', compact('banner', 'content'));
  12.  
  13.     header('HTTP/1.1 404 Not Found');
  14.  
  15.     return $output;
  16. }

The action notfound returns the error HTTP/1.1 404 Not Found followed by a document which displays an error message with a link to the contact page.

Add the title of the page to the file includes/strings.inc.

In English in the array 'en':

  1.         'http_not_found:title'              => 'Not Found',

In French in the array 'fr':

  1.         'http_not_found:title'              => 'Non trouvé',

Create a folder error in the folders views/en and views/fr. Add the view of the error page in the folders views/en/error for the English version and views/fr/error for the version in French.

  1. /cms/site9
    1. views
      1. en
        1. error
          1. notfound.phtml
      2. fr
        1. error
          1. notfound.phtml
  1. <h3>URL not found</h3>
  2. <p>The requested URL was not found on this server.
  3. If you entered the URL manually please check your input and try again.
  4. If you think this is a server error, please <a href="<?php echo $contact_page; ?>">contact us</a>.</p>
  1. <h3>URL non trouvée</h3>
  2. <p>L'URL demandée n'a pas été trouvée sur ce serveur.
  3. Si vous avez tapé l'URL à la main, veuillez vérifier la saisie et réessayer.
  4. Si vous pensez qu'il s'agit d'une erreur du serveur, merci de <a href="<?php echo $contact_page; ?>">nous contacter</a>.</p>

To capture addressing errors, modify the line in the dispatch function in the file library/engine.php which directly returns an HTTP/1.0 404 Not Found document:

  1.     $action=$args=false;
  2.     $r = route($path, $lang);
  3.     if (!$r) {
  4.         $action='error/notfound';
  5.     }

If a path cannot be routed, $action is set to error/notfound.

Enter http://localhost/cms/site9/en/nowhere then http://localhost/cms/site9/fr/nullepart in the address bar of your navigator to test the error page in English and in French.

To return an HTTP error if the file with the code for an action is missing, modify the run function in the file library/engine.php:

  1.     $file = ACTIONS_DIR.DIRECTORY_SEPARATOR.$action.'.php';
  2.     if (!is_file($file)) {
  3.         $action = 'error/internalerror';
  4.         $file = ACTIONS_DIR.DIRECTORY_SEPARATOR.$action.'.php';
  5.         $args = false;
  6.     }
  7.     require_once $file;

Add the file internalerror.php in the folder actions/error with the following content:

  1. function internalerror($lang) {
  2.     head('title', translate('http_internal_error:title', $lang));
  3.     head('robots', 'noindex, nofollow');
  4.  
  5.     $contact=true;
  6.     $banner = build('banner', $lang, compact('contact'));
  7.  
  8.     $contact_page=url('contact', $lang);
  9.     $content = view('error/internalerror', $lang, compact('contact_page'));
  10.  
  11.     $output = layout('standard', compact('header', 'banner', 'content'));
  12.  
  13.     header('HTTP/1.1 500 Internal Error');
  14.  
  15.     return $output;
  16. }

Add the title of the page in the file includes/strings.inc, in English and in French:

  1.         'http_internal_error:title'         => 'Internal Error',
  1.         'http_internal_error:title'         => 'Erreur interne',

Add the views internalerror.phtml in English and in French in the folders views/en/error and views/fr/error:

  1. <h3>Internal error</h3>
  2. <p>The server encountered an internal error and was unable to complete your request.
  3. If you can describe the problem, please <a href="<?php echo $contact_page; ?>">contact us</a>.</p>
  1. <h3>Erreur interne</h3>
  2. <p>Le serveur a rencontré une erreur interne et n'a pas pu faire aboutir votre requête.
  3. Si vous pouvez décrire le problème, merci de <a href="<?php echo $contact_page; ?>">nous contacter</a>.</p>

Lock the access to the site during a maintenance period, add the global parameters $closing_time and $opening_time in the configuration file includes/config.inc:

  1. global $closing_time, $opening_time;
  2.  
  3. $closing_time=0;    // mktime(13, 0);
  4. $opening_time=0;    // $closing_time+30*60;

$closing_time gives the closing time of the service. $opening_time can indicate when the service will be available again. Use the PHP function mktime to set $closing_time. Add a number of second to $closing_time to adjust $opening_time or leave this parameter at 0 if how long the interruption will be is indeterminate.

Modify the function dispatch in the file library/engine.php to take the maintenance mode into account:

  1.     global $closing_time, $opening_time;

Gives access to the global parameters $closing_time and $opening_time.

  1.     $action=$args=false;
  2.     if ($closing_time and $closing_time <= time()) {
  3.         $action='error/serviceunavailable';
  4.         $args=array($closing_time, $opening_time);
  5.     }
  6.     else {
  7.         $r = route($path, $lang);
  8.         if (!$r) {
  9.             $action='error/notfound';
  10.         }
  11.         else {
  12.             list($action, $args) = $r;
  13.         }
  14.     }

Triggers the action error/serviceunavailable with the parameters $closing_time and $opening_time if $closing_time is later than the current time. Notice that $opening_time isn't evaluated.

Add the file serviceunavailable.php in the folder actions/error with the following content:

  1. function serviceunavailable($lang, $closing_time=false, $opening_time=false) {
  2.     head('title', translate('http_service_unavailable:title', $lang));
  3.     head('robots', 'noindex, nofollow');
  4.  
  5.     $contact=true;
  6.     $banner = build('banner', $lang, compact('contact'));
  7.  
  8.     $content = view('error/serviceunavailable', $lang, compact('closing_time', 'opening_time'));
  9.  
  10.     $output = layout('standard', compact('header', 'banner', 'content'));
  11.  
  12.     header('HTTP/1.1 503 Service Unavailable');
  13.  
  14.     return $output;
  15. }

serviceunavailable passes the parameters $closing_time and $opening_time to the view.

Add the title of the page in the file includes/strings.inc, in English and in French:

  1.         'http_service_unavailable:title'    => 'Service unavailable',
  1.         'http_service_unavailable:title'    => 'Service indisponible',

Add the views serviceunavailable.phtml in English and in French in the folders views/en/error and views/fr/error:

  1. <?php
  2.  
  3. /**
  4. *
  5. * @copyright  2010 frasq.org
  6. * @version    1
  7. * @link       http://www.frasq.org
  8. */
  9. ?>
  10. <h3>Service unavailable</h3>
  11. <p>The site is under maintenance<?php if (isset($closing_time) and $closing_time): ?> since <?php echo date('H\hi', $closing_time); ?><?php if (isset($opening_time) and $opening_time): ?>. Back to normal scheduled at <b><?php echo date('H\hi', $opening_time); ?></b><?php endif; ?><?php endif; ?>.
  12. Please accept our apologizes for any inconvenience caused during renovations.
  13. Thank you for trying again later.</p>
  1. <h3>Service indisponible</h3>
  2. <p>Le site est en maintenance<?php if (isset($closing_time) and $closing_time): ?> depuis <?php echo date('H\hi', $closing_time); ?><?php if (isset($opening_time) and $opening_time): ?>. Retour à la normale prévu à <b><?php echo date('H\hi', $opening_time); ?></b><?php endif; ?><?php endif; ?>.
  3. Veuillez nous excuser pour les désagréments causés par les travaux.
  4. Merci de réessayer plus tard.</p>

Set $closing_time in includes/config.inc to a time in the past and $opening_time to a time in the future. Enter http://localhost/cms/site9/en then http://localhost/cms/site9/fr in the address bar of your navigator to test the locking of the site in English and in French. Try with $opening_time at 0. Reset $closing_time to 0 to unlock the site.

One last effort to install a specific page for the other HTTP error codes that the site could be led to return.

Copy all the following files in the folder actions/error:

  1.     $content = view('error/badrequest', $lang, compact('contact_page'));
  2.  
  3.     $output = layout('standard', compact('header', 'banner', 'content'));
  4.  
  5.     header('HTTP/1.1 400 Bad Request');
  1.     $content = view('error/unauthorized', $lang, compact('contact_page'));
  2.  
  3.     $output = layout('standard', compact('header', 'banner', 'content'));
  4.  
  5.     header('HTTP/1.1 401 Unauthorized');
  1.     $content = view('error/forbidden', $lang, compact('contact_page'));
  2.  
  3.     $output = layout('standard', compact('header', 'banner', 'content'));
  4.  
  5.     header('HTTP/1.1 403 Forbidden');
  1.     $content = view('error/notimplemented', $lang, compact('contact_page'));
  2.  
  3.     $output = layout('standard', compact('header', 'banner', 'content'));
  4.  
  5.     header('HTTP/1.1 501 Not Implemented');

Define the titles of the pages in includes/strings.inc, in English and in French:

  1.         'http_bad_request:title'            => 'Bad Request',
  2.         'http_unauthorized:title'           => 'Unauthorized',
  3.         'http_forbidden:title'              => 'Forbidden',
  4.         'http_not_found:title'              => 'Not Found',
  5.         'http_internal_error:title'         => 'Internal Error',
  6.         'http_not_implemented:title'        => 'No Implemented;',              
  7.         'http_service_unavailable:title'    => 'Service unavailable',
  1.         'http_bad_request:title'            => 'Mauvaise requête',
  2.         'http_unauthorized:title'           => 'Non autorisé',
  3.         'http_forbidden:title'              => 'Interdit',
  4.         'http_not_found:title'              => 'Non trouvé',
  5.         'http_internal_error:title'         => 'Erreur interne',
  6.         'http_not_implemented:title'        => 'Non implémenté',
  7.         'http_service_unavailable:title'    => 'Service indisponible',

Copy all the following views in views/en/error for the English versions and in views/fr/error for the versions in French:

  1. <h3>Bad request</h3>
  2. <p>The service has received a malformed or incomplete request which could not be interpreted.
  3. If you think this is a server error, please <a href="<?php echo $contact_page; ?>">contact us</a>.</p>
  1. <h3>Requête erronée</h3>
  2. <p>Le service a reçu une requête mal formulée ou incomplète qui n'a pas pu être interprétée.
  3. Si vous pensez qu'il s'agit d'une erreur du serveur, merci de <a href="<?php echo $contact_page; ?>">nous contacter</a>.</p>
  1. <h3>Authentication required</h3>
  2. <p>This server could not verify that you are authorized to access the requested object.
  3. If you think this is a server error, please <a href="<?php echo $contact_page; ?>">contact us</a>.</p>
  1. <h3>Autorisation requise</h3>
  2. <p>Ce serveur n'a pas été en mesure de vérifier que vous avez l'autorisation d'accéder à l'objet demandé.
  3. Si vous pensez qu'il s'agit d'une erreur du serveur, merci de <a href="<?php echo $contact_page; ?>">nous contacter</a>.</p>
  1. <h3>Access forbidden</h3>
  2. <p>You don't have permission to access the requested object.
  3. If you think this is a server error, please <a href="<?php echo $contact_page; ?>">contact us</a>.</p>
  1. <h3>Accès interdit</h3>
  2. <p>Vous n'avez pas le droit d'accéder à l'objet demandé.
  3. Si vous pensez qu'il s'agit d'une erreur du serveur, merci de <a href="<?php echo $contact_page; ?>">nous contacter</a>.</p>
  1. <h3>Action not implemented</h3>
  2. <p>The service is not able to run the requested action.
  3. If you think this is a server error, please <a href="<?php echo $contact_page; ?>">contact us</a>.</p>
  1. <h3>Action non implémentée</h3>
  2. <p>Le service n'est pas en mesure d'effectuer l'action demandée.
  3. Si vous pensez qu'il s'agit d'une erreur du serveur, merci de <a href="<?php echo $contact_page; ?>">nous contacter</a>.</p>

Comments

To add a comment, click here.