File indexing completed on 2024-12-15 03:29:16

0001 <?php
0002 
0003 // This script is intended to handle requests for files that do not exist
0004 // This may occur because:
0005 // 1) It is a language-free URL and we need to send the user to the most language appropriate version for them
0006 // 2) The page has moved elsewhere and we need to send them to the appropriate page
0007 // 3) The request is for a legacy page that existed on the older Mediawiki based setup, in which case we need to once again send them to the most appropriate page
0008 //
0009 // SPDX-License-Identifier: MIT
0010 
0011 // NOTE: enable supported languages.
0012 //       English is always enabled. Respect alphabetic order.
0013 //       Other languages must be listed in locale/ sub-directory from root directory of this git repository.
0014 //       All changes from this list must be also applied to the docs-digikam-org section from the JSON config file in binary-factory-tooling repository
0015 //       https://invent.kde.org/sysadmin/binary-factory-tooling/-/blob/master/staticweb/custom-jobs.json
0016 //       all_langs list in ressources/static/js/version_switch.js file from this repository needs to be also updated.
0017 
0018 $supported_languages = array(
0019     "ca",
0020     "cs",
0021     "da",
0022     "de",
0023     "en",
0024     "es",
0025     "et",
0026     "fi",
0027     "fr",
0028     "it",
0029     "ja",
0030     "ko",
0031     "lt",
0032     "nl",
0033     "sk",
0034     "sl",
0035     "sv",
0036     "ru",
0037     "tr",
0038     "pl",
0039     "pt_BR",
0040     "pt_PT",
0041     "uk_UA",
0042     "zh_CN",
0043     "zh_TW"
0044 );
0045 
0046 // List of page redirect rules
0047 // These should always be free of the language code, as this will be automatically added on when formulating the URL to forward the user on to
0048 $redirect_rules = array(
0049     // Default front page
0050     "^$" => "index.html"
0051 );
0052 
0053 //// SETTINGS END
0054 //// CHANGES SHOULD NOT BE NEEDED TO THE BELOW
0055 
0056 // Helper function to determine the most appropriate language for the user
0057 // Parameters:
0058 // $request              The web path that the user is trying to reach
0059 // $browser_languages    The languages accepted by the user browser, in Accept-Language format
0060 // $supported_languages  Array of languages that we support - in ISO language code format
0061 function determine_appropriate_language( $request, $browser_languages, $supported_languages )
0062 {
0063     // First we start by looking at the request we have received
0064     // If this contains a language code, then we should be using that as the user has chosen to use that language explicitly
0065     // We assume that this language is supported
0066     if( preg_match( '/^([a-z][a-z](_[A-Z][A-Z])?)\//', $request, $result ) ) {
0067         // Then the user has specified a language - let's use that!
0068         return $result[1];
0069     }
0070 
0071     // Now that we know that the URL has not specified a language we can move on to looking at Accept-Language
0072     // First split the list up by the language separator
0073     $browser_requested_languages = explode( ",", $browser_languages );
0074 
0075     // Now go through each browser requested language in turn
0076     foreach( $browser_requested_languages as $language ) {
0077         // First as this might have a weighting value on it, we need to rip that off
0078         // Safest way to do this is just to split again by the appropriate separator for that
0079         $components = explode(";", $language);
0080         $language = $components[0];
0081 
0082         if( preg_match( '/^zh(-han[ts])?(-[a-z]{2})?$/i', $language, $result, PREG_UNMATCHED_AS_NULL ) ) {
0083             // Handle Chinese as a special case. Chinese lang tags may carry
0084             // a `Hant` or `Hans` script subtag, and/or a region subtag.
0085             // As long as a translation for `zh_HK` isn't available, this
0086             // matching is sufficient.
0087             if( strcasecmp($result[1], "-hant") === 0 ) {
0088                 $language = "zh_TW";
0089             } else if( strcasecmp($result[1], "-hans") === 0 ) {
0090                 $language = "zh_CN";
0091             } else if( strcasecmp($result[2], "-tw") === 0 || strcasecmp($result[2], "-hk") === 0 || strcasecmp($result[2], "-mo") === 0 ) {
0092                 $language = "zh_TW";
0093             } else {
0094                 // Note this also matches `zh` without script or region subtag.
0095                 $language = "zh_CN";
0096             }
0097         } else {
0098             // Browsers use dashes to seperate language variants
0099             // But KDE translation systems use underscores for this so ensure we are consistent here
0100             $language = str_replace("-", "_", $language);
0101         }
0102 
0103         // Is this one of our supported languages?
0104         if( in_array($language, $supported_languages) ) {
0105             // Then we have a winner!
0106             return $language;
0107         }
0108     }
0109 
0110     // Finally if we found nothing we fallback to English
0111     return 'en';
0112 }
0113 
0114 // Start - Retrieve the values we need to work with here
0115 $requested_url = $_SERVER['REQUEST_URI'];
0116 $requested_languages = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
0117 
0118 // Before we can do anything else we need to clean up the URL we have received to remove the leading slash
0119 $requested_url = substr($requested_url, 1);
0120 
0121 // Now determine the language we should be sending the user to
0122 $language = determine_appropriate_language( $requested_url, $requested_languages, $supported_languages );
0123 
0124 // Split out the content part of the URL
0125 // We will need this for the matching we are about to do above
0126 if( !preg_match( '/^([a-z][a-z](_[A-Z][A-Z])?\/)?(.*)/', $requested_url, $result ) ) {
0127     // This shouldn't happen...
0128     // But in case it does, serve a 404 and bail
0129     http_response_code(404);
0130     include("../$language/404.html");
0131     exit();
0132 }
0133 
0134 // Save our result...
0135 $requested_page = $result[3];
0136 
0137 // First do a local check and see if $language/$requested_page exists..
0138 // This allows for urls such as https://docs.krita.org/user_manual/getting_started/starting_krita.html to work
0139 if( file_exists("../$language/$requested_page") ) {
0140     // Then redirect them there
0141     header("HTTP/1.1 301 Moved Permanently");
0142     header("Location: /$language/$requested_page");
0143     exit();
0144 }
0145 
0146 // Go across all of our redirect rules now and see if we have any matches
0147 foreach( $redirect_rules as $rule => $replacement ) {
0148     // Try to match it...
0149     if( !preg_match( "/$rule/", $requested_page, $result ) ) {
0150         // Then we need to try another one...
0151         continue;
0152     }
0153 
0154     // We have a winner!
0155     // Perform the redirect
0156     header("HTTP/1.1 301 Moved Permanently"); 
0157     header("Location: /$language/$replacement"); 
0158     exit();
0159 }
0160 
0161 // Alas it looks like we have no match :(
0162 // Send a 404
0163 http_response_code(404);
0164 include("../$language/404.html");
0165 exit();
0166 
0167 ?>