# HG changeset patch # User Dan # Date 1217272061 21600 # Node ID 0631e4de5de698a7aa2e5f7481e3501d0674eefc # Parent 72818d2bf3366db1bdc25df2f848aec95878aab1 Added ability to have language strings send variables through filter functions. Operates based on predefined filters, expandable with a call to Language::register_filter at the hook lang_init diff -r 72818d2bf336 -r 0631e4de5de6 includes/lang.php --- a/includes/lang.php Mon Jul 28 13:06:36 2008 -0600 +++ b/includes/lang.php Mon Jul 28 13:07:41 2008 -0600 @@ -68,6 +68,14 @@ var $debug = false; /** + * List of available filters to pass variables through. + * @var array + * @access private + */ + + protected $filters = array(); + + /** * Constructor. * @param int|string Language ID or code to load. */ @@ -113,6 +121,16 @@ $this->lang_id = intval( $row['lang_id'] ); $this->lang_code = $row['lang_code']; $this->lang_timestamp = $row['last_changed']; + + $this->register_filter('htmlsafe', 'htmlspecialchars'); + $this->register_filter('urlencode', 'urlencode'); + $this->register_filter('rawurlencode', 'rawurlencode'); + + $code = $plugins->setHook('lang_init'); + foreach ( $code as $cmd ) + { + eval($cmd); + } } /** @@ -591,6 +609,30 @@ } /** + * Registers a filter, a function that strings can be passed through to change the string somehow (e.g. htmlspecialchars) + * @param string Filter name. Lowercase alphanumeric (htmlsafe) + * @param callback Function to call. + * @return bool True on success, false if some error occurred + */ + + public function register_filter($filter_name, $filter_function) + { + if ( !is_string($filter_function) && !is_array($filter_function) ) + { + return false; + } + if ( ( is_string($filter_function) && !function_exists($filter_function) ) || ( is_array($filter_function) && !method_exists(@$filter_function[0], @$filter_function[1]) ) ) + { + return false; + } + if ( !preg_match('/^[a-z0-9_]+$/', $filter_name) ) + { + return false; + } + $this->filters[$filter_name] = $filter_function; + } + + /** * Fetches a language string from the cache in RAM. If it isn't there, it will call fetch() again and then try. If it still can't find it, it will ask for the string * in the default language. If even then the string can't be found, this function will return what was passed to it. * @@ -679,30 +721,64 @@ function substitute($string, $subs) { - preg_match_all('/%this\.([a-z0-9_]+)%/', $string, $matches); + preg_match_all('/%this\.([a-z0-9_]+)((?:\|(?:[a-z0-9_]+))*)%/', $string, $matches); if ( count($matches[0]) > 0 ) { foreach ( $matches[1] as $i => $string_id ) { $result = $this->get($string_id); - $string = str_replace($matches[0][$i], $result, $string); + $string = str_replace($matches[0][$i], $this->process_filters($result, $matches[2][$i]), $string); } } - preg_match_all('/%config\.([a-z0-9_]+)%/', $string, $matches); + preg_match_all('/%config\.([a-z0-9_]+)((?:\|(?:[a-z0-9_]+))*)%/', $string, $matches); + if ( count($matches[0]) > 0 ) + { + foreach ( $matches[1] as $i => $string_id ) + { + $result = getConfig($string_id, ''); + $string = str_replace($matches[0][$i], $this->process_filters($result, $matches[2][$i]), $string); + } + } + preg_match_all('/%([a-z0-9_]+)((?:\|(?:[a-z0-9_]+))*)%/', $string, $matches); if ( count($matches[0]) > 0 ) { foreach ( $matches[1] as $i => $string_id ) { - $result = getConfig($string_id); - $string = str_replace($matches[0][$i], $result, $string); + if ( isset($subs[$string_id]) ) + { + $string = str_replace($matches[0][$i], $this->process_filters($subs[$string_id], $matches[2][$i]), $string); + } } } - foreach ( $subs as $key => $value ) + return ( $this->debug ) ? "$string*" : $string; + } + + /** + * Processes filters to a language string. + * @param string Unprocessed string + * @param string Filter list (format: |filter1|filter2|filter3, initial pipe is important); can also be an array if you so desire + * @return string + */ + + function process_filters($string, $filters) + { + if ( !empty($filters) ) { - $subs[$key] = strval($value); - $string = str_replace("%{$key}%", "{$subs[$key]}", $string); + $filters = trim($filters, '|'); + $filters = explode('|', $filters); + foreach ( $filters as $filter ) + { + if ( isset($this->filters[$filter]) ) + { + $result = @call_user_func($this->filters[$filter], $string); + if ( is_string($result) ) + { + $string = $result; + } + } + } } - return ( $this->debug ) ? "$string*" : $string; + return $string; } } // class Language