Exemple #1
0
 /**
  * Get the human-readable form of a language id, or a language entry from a language INI file. (STUB)
  *
  * @param  ID_TEXT		The language id
  * @param  ?mixed			The first token [string or tempcode] (replaces {1}) (NULL: none)
  * @param  ?mixed			The second token [string or tempcode] (replaces {2}) (NULL: none)
  * @param  ?mixed			The third token (replaces {3}). May be an array of [of string], to allow any number of additional args (NULL: none)
  * @param  ?LANGUAGE_NAME The language to use (NULL: users language)
  * @param  boolean		Whether to cause ocPortal to exit if the lookup does not succeed
  * @return ?mixed			The human-readable content (NULL: not found). String normally. Tempcode if tempcode parameters.
  */
 function do_lang($a, $param_a = NULL, $param_b = NULL, $param_c = NULL, $lang = NULL, $require_result = true)
 {
     if (function_exists('_do_lang')) {
         return _do_lang($a, $param_a, $param_b, $param_c, $lang, $require_result);
     }
     switch ($a) {
         case 'LINK_NEW_WINDOW':
             return 'new window';
         case 'SPREAD_TABLE':
             return 'Spread table';
         case 'MAP_TABLE':
             return 'Item to value mapper table';
         case 'charset':
             return NULL;
     }
     if (is_null($param_a)) {
         return $a;
     }
     return serialize(array($a, $param_a, $param_b, $param_c));
 }
