diff --git a/conlite/classes/UrlBuilder/Contenido_UrlBuilder_MR.class.php b/conlite/classes/UrlBuilder/Contenido_UrlBuilder_MR.class.php index 4035c98..e9e4a24 100644 --- a/conlite/classes/UrlBuilder/Contenido_UrlBuilder_MR.class.php +++ b/conlite/classes/UrlBuilder/Contenido_UrlBuilder_MR.class.php @@ -186,6 +186,8 @@ class Contenido_UrlBuilder_MR extends Contenido_UrlBuilder // get pretty url parts $oMRUrlStack = ModRewriteUrlStack::getInstance(); $aPretty = $oMRUrlStack->getPrettyUrlParts('front_content.php?' . $sQuery); + + ModRewriteDebugger::add($aPretty, 'Contenido_UrlBuilder_MR::_buildUrl() getPrettyUrlParts'); // get all non contenido related query parameter $sQuery = $this->_createUrlQueryPart($aParams); @@ -209,6 +211,9 @@ class Contenido_UrlBuilder_MR extends Contenido_UrlBuilder $aParts[] = $sPath; } $sPath = implode('/', $aParts) . '/'; + + ModRewriteDebugger::add($aParts, 'Contenido_UrlBuilder_MR::_buildUrl() $aParts'); + ModRewriteDebugger::add($sPath, 'Contenido_UrlBuilder_MR::_buildUrl() $sPath'); // get pagename part of the url $sArticle = $this->_getArticleName($aPretty, $aParams); @@ -343,7 +348,7 @@ class Contenido_UrlBuilder_MR extends Contenido_UrlBuilder */ private function _getPath(array $aPretty) { - $sPath = (isset($aPretty['urlpath'])) ? $aPretty['urlpath'] : ''; + $sPath = (!empty($aPretty['urlpath'])) ? $aPretty['urlpath'] : ''; // check start directory settings if ($this->_aMrCfg['startfromroot'] == 0 && (strlen($sPath) > 0)) { diff --git a/conlite/classes/class.string.multi.byte.wrapper.php b/conlite/classes/class.string.multi.byte.wrapper.php new file mode 100644 index 0000000..cc101ca --- /dev/null +++ b/conlite/classes/class.string.multi.byte.wrapper.php @@ -0,0 +1,405 @@ + + * @author Marcus Gnaß + * @copyright four for business AG + * @license http://www.contenido.org/license/LIZENZ.txt + * @link http://www.4fb.de + * @link http://www.contenido.org + */ + +defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.'); + +/** + * Wrapper class for mbstring functions to be used with strings. + * + * Each method is a wrapper for a mbstring function that implements a fallback + * to the regular string function if the mbstring function does not exist + * or the mbstring extension itself is not available. + * + * @package Core + * @subpackage Util + * @todo add mb_chr(), mb_ord() + */ +class cStringMultiByteWrapper { + + /** + * Checks if a given mbstring function exists. + * + * Caches informations about existing mbstring functions for better + * performance. + * + * @param string $functionName + * @return bool + */ + protected static function _functionExists($functionName) { + static $cache; + if (!isset($cache)) { + $cache = array(); + foreach (array( + 'mb_strtolower', 'mb_strtoupper', 'mb_strlen', 'mb_substr', + 'mb_substr_count', 'mb_send_mail', 'mb_strpos', 'mb_strrpos', 'mb_stripos', + 'mb_strripos', 'mb_stristr', 'mb_strrchr' + ) as $function) { + $cache[$function] = function_exists($function); + } + } + return isset($cache[$functionName]) ? $cache[$functionName] : false; + } + + /** + * Determines multi byte encoding to be used for various mbstring functions. + * + * If NULL is given the encoding for the current language is used + * which tends to be awfully slow as it requires a database lookup! + * + * If none could be determined the current set encoding is used. + * + * @param string|null $encoding + * - give a string to use a specific encoding + * - give null to use the encoding of the current language + * @return string + */ + protected static function _getEncoding($encoding = null) { + if (!is_string($encoding)) { + $encoding = mb_internal_encoding(); + } + return $encoding; + } + + /** + * Make a string lowercase + * + * @param string $string + * The string being lowercased + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return string + * with all alphabetic characters converted to lowercases + * @link http://php.net/manual/de/function.mb-strtolower.php + */ + public static function toLowerCase($string, $encoding = null) { + if (self::_functionExists('mb_strtolower')) { + $result = mb_strtolower($string, self::_getEncoding($encoding)); + } else { + $result = strtolower($string); + } + return $result; + } + + /** + * Make a string uppercase + * + * @param string $string + * The string being uppercased + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return string + * with all alphabetic characters converted to uppercases + * @link http://php.net/manual/de/function.mb-strtoupper.php + */ + public static function toUpperCase($string, $encoding = null) { + if (self::_functionExists('mb_strtoupper')) { + $result = mb_strtoupper($string, self::_getEncoding($encoding)); + } else { + $result = strtoupper($string); + } + return $result; + } + + /** + * Get string length + * + * @param string $string + * The string being checked for length + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return int + * Returns the number of characters + * @link http://php.net/manual/de/function.mb-strlen.php + */ + public static function getStringLength($string, $encoding = null) { + if (self::_functionExists('mb_strlen')) { + $result = mb_strlen($string, self::_getEncoding($encoding)); + } else { + $result = strlen($string); + } + return $result; + } + + /** + * Get string length + * + * @param string $string + * The string to extract the substring form + * @param int $start + * @param int $length [Optional] + * Maximum number of characters to use from $string, standard is NULL + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return string + * Returns the number of characters + * @link http://php.net/manual/de/function.mb-substr.php + */ + public static function getPartOfString($string, $start, $length = null, $encoding = null) { + if (self::_functionExists('mb_substr')) { + $result = mb_substr($string, $start, $length, self::_getEncoding($encoding)); + } else { + $result = substr($string, $start, $length); + } + return $result; + } + + /** + * Count the number of substring occurences + * + * @param string $haystack + * The string being checked + * @param string $needle + * The string being found + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return int + * The number of times the needle substring occurs in the haystack string. + * @link http://php.net/manual/de/function.mb-substr-count.php + */ + public static function countSubstring($haystack, $needle, $encoding = null) { + if (self::_functionExists('mb_substr_count')) { + $result = mb_substr_count($haystack, $needle, self::_getEncoding($encoding)); + } else { + $result = substr_count($haystack, $needle); + } + return $result; + } + + /** + * Send encoded mail + * + * @param string $to + * The mail addresses being sent to (multiple recipents comma separated) + * @param string $subject + * The subject of the mail + * @param string $message + * The message of the mail + * @param string $additional_headers [Optional] + * @param string $additional_parameter [Optional] + * @return boolean + * true or false + * @link http://php.net/manual/de/function.mb-send-mail.php + */ + public static function mail($to, $subject, $message, $additional_headers = null, $additional_parameter = null) { + if (self::_functionExists('mb_send_mail')) { + $result = mb_send_mail($to, $subject, $message, $additional_headers, $additional_parameter); + } else { + $result = mail($to, $subject, $message, $additional_headers, $additional_parameter); + } + return $result; + } + + /** + * Find the position of first occurence of string in a string + * + * @param string $haystack + * @param string $needle + * @param integer $offset [Optional] + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return int + * Returns the numeric position of the first occurrence of needle in the haystack string + * @link http://php.net/manual/de/function.mb-strpos.php + */ + public static function findFirstPos($haystack, $needle, $offset = 0, $encoding = null) { + if (self::_functionExists('mb_strpos')) { + $result = mb_strpos($haystack, $needle, $offset, self::_getEncoding($encoding)); + } else { + $result = strpos($haystack, $needle, $offset); + } + return $result; + } + + /** + * Find the position of last occurence of string in a string + * + * @param string $haystack + * @param string $needle + * @param integer $offset [Optional] + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return int + * Returns the numeric position of the last occurrence of needle in the haystack string + * @link http://php.net/manual/de/function.mb-strrpos.php + */ + public static function findLastPos($haystack, $needle, $offset = 0, $encoding = null) { + if (self::_functionExists('mb_strrpos')) { + $result = mb_strrpos($haystack, $needle, $offset, self::_getEncoding($encoding)); + } else { + $result = strrpos($haystack, $needle, $offset); + } + return $result; + } + + /** + * Finds position of first occurrence of a string within another, case insensitive + * + * @param string $haystack + * @param string $needle + * @param integer $offset [Optional] + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return int + * Returns the numeric position of the first occurrence of needle in the haystack string + * @link http://php.net/manual/de/function.mb-stripos.php + */ + public static function findFirstPosCI($haystack, $needle, $offset = 0, $encoding = null) { + if (self::_functionExists('mb_stripos')) { + $result = mb_stripos($haystack, $needle, $offset, self::_getEncoding($encoding)); + } else { + $result = stripos($haystack, $needle, $offset); + } + return $result; + } + + /** + * Finds position of last occurrence of a string within another, case insensitive + * + * @param string $haystack + * @param string $needle + * @param integer $offset [Optional] + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return int + * Returns the numeric position of the last occurrence of needle in the haystack string + * @link http://php.net/manual/de/function.mb-strripos.php + */ + public static function findLastPosCI($haystack, $needle, $offset = 0, $encoding = null) { + if (self::_functionExists('mb_strripos')) { + $result = mb_strripos($haystack, $needle, $offset, self::_getEncoding($encoding)); + } else { + $result = strripos($haystack, $needle, $offset); + } + return $result; + } + + /** + * Finds first occurrence of a string within another, case insensitive + * + * @param string $haystack + * @param string $needle + * @param boolean $before_needle [Optional] + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return string + * Returns the portion of haystack, or FALSE if needle is not found. + * @link http://php.net/manual/de/function.mb-stristr.php + */ + public static function findFirstOccurrenceCI($haystack, $needle, $before_needle = false, $encoding = null) { + if (self::_functionExists('mb_stristr')) { + $result = mb_stristr($haystack, $needle, $before_needle, self::_getEncoding($encoding)); + } else { + $result = stristr($haystack, $needle, $before_needle); + } + return $result; + } + + /** + * Finds first occurrence of a string within another, case insensitive + * + * @param string $haystack + * @param string $needle + * @param boolean $part [Optional] + * @param string|null $encoding + * encoding parameter, standard: cRegistry::getEncoding() + * @return string + * Returns the portion of haystack, or FALSE if needle is not found. + * @link http://php.net/manual/de/function.mb-strrchr.php + */ + public static function findLastOccurrence($haystack, $needle, $part = false, $encoding = null) { + if (self::_functionExists('mb_strrchr')) { + $result = mb_strrchr($haystack, $needle, $part, self::_getEncoding($encoding)); + } elseif (!$part) { + $result = strrchr($haystack, $needle); + } else { + // TODO strrchr canot handle $part = true + $result = null; + } + return $result; + } + + /** + * Regular expression match + * + * @param string $pattern + * @param string $string + * @param array $regs [Optional] + * @return int + * @link http://php.net/manual/de/function.mb-ereg.php + */ + public static function ereg($pattern, $string, &$regs = array()) { + // TODO provide fallback multibyte extension is missing + return mb_ereg($pattern, $string, $regs); + } + + /** + * Regular expression match ignoring case + * + * @param string $pattern + * @param string $string + * @param array $regs [Optional] + * @return int Returns the byte length of the matched string if a match for pattern was found in string + * @link http://php.net/manual/de/function.mb-eregi.php + */ + public static function eregi($pattern, $string, &$regs = array()) { + // TODO provide fallback multibyte extension is missing + return mb_eregi($pattern, $string, $regs); + } + + /** + * Replace regular expression + * + * @param string $pattern + * @param string $replacement + * @param string $string + * @param string $option [Optional] + * @return false|string Returns the byte length of the matched string if a match for pattern was found in string + * @link http://php.net/manual/de/function.mb-ereg-replace.php + */ + public static function ereg_replace($pattern, $replacement, $string, $option = 'msr') { + // TODO provide fallback multibyte extension is missing + return mb_ereg_replace($pattern, $replacement, $string, $option); + } + + /** + * Replace regular expression ignoring case + * + * @param string $pattern + * @param string $replacement + * @param string $string + * @param string $option [Optional] + * @return false|string Returns the byte length of the matched string if a match for pattern was found in string + * @link http://php.net/manual/de/function.mb-eregi-replace.php + */ + public static function eregi_replace($pattern, $replacement, $string, $option = 'msr') { + // TODO provide fallback multibyte extension is missing + return mb_eregi_replace($pattern, $replacement, $string, $option); + } + + /** + * Split string using regular expression + * + * @param string $pattern + * @param string $string + * @param integer $limit [Optional] + * @return string[] The result as an array + * @link http://php.net/manual/de/function.mb-split.php + */ + public static function split($pattern, $string, $limit = -1) { + // TODO provide fallback multibyte extension is missing + return mb_split($pattern, $string, $limit); + } + +} diff --git a/conlite/classes/class.string.php b/conlite/classes/class.string.php new file mode 100644 index 0000000..3f371a1 --- /dev/null +++ b/conlite/classes/class.string.php @@ -0,0 +1,718 @@ + + * @copyright four for business AG + * @license http://www.contenido.org/license/LIZENZ.txt + * @link http://www.4fb.de + * @link http://www.contenido.org + */ + +defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.'); + +/** + * String helper class. + * + * @package Core + * @subpackage Util + */ +class cString extends cStringMultiByteWrapper { + + /** + * Replaces a string only once. + * + * Caution: This function only takes strings as parameters, not arrays! + * + * @param string $find + * String to find + * @param string $replace + * String to replace + * @param string $subject + * String to process + * @return string + * Processed string + */ + public static function iReplaceOnce($find, $replace, $subject) { + $start = parent::findFirstPos(parent::toLowerCase($subject), parent::toLowerCase($find)); + + if ($start === false) { + return $subject; + } + + $end = $start + parent::getStringLength($find); + $first = parent::getPartOfString($subject, 0, $start); + $last = parent::getPartOfString($subject, $end, parent::getStringLength($subject) - $end); + + $result = $first . $replace . $last; + + return $result; + } + + /** + * Replaces a string only once, in reverse direction. + * + * Caution: This function only takes strings as parameters, not arrays! + * + * @param string $find + * String to find + * @param string $replace + * String to replace + * @param string $subject + * String to process + * @return string + * Processed string + */ + public static function iReplaceOnceReverse($find, $replace, $subject) { + $start = self::posReverse(parent::toLowerCase($subject), parent::toLowerCase($find)); + + if ($start === false) { + return $subject; + } + + $end = $start + parent::getStringLength($find); + + $first = parent::getPartOfString($subject, 0, $start); + $last = parent::getPartOfString($subject, $end, parent::getStringLength($subject) - $end); + + $result = $first . $replace . $last; + + return $result; + } + + /** + * Finds a string position in reverse direction. + * + * NOTE: The original cString::findLastPos-function of PHP4 only finds a single character + * as needle. + * + * @param string $haystack + * String to search in + * @param string $needle + * String to search for + * @param int $start [optional] + * Offset + * @return int + * String position + */ + public static function posReverse($haystack, $needle, $start = 0) { + $tempPos = parent::findFirstPos($haystack, $needle, $start); + + if ($tempPos === false) { + if ($start == 0) { + // Needle not in string at all + return false; + } else { + // No more occurances found + return $start - parent::getStringLength($needle); + } + } else { + // Find the next occurance + return self::posReverse($haystack, $needle, $tempPos + parent::getStringLength($needle)); + } + } + + /** + * Adds slashes to passed variable or array. + * + * @param string|array $value + * Either a string or a multi-dimensional array of values + * @return string|array + */ + public static function addSlashes($value) { + $value = is_array($value) ? array_map(array('cString', 'addSlashes'), $value) : addslashes($value); + return $value; + } + + /** + * Removes slashes from passed variable or array. + * + * @param string|array $value + * Either a string or a multi-dimensional array of values + * @return string|array + */ + public static function stripSlashes($value) { + $value = is_array($value) ? array_map(array('cString', 'stripSlashes'), $value) : stripslashes($value); + return $value; + } + + /** + * Checks if the string haystack ends with needle. + * + * @param string $haystack + * The string to check + * @param string $needle + * The string with which it should end + * @return bool + */ + public static function endsWith($haystack, $needle) { + $length = parent::getStringLength($needle); + if ($length == 0) { + return true; + } + + return parent::getPartOfString($haystack, -$length) === $needle; + } + + /** + * Returns true if needle can be found in haystack. + * + * @param string $haystack + * String to be searched + * @param string $needle + * String to search for + * @return bool + */ + public static function contains($haystack, $needle) { + return !(parent::findFirstPos($haystack, $needle) === false); + } + + /** + * Implementation of PHP 5.3's strstr with beforeNeedle. + * + * @param string $haystack + * String to be searched + * @param string $needle + * String to search for + * @param bool $beforeNeedle [optional] + * If true, return everything BEFORE needle + * @return string + * @link http://php.net/manual/de/function.mb-strstr.php + * @link http://php.net/manual/de/function.strstr.php + */ + public static function strstr($haystack, $needle, $beforeNeedle = false) { + + if (!$beforeNeedle) { + if (self::_functionExists('mb_strstr')) { + return mb_strstr($haystack, $needle); + } else { + return strstr($haystack, $needle); + } + } else { + return strtok($haystack, $needle); + } + } + + /** + * This function checks if a given format is accepted by php's date function. + * + * @param string $format + * format according to date function specification + * @return bool + * true if format is correct, false otherwise + */ + public static function validateDateFormat($format) { + // try to create a DateTime instance based on php's date function format specification + // return true if date is valid (no wrong format) + return false !== DateTime::createFromFormat($format, date($format, time())); + } + + /** + * Extract a number from a string. + * + * @param string $string + * String var by reference + * @return string + */ + public static function extractNumber(&$string) { + $string = preg_replace('/[^0-9]/', '', $string); + return $string; + } + + + /** + * Returns whether a string is UTF-8 encoded or not. + * + * @param string $input + * @return bool + */ + public static function isUtf8($input) { + $len = parent::getStringLength($input); + + for ($i = 0; $i < $len; $i++) { + $char = ord($input[$i]); + + if ($char < 0x80) { + // ASCII char + continue; + } else if (($char & 0xE0) === 0xC0 && $char > 0xC1) { + // 2 byte long char + $n = 1; + } else if (($char & 0xF0) === 0xE0) { + // 3 byte long char + $n = 2; + } else if (($char & 0xF8) === 0xF0 && $char < 0xF5) { + // 4 byte long char + $n = 3; + } else { + return false; + } + + for ($j = 0; $j < $n; $j++) { + $i++; + + if ($i == $len || (ord($input[$i]) & 0xC0) !== 0x80) { + return false; + } + } + } + return true; + } + + + /** + * Checks if a value is alphanumeric. + * + * @param mixed $test + * Value to test + * @param bool $umlauts [optional] + * Use german umlauts + * @return bool + * Value is alphanumeric + */ + public static function isAlphanumeric($test, $umlauts = true) { + if ($umlauts == true) { + $match = "/^[a-z0-9ÄäÖöÜüß ]+$/i"; + } else { + $match = "/^[a-z0-9 ]+$/i"; + } + + return preg_match($match, $test); + } + + /** + * Trims a string to a given length and makes sure that all words up to + * $maxlen are preserved, without exceeding $maxlen. + * + * Warning: Currently, this function uses a regular ASCII-Whitespace to do + * the separation test. If you are using ' ' to create spaces, this + * function will fail. + * + * Example: + * $string = "This is a simple test"; + * echo cString::trimAfterWord($string, 15); + * + * This would output "This is a", since this function respects word + * boundaries and doesn't operate beyond the limit given by $maxlen. + * + * @param string $string + * The string to operate on + * @param int $maxlen + * The maximum number of characters + * @return string + * The resulting string + */ + public static function trimAfterWord($string, $maxlen) { + // If the string is smaller than the maximum lenght, it makes no sense to + // process it any further. Return it. + if (parent::getStringLength($string) < $maxlen) { + return $string; + } + + // If the character after the $maxlen position is a space, we can return + // the string until $maxlen. + if (parent::getPartOfString($string, $maxlen, 1) == ' ') { + return parent::getPartOfString($string, 0, $maxlen); + } + + // Cut the string up to $maxlen so we can use cString::findLastPos (reverse str position) + $cutted_string = parent::getPartOfString($string, 0, $maxlen); + + // Extract the end of the last word + $last_word_position = cString::findLastPos($cutted_string, ' '); + + return parent::getPartOfString($cutted_string, 0, $last_word_position); + } + + /** + * Trims a string to a specific length. + * + * If the string is longer than $maxlen, dots are inserted ("...") right + * before $maxlen. + * + * Example: + * $string = "This is a simple test"; + * echo cString::trimHard ($string, 15); + * + * This would output "This is a si...", since the string is longer than + * $maxlen and the resulting string matches 15 characters including the dots. + * + * @param string $string + * The string to operate on + * @param int $maxlen + * The maximum number of characters + * @param string $fillup [optional] + * @return string + * The resulting string + */ + public static function trimHard($string, $maxlen, $fillup = '...') { + // If the string is smaller than the maximum lenght, it makes no sense to + // process it any further. Return it. + if (parent::getStringLength($string) < $maxlen) { + return $string; + } + + // Calculate the maximum text length + $maximum_text_length = $maxlen - parent::getStringLength($fillup); + + // If text length is over zero cut it + if ($maximum_text_length > 0) { + if (preg_match('/(*UTF8)^.{0,' . $maximum_text_length . '}/', $string, $result_array)) { + $cutted_string = $result_array[0]; + } else if (preg_match('/^.{0,' . $maximum_text_length . '}/u', $string, $result_array)) { + $cutted_string = $result_array[0]; + } else { + $cutted_string = parent::getPartOfString($string, 0, $maximum_text_length); + } + } else { + $cutted_string = $string; + } + + // Append the fillup string + $cutted_string .= $fillup; + + return $cutted_string; + } + + /** + * Trims a string to a approximate length preserving sentence boundaries. + * + * The algorithm inside calculates the sentence length to the previous and + * next sentences. The distance to the next sentence which is smaller will + * be taken to trim the string to match the approximate length parameter. + * + * Example: + * + * $string = "This contains two sentences. "; + * $string .= "Lets play around with them. "; + * + * echo cString::trimSentence($string, 40); + * echo cString::trimSentence($string, 50); + * + * The first example would only output the first sentence, the second + * example both sentences. + * + * Explanation: + * + * To match the given max length closely, the function calculates the + * distance to the next and previous sentences. Using the maxlength of 40 + * characters, the distance to the previous sentence would be 8 characters, + * and to the next sentence it would be 19 characters. Therefore, only the + * previous sentence is displayed. + * + * The second example displays the second sentence also, since the distance + * to the next sentence is only 9 characters, but to the previous it is 18 + * characters. + * + * If you specify the boolean flag "$hard", the limit parameter creates a + * hard limit instead of calculating the distance. + * + * This function ensures that at least one sentence is returned. + * + * @param string $string + * The string to operate on + * @param int $approxlen + * The approximate number of characters + * @param bool $hard [optional] + * If true, use a hard limit for the number of characters + * @return string + * The resulting string + */ + public static function trimSentence($string, $approxlen, $hard = false) { + // If the string is smaller than the maximum lenght, it makes no sense to + // process it any further. Return it. + if (parent::getStringLength($string) < $approxlen) { + return $string; + } + + // Find out the start of the next sentence + $next_sentence_start = parent::findFirstPos($string, '.', $approxlen); + + // If there's no next sentence (somebody forgot the dot?), set it to the end + // of the string. + if ($next_sentence_start === false) { + $next_sentence_start = parent::getStringLength($string); + } + + // Cut the previous sentence so we can use cString::findLastPos + $previous_sentence_cutted = parent::getPartOfString($string, 0, $approxlen); + + // Get out the previous sentence start + $previous_sentence_start = cString::findLastPos($previous_sentence_cutted, '.'); + + // If the sentence doesn't contain a dot, use the text start. + if ($previous_sentence_start === false) { + $previous_sentence_start = 0; + } + + // If we have a hard limit, we only want to process everything before + // $approxlen + if (($hard == true) && ($next_sentence_start > $approxlen)) { + return parent::getPartOfString($string, 0, $previous_sentence_start + 1); + } + + // Calculate next and previous sentence distances + $distance_previous_sentence = $approxlen - $previous_sentence_start; + $distance_next_sentence = $next_sentence_start - $approxlen; + + // Sanity: Return at least one sentence. + $sanity = parent::getPartOfString($string, 0, $previous_sentence_start + 1); + + if (parent::findFirstPos($sanity, '.') === false) { + return parent::getPartOfString($string, 0, $next_sentence_start + 1); + } + + // Decide wether the next or previous sentence is nearer + if ($distance_previous_sentence > $distance_next_sentence) { + return parent::getPartOfString($string, 0, $next_sentence_start + 1); + } else { + return parent::getPartOfString($string, 0, $previous_sentence_start + 1); + } + } + + /** + * Converts diactritics to english characters whenever possible. + * + * For german umlauts, this function converts the umlauts to their ASCII + * equivalents (e.g. ä => ae). + * + * For more information about diacritics, refer to + * http://en.wikipedia.org/wiki/Diacritic + * + * For other languages, the diacritic marks are removed, if possible. + * + * @param string $string + * The string to operate on + * @param string $sourceEncoding [optional; default: UTF-8] + * The source encoding + * @param string $targetEncoding [optional; default: UTF-8] + * The target encoding + * + * @return string + * The resulting string + * @throws cInvalidArgumentException + */ + public static function replaceDiacritics($string, $sourceEncoding = 'UTF-8', $targetEncoding = 'UTF-8') { + if ($sourceEncoding != 'UTF-8') { + $string = self::recodeString($string, $sourceEncoding, "UTF-8"); + } + + // replace regular german umlauts and other common characters with + // diacritics + static $search, $replace; + if (!isset($search)) { + $search = array( + 'Ä', + 'Ö', + 'Ü', + 'ä', + 'ö', + 'ü', + 'ß', + 'Á', + 'À', + 'Â', + 'á', + 'à', + 'â', + 'É', + 'È', + 'Ê', + 'é', + 'è', + 'ê', + 'Í', + 'Ì', + 'Î', + 'í', + 'ì', + 'î', + 'Ó', + 'Ò', + 'Ô', + 'ó', + 'ò', + 'ô', + 'Ú', + 'Ù', + 'Û', + 'ú', + 'ù', + 'û' + ); + $replace = array( + 'Ae', + 'Oe', + 'Ue', + 'ae', + 'oe', + 'ue', + 'ss', + 'A', + 'A', + 'A', + 'a', + 'a', + 'a', + 'E', + 'E', + 'E', + 'e', + 'e', + 'e', + 'I', + 'I', + 'I', + 'i', + 'i', + 'i', + 'O', + 'O', + 'O', + 'o', + 'o', + 'o', + 'U', + 'U', + 'U', + 'u', + 'u', + 'u' + ); + } + $string = str_replace($search, $replace, $string); + + // TODO: Additional converting + + return self::recodeString($string, "UTF-8", $targetEncoding); + } + + /** + * Converts a string to another encoding. + * + * This function tries to detect which function to use (either recode or + * iconv). + * + * If $sourceEncoding and $targetEncoding are the same, this function + * returns immediately. + * + * For more information about encodings, refer to + * http://en.wikipedia.org/wiki/Character_encoding + * + * For more information about the supported encodings in recode, refer to + * http://www.delorie.com/gnu/docs/recode/recode_toc.html + * + * Note: depending on whether recode or iconv is used, the supported + * charsets differ. The following ones are commonly used and are most likely + * supported by both converters: + * + * - ISO-8859-1 to ISO-8859-15 + * - ASCII + * - UTF-8 + * + * @todo Check if the charset names are the same for both converters + * @todo Implement a converter and charset checker to ensure compilance. + * + * @param string $string + * The string to operate on + * @param string $sourceEncoding + * The source encoding + * @param string $targetEncoding + * The target encoding (if false, use source encoding) + * + * @return string + * The resulting string + * @throws cInvalidArgumentException + */ + public static function recodeString($string, $sourceEncoding, $targetEncoding) { + // If sourceEncoding and targetEncoding are the same, return + if (parent::toLowerCase($sourceEncoding) == parent::toLowerCase($targetEncoding)) { + return $string; + } + + // Check for the "recode" support + if (function_exists('recode')) { + $sResult = recode_string("$sourceEncoding..$targetEncoding", $string); + return $sResult; + } + + // Check for the "iconv" support + if (function_exists('iconv')) { + $sResult = iconv($sourceEncoding, $targetEncoding, $string); + return $sResult; + } + + // No charset converters found; return with warning + cWarning(__FILE__, __LINE__, 'cString::recodeString could not find either recode or iconv to do charset conversion.'); + return $string; + } + + /** + * Removes or converts all "evil" URL characters. + * + * This function removes or converts all characters which can make an URL + * invalid. + * + * Clean characters include: + * - All characters between 32 and 126 which are not alphanumeric and + * aren't one of the following: _-. + * + * @param string $string + * The string to operate on + * @param bool $replace [optional] + * If true, all "unclean" characters are replaced + * + * @return string + * The resulting string + * @throws cInvalidArgumentException + */ + public static function cleanURLCharacters($string, $replace = false) { + $string = self::replaceDiacritics($string); + $string = str_replace(' ', '-', $string); + $string = str_replace('/', '-', $string); + $string = str_replace('&', '-', $string); + $string = str_replace('+', '-', $string); + + $iStrLen = parent::getStringLength($string); + + $sResultString = ''; + + for ($i = 0; $i < $iStrLen; $i++) { + $sChar = parent::getPartOfString($string, $i, 1); + + if (preg_match('/^[a-z0-9]*$/i', $sChar) || $sChar == '-' || $sChar == '_' || $sChar == '.') { + $sResultString .= $sChar; + } else { + if ($replace == true) { + $sResultString .= '_'; + } + } + } + + return $sResultString; + } + + /** + * Normalizes line endings in passed string. + * + * @param string $string + * @param string $lineEnding [optional] + * Feasible values are "\n", "\r" or "\r\n" + * @return string + */ + public static function normalizeLineEndings($string, $lineEnding = "\n") { + if ($lineEnding !== "\n" && $lineEnding !== "\r" && $lineEnding !== "\r\n") { + $lineEnding = "\n"; + } + + $string = str_replace("\r\n", "\n", $string); + $string = str_replace("\r", "\n", $string); + if ($lineEnding !== "\n") { + $string = str_replace("\n", $lineEnding, $string); + } + + return $string; + } +} \ No newline at end of file diff --git a/conlite/classes/con2con/class.registry.php b/conlite/classes/con2con/class.registry.php index 7a52792..02e59bb 100644 --- a/conlite/classes/con2con/class.registry.php +++ b/conlite/classes/con2con/class.registry.php @@ -46,6 +46,36 @@ class cRegistry { return $cfg['path']['contenido_fullhtml']; } + /** + * Function which returns path after the last possible place changing via + * configuration file. + * The path point to the current client + * + * @author konstantinos.katikakis + * @return string + * path + */ + public static function getFrontendPath() { + $cfgClient = self::getClientConfig(); + $client = self::getClientId(); + return $cfgClient[$client]['path']['frontend']; + } + + /** + * Function which returns URL after the last possible place changing via + * configuration file. + * The path point to the current client + * + * @author konstantinos.katikakis + * @return string + * URL + */ + public static function getFrontendUrl() { + $cfgClient = self::getClientConfig(); + $client = self::getClientId(); + return $cfgClient[$client]['path']['htmlpath']; + } + /** * Returns the client configuration array stored in the global variable * "cfgClient". diff --git a/conlite/includes/include.logs.php b/conlite/includes/include.logs.php index 844f5f4..3fdf8c9 100644 --- a/conlite/includes/include.logs.php +++ b/conlite/includes/include.logs.php @@ -131,7 +131,7 @@ if(!$perm->have_perm_area_action($area)) } $years = array(); - for ($i = 2000; $i < 2020; $i++) + for ($i = 2000; $i < 2030; $i++) { $years[$i] = $i; }