Exemple #2
0
 /**
  * Get the human-readable form of a language id, or a language entry from a language INI file.
  *
  * @param  ID_TEXT		The language id
  * @param  ?mixed			The first token [string or tempcode] (replaces {1}) (NULL: none)
  * @param  ?mixed			The second token [string or tempcode] (replaces {2}) (NULL: none)
  * @param  ?mixed			The third token (replaces {3}). May be an array of [of string], to allow any number of additional args (NULL: none)
  * @param  ?LANGUAGE_NAME The language to use (NULL: users language)
  * @param  boolean		Whether to cause ocPortal to exit if the lookup does not succeed
  * @return ?mixed			The human-readable content (NULL: not found). String normally. Tempcode if tempcode parameters.
  */
 function _do_lang($codename, $token1 = NULL, $token2 = NULL, $token3 = NULL, $lang = NULL, $require_result = true)
 {
     $pos = strpos($codename, ':');
     if ($pos !== false) {
         require_lang(substr($codename, 0, $pos));
         $codename = substr($codename, $pos + 1);
     }
     global $LANGUAGE, $USER_LANG_CACHED, $RECORD_LANG_STRINGS, $XSS_DETECT, $PAGE_CACHE_FILE, $PAGE_CACHE_LANG_LOADED;
     if ($RECORD_LANG_STRINGS) {
         global $RECORDED_LANG_STRINGS;
         $RECORDED_LANG_STRINGS[$codename] = 1;
     }
     if ($lang === NULL) {
         $lang = $USER_LANG_CACHED === NULL ? user_lang() : $USER_LANG_CACHED;
     }
     if (!isset($LANGUAGE[$lang][$codename]) && (!array_key_exists($lang, $LANGUAGE) || !array_key_exists($codename, $LANGUAGE[$lang]))) {
         global $PAGE_CACHE_LAZY_LOAD, $PAGE_CACHE_LANGS_REQUESTED, $LANG_REQUESTED_LANG;
         if ($PAGE_CACHE_LAZY_LOAD) {
             $PAGE_CACHE_LAZY_LOAD = false;
             // We can't be lazy any more, but we will keep growing our pool so hopefully CAN be lazy the next time
             foreach ($PAGE_CACHE_LANGS_REQUESTED as $request) {
                 list($that_codename, $that_lang) = $request;
                 unset($LANG_REQUESTED_LANG[$that_lang][$that_codename]);
                 require_lang($that_codename, $that_lang, NULL, true);
             }
             $ret = _do_lang($codename, $token1, $token2, $token3, $lang, $require_result);
             if ($ret === NULL) {
                 $PAGE_CACHE_LANG_LOADED[$lang][$codename] = NULL;
                 if ($GLOBALS['MEM_CACHE'] !== NULL) {
                     persistant_cache_set($PAGE_CACHE_FILE, $PAGE_CACHE_LANG_LOADED);
                 } else {
                     @rewind($PAGE_CACHE_FILE);
                     @ftruncate($PAGE_CACHE_FILE, 0);
                     @fwrite($PAGE_CACHE_FILE, serialize($PAGE_CACHE_LANG_LOADED));
                 }
             }
             return $ret;
         }
         require_all_open_lang_files($lang);
     }
     if ($lang == 'xxx') {
         return 'xxx';
     }
     // Helpful for testing language compliancy. We don't expect to see non x's if we're running this language
     if (!isset($LANGUAGE[$lang][$codename]) && (!array_key_exists($lang, $LANGUAGE) || !array_key_exists($codename, $LANGUAGE[$lang]))) {
         if ($lang != fallback_lang()) {
             $ret = do_lang($codename, $token1, $token2, $token3, fallback_lang(), $require_result);
             if ($codename == 'charset') {
                 switch (strtolower($lang)) {
                     case 'ar':
                     case 'bg':
                     case 'zh-CN':
                     case 'zh-TW':
                     case 'hr':
                     case 'cs':
                     case 'da':
                     case 'nl':
                     case 'fi':
                     case 'fr':
                     case 'de':
                     case 'el':
                     case 'hi':
                     case 'it':
                     case 'ja':
                     case 'ko':
                     case 'pl':
                     case 'pt':
                     case 'ro':
                     case 'ru':
                     case 'es':
                     case 'sv':
                         $ret = 'utf-8';
                         break;
                 }
             } elseif (substr($codename, 0, 3) == 'FC_') {
                 $ret = ocp_mb_substr(trim(do_lang(substr($codename, 3), $token1, $token2, $token3, $lang)), 0, 1);
             } elseif ($codename == 'locale') {
                 $ret = strtolower($lang) . '_' . strtoupper($lang);
             } else {
                 $ret2 = strtolower($codename) != $codename ? google_translate($ret, $lang) : $ret;
                 if ($ret2 != $ret) {
                     $ret = $ret2;
                 }
             }
             if ($PAGE_CACHE_FILE !== NULL) {
                 if (!isset($PAGE_CACHE_LANG_LOADED[$lang][$codename]) && isset($PAGE_CACHE_LANG_LOADED[fallback_lang()][$codename])) {
                     $PAGE_CACHE_LANG_LOADED[$lang][$codename] = $ret;
                     // Will have been cached into fallback_lang() from the nested do_lang call, we need to copy it into our cache bucket for this language
                     if ($GLOBALS['MEM_CACHE'] !== NULL) {
                         persistant_cache_set($PAGE_CACHE_FILE, $PAGE_CACHE_LANG_LOADED);
                     } else {
                         @rewind($PAGE_CACHE_FILE);
                         @ftruncate($PAGE_CACHE_FILE, 0);
                         @fwrite($PAGE_CACHE_FILE, serialize($PAGE_CACHE_LANG_LOADED));
                     }
                 }
             }
             return $ret;
         } else {
             if ($require_result) {
                 global $USER_LANG_LOOP, $REQUIRE_LANG_LOOP;
                 //print_r(debug_backtrace());
                 if ($USER_LANG_LOOP == 1) {
                     critical_error('RELAY', 'Missing language code: ' . escape_html($codename) . '. This language code is required to produce error messages, and thus a critical error was prompted by the non-ability to show less-critical error messages. It is likely the source language files (lang/' . fallback_lang() . '/*.ini) for ocPortal on this website have been corrupted.');
                 }
                 if ($REQUIRE_LANG_LOOP >= 2) {
                     return '';
                 }
                 // Probably failing to load global.ini, so just output with some text missing
                 require_code('view_modes');
                 erase_cached_language();
                 fatal_exit(do_lang_tempcode('MISSING_LANG_ENTRY', escape_html($codename)));
             } else {
                 return NULL;
             }
         }
     }
     if ($PAGE_CACHE_FILE !== NULL) {
         if (!isset($PAGE_CACHE_LANG_LOADED[$lang][$codename])) {
             $PAGE_CACHE_LANG_LOADED[$lang][$codename] = $LANGUAGE[$lang][$codename];
             if ($GLOBALS['MEM_CACHE'] !== NULL) {
                 persistant_cache_set($PAGE_CACHE_FILE, $PAGE_CACHE_LANG_LOADED);
             } else {
                 @rewind($PAGE_CACHE_FILE);
                 @ftruncate($PAGE_CACHE_FILE, 0);
                 @fwrite($PAGE_CACHE_FILE, serialize($PAGE_CACHE_LANG_LOADED));
             }
         }
     }
     // Put in parameters
     static $non_plural_non_vowel = array('1', 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z');
     $looked_up = $LANGUAGE[$lang][$codename];
     if ($looked_up === NULL) {
         return NULL;
     }
     // Learning cache pool has told us this string definitely does not exist
     $out = str_replace('\\n', "\n", $looked_up);
     $plural_or_vowel_check = strpos($out, '|') !== false;
     if ($XSS_DETECT) {
         ocp_mark_as_escaped($out);
     }
     if ($token1 !== NULL) {
         if (is_object($token1) && $token2 === NULL || $token2 !== NULL && is_object($token2)) {
             $bits = preg_split('#\\{\\d[^\\}]*\\}#', $out, 2, PREG_SPLIT_OFFSET_CAPTURE);
             $ret = new ocp_tempcode();
             foreach ($bits as $bit) {
                 if ($XSS_DETECT) {
                     ocp_mark_as_escaped($bit[0]);
                 }
                 $at = $bit[1];
                 if ($at != 0) {
                     if ($out[$at - 2] == '1') {
                         $ret->attach($token1);
                     } elseif ($out[$at - 2] == '2') {
                         $ret->attach($token2);
                     } elseif ($plural_or_vowel_check && substr($out[$at - 2], 0, 2) == '1|') {
                         $exploded = explode('|', $out[$at - 2]);
                         $_token = $token1->evaluate();
                         $_token_denum = str_replace(',', '', $_token);
                         $ret->attach(in_array(is_numeric($_token_denum) ? $_token_denum : strtolower(substr($_token, 0, 1)), $non_plural_non_vowel) ? $exploded[1] : $exploded[2]);
                     } elseif ($plural_or_vowel_check && substr($out[$at - 2], 0, 2) == '2|') {
                         $exploded = explode('|', $out[$at - 2]);
                         $_token = $token2->evaluate();
                         $_token_denum = str_replace(',', '', $_token);
                         $ret->attach(in_array(is_numeric($_token_denum) ? $_token_denum : strtolower(substr($_token, 0, 1)), $non_plural_non_vowel) ? $exploded[1] : $exploded[2]);
                     }
                 }
                 $ret->attach($bit[0]);
             }
             return $ret;
         } elseif ($token1 !== NULL) {
             $out = str_replace('{1}', $token1, $out);
             if ($plural_or_vowel_check) {
                 $_token_denum = str_replace(',', '', $token1);
                 $out = preg_replace('#\\{1\\|(.*)\\|(.*)\\}#U', in_array(is_numeric($_token_denum) ? $_token_denum : strtolower(substr($token1, 0, 1)), $non_plural_non_vowel) ? '\\1' : '\\2', $out);
             }
             if ($XSS_DETECT && ocp_is_escaped($token1)) {
                 ocp_mark_as_escaped($out);
             }
         }
         if ($token2 !== NULL) {
             if ($XSS_DETECT) {
                 $escaped = ocp_is_escaped($out);
             }
             $out = str_replace('{2}', $token2, $out);
             if ($plural_or_vowel_check) {
                 $_token_denum = str_replace(',', '', $token1);
                 $out = preg_replace('#\\{2\\|(.*)\\|(.*)\\}#U', in_array(is_numeric($_token_denum) ? $_token_denum : strtolower(substr($token2, 0, 1)), $non_plural_non_vowel) ? '\\1' : '\\2', $out);
             }
             if ($XSS_DETECT && ocp_is_escaped($token2) && $escaped) {
                 ocp_mark_as_escaped($out);
             }
             if ($token3 !== NULL) {
                 $i = 3;
                 if (!is_array($token3)) {
                     $token3 = array($token3);
                 }
                 foreach ($token3 as $token) {
                     if ($XSS_DETECT) {
                         $escaped = ocp_is_escaped($out);
                     }
                     $out = str_replace('{' . strval($i) . '}', $token, $out);
                     if ($plural_or_vowel_check) {
                         $_token_denum = str_replace(',', '', $token);
                         $out = preg_replace('#\\{' . strval($i) . '\\|(.*)\\|(.*)\\}#U', in_array(is_numeric($_token_denum) ? $_token_denum : strtolower(substr($token, 0, 1)), $non_plural_non_vowel) ? '\\1' : '\\2', $out);
                     }
                     if ($XSS_DETECT && ocp_is_escaped($token) && $escaped) {
                         ocp_mark_as_escaped($out);
                     }
                     $i++;
                 }
             }
         }
     }
     return $out;
 }
Exemple #3
0
 /**
  * Get the human-readable form of a language id, or a language entry from a language INI file. (STUB)
  *
  * @param  ID_TEXT		The language id
  * @param  ?mixed			The first token [string or tempcode] (replaces {1}) (NULL: none)
  * @param  ?mixed			The second token [string or tempcode] (replaces {2}) (NULL: none)
  * @param  ?mixed			The third token (replaces {3}). May be an array of [of string], to allow any number of additional args (NULL: none)
  * @param  ?LANGUAGE_NAME The language to use (NULL: users language)
  * @param  boolean		Whether to cause ocPortal to exit if the lookup does not succeed
  * @return ?mixed			The human-readable content (NULL: not found). String normally. Tempcode if tempcode parameters.
  */
 function do_lang($a, $param_a = NULL, $param_b = NULL, $param_c = NULL, $lang = NULL, $require_result = true)
 {
     if (function_exists('_do_lang')) {
         return _do_lang($a, $param_a, $param_b, $param_c, $lang, $require_result);
     }
     unset($lang);
     unset($allow_fail);
     switch ($a) {
         case 'LINK_NEW_WINDOW':
             return 'new window';
         case 'SPREAD_TABLE':
             return 'Spread table';
         case 'MAP_TABLE':
             return 'Item to value mapper table';
     }
     return array($a, $param_a, $param_b, $param_c);
 }
Exemple #4
0
/**
 * Get the human-readable form of a language id, or a language entry from a language INI file.
 *
 * @param  ID_TEXT		The language id
 * @param  ?mixed			The first token [string or tempcode] (replaces {1}) (NULL: none)
 * @param  ?mixed			The second token [string or tempcode] (replaces {2}) (NULL: none)
 * @param  ?mixed			The third token (replaces {3}). May be an array of [of string], to allow any number of additional args (NULL: none)
 * @param  ?LANGUAGE_NAME The language to use (NULL: users language)
 * @param  boolean		Whether to cause ocPortal to exit if the lookup does not succeed
 * @return ?mixed			The human-readable content (NULL: not found). String normally. Tempcode if tempcode parameters.
 */
function _do_lang($codename, $token1 = NULL, $token2 = NULL, $token3 = NULL, $lang = NULL, $require_result = true)
{
    global $LANGUAGE, $USER_LANG_CACHED, $RECORD_LANG_STRINGS, $XSS_DETECT, $PAGE_CACHE_FILE, $PAGE_CACHE_LANG_LOADED;
    if ($lang === NULL) {
        $lang = $USER_LANG_CACHED === NULL ? user_lang() : $USER_LANG_CACHED;
    }
    if ($GLOBALS['SEMI_DEBUG_MODE']) {
        $pos = strpos($codename, '=');
        if ($pos !== false) {
            // Find loaded file with smallest levenstein distance to current page
            $best = mixed();
            $best_for = NULL;
            global $LANGS_REQUESTED;
            foreach (array_keys($LANGS_REQUESTED) as $possible) {
                $dist = levenshtein(get_page_name(), $possible);
                if (is_null($best) || $best > $dist) {
                    $best = $dist;
                    $best_for = $possible;
                }
            }
            $save_path = get_file_base() . '/lang/' . fallback_lang() . '/' . $best_for . '.ini';
            if (!is_file($save_path)) {
                $save_path = get_file_base() . '/lang_custom/' . fallback_lang() . '/' . $best_for . '.ini';
            }
            // Tack language strings onto this file
            list($codename, $value) = explode('=', $codename, 2);
            $myfile = fopen($save_path, 'at');
            fwrite($myfile, "\n" . $codename . '=' . $value);
            fclose($myfile);
            // Fake-load the string
            $LANGUAGE[$lang][$codename] = $value;
            // Go through all required files, doing a string replace if needed
            $included_files = get_included_files();
            foreach ($included_files as $inc) {
                $orig_contents = file_get_contents($inc);
                $contents = str_replace("'" . $codename . '=' . $value . "'", "'" . $codename . "'", $orig_contents);
                if ($orig_contents != $contents) {
                    $myfile = fopen($inc, 'wt');
                    fwrite($myfile, $contents);
                    fclose($myfile);
                }
            }
        }
    }
    $there = isset($LANGUAGE[$lang][$codename]);
    if (!$there) {
        $pos = strpos($codename, ':');
        if ($pos !== false) {
            require_lang(substr($codename, 0, $pos), NULL, NULL, !$require_result);
            $codename = substr($codename, $pos + 1);
        }
        $there = isset($LANGUAGE[$lang][$codename]);
    }
    if ($RECORD_LANG_STRINGS) {
        global $RECORDED_LANG_STRINGS;
        $RECORDED_LANG_STRINGS[$codename] = 1;
    }
    if (!$there && (!isset($LANGUAGE[$lang]) || !array_key_exists($codename, $LANGUAGE[$lang]))) {
        global $PAGE_CACHE_LAZY_LOAD, $PAGE_CACHE_LANGS_REQUESTED, $LANG_REQUESTED_LANG;
        if ($PAGE_CACHE_LAZY_LOAD) {
            $PAGE_CACHE_LAZY_LOAD = false;
            // We can't be lazy any more, but we will keep growing our pool so hopefully CAN be lazy the next time
            foreach ($PAGE_CACHE_LANGS_REQUESTED as $request) {
                list($that_codename, $that_lang) = $request;
                unset($LANG_REQUESTED_LANG[$that_lang][$that_codename]);
                require_lang($that_codename, $that_lang, NULL, true);
            }
            $ret = _do_lang($codename, $token1, $token2, $token3, $lang, $require_result);
            if ($ret === NULL) {
                $PAGE_CACHE_LANG_LOADED[$lang][$codename] = NULL;
                if ($GLOBALS['MEM_CACHE'] !== NULL) {
                    persistant_cache_set($PAGE_CACHE_FILE, $PAGE_CACHE_LANG_LOADED);
                } else {
                    open_page_cache_file();
                    @rewind($PAGE_CACHE_FILE);
                    @flock($PAGE_CACHE_FILE, LOCK_EX);
                    @ftruncate($PAGE_CACHE_FILE, 0);
                    @fwrite($PAGE_CACHE_FILE, serialize($PAGE_CACHE_LANG_LOADED));
                    @flock($PAGE_CACHE_FILE, LOCK_UN);
                }
            }
            return $ret;
        }
        require_all_open_lang_files($lang);
    }
    if ($lang == 'xxx') {
        return 'xxx';
    }
    // Helpful for testing language compliancy. We don't expect to see non x's if we're running this language
    if (!isset($LANGUAGE[$lang][$codename]) && ($require_result || !isset($LANGUAGE[$lang]) || !array_key_exists($codename, $LANGUAGE[$lang]))) {
        if ($lang != fallback_lang()) {
            $ret = do_lang($codename, $token1, $token2, $token3, fallback_lang(), $require_result);
            if ($PAGE_CACHE_FILE !== NULL) {
                if (!isset($PAGE_CACHE_LANG_LOADED[$lang][$codename]) && isset($PAGE_CACHE_LANG_LOADED[fallback_lang()][$codename])) {
                    $PAGE_CACHE_LANG_LOADED[$lang][$codename] = $PAGE_CACHE_LANG_LOADED[fallback_lang()][$codename];
                    // Will have been cached into fallback_lang() from the nested do_lang call, we need to copy it into our cache bucket for this language
                    if ($GLOBALS['MEM_CACHE'] !== NULL) {
                        persistant_cache_set($PAGE_CACHE_FILE, $PAGE_CACHE_LANG_LOADED);
                    } else {
                        open_page_cache_file();
                        @rewind($PAGE_CACHE_FILE);
                        @flock($PAGE_CACHE_FILE, LOCK_EX);
                        @ftruncate($PAGE_CACHE_FILE, 0);
                        @fwrite($PAGE_CACHE_FILE, serialize($PAGE_CACHE_LANG_LOADED));
                        @flock($PAGE_CACHE_FILE, LOCK_UN);
                    }
                }
            }
            return $ret;
        } else {
            if ($require_result) {
                global $USER_LANG_LOOP, $REQUIRE_LANG_LOOP;
                //print_r(debug_backtrace());
                if ($USER_LANG_LOOP == 1) {
                    critical_error('RELAY', 'Missing language code: ' . escape_html($codename) . '. This language code is required to produce error messages, and thus a critical error was prompted by the non-ability to show less-critical error messages. It is likely the source language files (lang/' . fallback_lang() . '/*.ini) for ocPortal on this website have been corrupted.');
                }
                if ($REQUIRE_LANG_LOOP >= 2) {
                    return '';
                }
                // Probably failing to load global.ini, so just output with some text missing
                require_code('view_modes');
                erase_cached_language();
                require_code('site');
                attach_message(do_lang_tempcode('MISSING_LANG_ENTRY', escape_html($codename)), 'warn');
                return '';
            } else {
                return NULL;
            }
        }
    }
    if ($PAGE_CACHE_FILE !== NULL) {
        if (!isset($PAGE_CACHE_LANG_LOADED[$lang][$codename]) && (!isset($PAGE_CACHE_LANG_LOADED[$lang]) || !array_key_exists($codename, $PAGE_CACHE_LANG_LOADED[$lang]))) {
            $PAGE_CACHE_LANG_LOADED[$lang][$codename] = $LANGUAGE[$lang][$codename];
            if ($GLOBALS['MEM_CACHE'] !== NULL) {
                persistant_cache_set($PAGE_CACHE_FILE, $PAGE_CACHE_LANG_LOADED);
            } else {
                open_page_cache_file();
                @rewind($PAGE_CACHE_FILE);
                @flock($PAGE_CACHE_FILE, LOCK_EX);
                @ftruncate($PAGE_CACHE_FILE, 0);
                @fwrite($PAGE_CACHE_FILE, serialize($PAGE_CACHE_LANG_LOADED));
                @flock($PAGE_CACHE_FILE, LOCK_UN);
            }
        }
    }
    // Put in parameters
    static $non_plural_non_vowel = array('1', 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', '{');
    $looked_up = $LANGUAGE[$lang][$codename];
    if ($looked_up === NULL) {
        return NULL;
        // Learning cache pool has told us this string definitely does not exist
    }
    $out = str_replace('\\n', "\n", $looked_up);
    $plural_or_vowel_check = strpos($out, '|') !== false;
    if ($XSS_DETECT) {
        ocp_mark_as_escaped($out);
    }
    if ($token1 !== NULL) {
        if (is_object($token1) && $token2 === NULL || $token2 !== NULL && is_object($token2)) {
            $bits = preg_split('#\\{\\d[^\\}]*\\}#', $out, 2, PREG_SPLIT_OFFSET_CAPTURE);
            $ret = new ocp_tempcode();
            foreach ($bits as $bit) {
                if ($XSS_DETECT) {
                    ocp_mark_as_escaped($bit[0]);
                }
                $at = $bit[1];
                if ($at != 0) {
                    if ($out[$at - 2] == '1') {
                        $ret->attach($token1);
                    } elseif ($out[$at - 2] == '2') {
                        $ret->attach($token2);
                    } elseif ($plural_or_vowel_check && substr($out[$at - 2], 0, 2) == '1|') {
                        $exploded = explode('|', $out[$at - 2]);
                        $_token = $token1->evaluate();
                        $_token_denum = str_replace(',', '', $_token);
                        $ret->attach(in_array(is_numeric($_token_denum) ? $_token_denum : ocp_mb_strtolower(ocp_mb_substr($_token, 0, 1)), $non_plural_non_vowel) ? $exploded[1] : $exploded[2]);
                    } elseif ($plural_or_vowel_check && substr($out[$at - 2], 0, 2) == '2|') {
                        $exploded = explode('|', $out[$at - 2]);
                        $_token = $token2->evaluate();
                        $_token_denum = str_replace(',', '', $_token);
                        $ret->attach(in_array(is_numeric($_token_denum) ? $_token_denum : ocp_mb_strtolower(ocp_mb_substr($_token, 0, 1)), $non_plural_non_vowel) ? $exploded[1] : $exploded[2]);
                    }
                }
                $ret->attach($bit[0]);
            }
            return $ret;
        } elseif ($token1 !== NULL) {
            $out = str_replace('{1}', $token1, $out);
            if ($plural_or_vowel_check) {
                $_token_denum = str_replace(',', '', $token1);
                $out = preg_replace('#\\{1\\|(.*)\\|(.*)\\}#U', in_array(is_numeric($_token_denum) ? $_token_denum : ocp_mb_strtolower(ocp_mb_substr($token1, 0, 1)), $non_plural_non_vowel) ? '\\1' : '\\2', $out);
            }
            if ($XSS_DETECT && ocp_is_escaped($token1)) {
                ocp_mark_as_escaped($out);
            }
        }
        if ($token2 !== NULL) {
            if ($XSS_DETECT) {
                $escaped = ocp_is_escaped($out);
            }
            $out = str_replace('{2}', $token2, $out);
            if ($plural_or_vowel_check) {
                $_token_denum = str_replace(',', '', $token1);
                $out = preg_replace('#\\{2\\|(.*)\\|(.*)\\}#U', in_array(is_numeric($_token_denum) ? $_token_denum : ocp_mb_strtolower(ocp_mb_substr($token2, 0, 1)), $non_plural_non_vowel) ? '\\1' : '\\2', $out);
            }
            if ($XSS_DETECT && ocp_is_escaped($token2) && $escaped) {
                ocp_mark_as_escaped($out);
            }
            if ($token3 !== NULL) {
                $i = 3;
                if (!is_array($token3)) {
                    $token3 = array($token3);
                }
                foreach ($token3 as $token) {
                    if ($XSS_DETECT) {
                        $escaped = ocp_is_escaped($out);
                    }
                    $out = str_replace('{' . strval($i) . '}', $token, $out);
                    if ($plural_or_vowel_check) {
                        $_token_denum = str_replace(',', '', $token);
                        $out = preg_replace('#\\{' . strval($i) . '\\|(.*)\\|(.*)\\}#U', in_array(is_numeric($_token_denum) ? $_token_denum : ocp_mb_strtolower(ocp_mb_substr($token, 0, 1)), $non_plural_non_vowel) ? '\\1' : '\\2', $out);
                    }
                    if ($XSS_DETECT && ocp_is_escaped($token) && $escaped) {
                        ocp_mark_as_escaped($out);
                    }
                    $i++;
                }
            }
        }
    }
    return $out;
}