/lib/log4php/helpers/LoggerOptionConverter.php
PHP | 445 lines | 209 code | 44 blank | 192 comment | 72 complexity | b5db311d51fa6dece9c8e42510a0a500 MD5 | raw file
- <?php
- /**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @package log4php
- */
- /**
- * A convenience class to convert property values to specific types.
- *
- * @version $Revision: 31 $
- * @package log4php
- * @subpackage helpers
- * @since 0.5
- */
- class LoggerOptionConverter {
- const DELIM_START = '${';
- const DELIM_STOP = '}';
- const DELIM_START_LEN = 2;
- const DELIM_STOP_LEN = 1;
-
- /** String values which are converted to boolean TRUE. */
- private static $trueValues = array('1', 'true', 'yes', 'on');
-
- /** String values which are converted to boolean FALSE. */
- private static $falseValues = array('0', 'false', 'no', 'off');
-
- /**
- * Read a predefined var.
- *
- * It returns a value referenced by <var>$key</var> using this search criteria:
- * - if <var>$key</var> is a constant then return it. Else
- * - if <var>$key</var> is set in <var>$_ENV</var> then return it. Else
- * - return <var>$def</var>.
- *
- * @param string $key The key to search for.
- * @param string $def The default value to return.
- * @return string the string value of the system property, or the default
- * value if there is no property with that key.
- */
- public static function getSystemProperty($key, $def) {
- if(defined($key)) {
- return (string)constant($key);
- } else if(isset($_SERVER[$key])) {
- return (string)$_SERVER[$key];
- } else if(isset($_ENV[$key])) {
- return (string)$_ENV[$key];
- } else {
- return $def;
- }
- }
- /**
- * If <var>$value</var> is <i>true</i>, then <i>true</i> is
- * returned. If <var>$value</var> is <i>false</i>, then
- * <i>true</i> is returned. Otherwise, <var>$default</var> is
- * returned.
- *
- * <p>Case of value is unimportant.</p>
- *
- * @param string $value
- * @param boolean $default
- * @return boolean
- */
- public static function toBoolean($value, $default=true) {
- if (is_null($value)) {
- return $default;
- } elseif (is_string($value)) {
- $trimmedVal = strtolower(trim($value));
- if("1" == $trimmedVal or "true" == $trimmedVal or "yes" == $trimmedVal or "on" == $trimmedVal) {
- return true;
- } else if ("" == $trimmedVal or "0" == $trimmedVal or "false" == $trimmedVal or "no" == $trimmedVal or "off" == $trimmedVal) {
- return false;
- }
- } elseif (is_bool($value)) {
- return $value;
- } elseif (is_int($value)) {
- return !($value == 0); // true is everything but 0 like in C
- }
-
- return $default;
- }
- /** Converts $value to boolean, or throws an exception if not possible. */
- public static function toBooleanEx($value) {
- if (isset($value)) {
- if (is_bool($value)) {
- return $value;
- }
- $value = strtolower(trim($value));
- if (in_array($value, self::$trueValues)) {
- return true;
- }
- if (in_array($value, self::$falseValues)) {
- return false;
- }
- }
-
- throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to boolean.");
- }
-
- /**
- * @param string $value
- * @param integer $default
- * @return integer
- */
- public static function toInt($value, $default) {
- $value = trim($value);
- if(is_numeric($value)) {
- return (int)$value;
- } else {
- return $default;
- }
- }
-
-
- /**
- * Converts $value to integer, or throws an exception if not possible.
- * Floats cannot be converted to integer.
- */
- public static function toIntegerEx($value) {
- if (is_integer($value)) {
- return $value;
- }
- if (is_numeric($value) && ($value == (integer) $value)) {
- return (integer) $value;
- }
-
- throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to integer.");
- }
-
- /**
- * Converts $value to integer, or throws an exception if not possible.
- * Floats cannot be converted to integer.
- */
- public static function toPositiveIntegerEx($value) {
- if (is_integer($value) && $value > 0) {
- return $value;
- }
- if (is_numeric($value) && ($value == (integer) $value) && $value > 0) {
- return (integer) $value;
- }
-
- throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a positive integer.");
- }
- /**
- * Converts a standard or custom priority level to a Level
- * object.
- *
- * <p> If <var>$value</var> is of form "<b>level#full_file_classname</b>",
- * where <i>full_file_classname</i> means the class filename with path
- * but without php extension, then the specified class' <i>toLevel()</i> method
- * is called to process the specified level string; if no '#'
- * character is present, then the default {@link LoggerLevel}
- * class is used to process the level value.</p>
- *
- * <p>As a special case, if the <var>$value</var> parameter is
- * equal to the string "NULL", then the value <i>null</i> will
- * be returned.</p>
- *
- * <p>If any error occurs while converting the value to a level,
- * the <var>$defaultValue</var> parameter, which may be
- * <i>null</i>, is returned.</p>
- *
- * <p>Case of <var>$value</var> is insignificant for the level level, but is
- * significant for the class name part, if present.</p>
- *
- * @param string $value
- * @param LoggerLevel $defaultValue
- * @return LoggerLevel a {@link LoggerLevel} or null
- */
- public static function toLevel($value, $defaultValue) {
- if($value === null) {
- return $defaultValue;
- }
- $hashIndex = strpos($value, '#');
- if($hashIndex === false) {
- if("NULL" == strtoupper($value)) {
- return null;
- } else {
- // no class name specified : use standard Level class
- return LoggerLevel::toLevel($value, $defaultValue);
- }
- }
- $result = $defaultValue;
- $clazz = substr($value, ($hashIndex + 1));
- $levelName = substr($value, 0, $hashIndex);
- // This is degenerate case but you never know.
- if("NULL" == strtoupper($levelName)) {
- return null;
- }
- $clazz = basename($clazz);
- if(class_exists($clazz)) {
- $result = @call_user_func(array($clazz, 'toLevel'), $levelName, $defaultValue);
- if(!$result instanceof LoggerLevel) {
- $result = $defaultValue;
- }
- }
- return $result;
- }
-
-
- /** Converts the value to a level. Throws an exception if not possible. */
- public static function toLevelEx($value) {
- if ($value instanceof LoggerLevel) {
- return $value;
- }
- $level = LoggerLevel::toLevel($value);
- if ($level === null) {
- throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a logger level.");
- }
- return $level;
- }
- /**
- * @param string $value
- * @param float $default
- * @return float
- */
- public static function toFileSize($value, $default) {
- if($value === null) {
- return $default;
- }
- $s = strtoupper(trim($value));
- $multiplier = (float)1;
- if(($index = strpos($s, 'KB')) !== false) {
- $multiplier = 1024;
- $s = substr($s, 0, $index);
- } else if(($index = strpos($s, 'MB')) !== false) {
- $multiplier = 1024 * 1024;
- $s = substr($s, 0, $index);
- } else if(($index = strpos($s, 'GB')) !== false) {
- $multiplier = 1024 * 1024 * 1024;
- $s = substr($s, 0, $index);
- }
- if(is_numeric($s)) {
- return (float)$s * $multiplier;
- }
- return $default;
- }
-
- /**
- * Converts a value to a valid file size (integer).
- *
- * Supports 'KB', 'MB' and 'GB' suffixes, where KB = 1024 B etc.
- *
- * The final value will be rounded to the nearest integer.
- *
- * Examples:
- * - '100' => 100
- * - '100.12' => 100
- * - '100KB' => 102400
- * - '1.5MB' => 1572864
- *
- * @param mixed $value File size (optionally with suffix).
- * @return integer Parsed file size.
- */
- public static function toFileSizeEx($value) {
-
- if (empty($value)) {
- throw new LoggerException("Empty value cannot be converted to a file size.");
- }
-
- if (is_numeric($value)) {
- return (integer) $value;
- }
-
- if (!is_string($value)) {
- throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a file size.");
- }
-
- $str = strtoupper(trim($value));
- $count = preg_match('/^([0-9.]+)(KB|MB|GB)?$/', $str, $matches);
-
- if ($count > 0) {
- $size = $matches[1];
- $unit = $matches[2];
-
- switch($unit) {
- case 'KB': $size *= pow(1024, 1); break;
- case 'MB': $size *= pow(1024, 2); break;
- case 'GB': $size *= pow(1024, 3); break;
- }
-
- return (integer) $size;
- }
-
- throw new LoggerException("Given value [$value] cannot be converted to a file size.");
- }
- /**
- * Converts a value to string, or throws an exception if not possible.
- *
- * Objects can be converted to string if they implement the magic
- * __toString() method.
- *
- */
- public static function toStringEx($value) {
- if (is_string($value)) {
- return $value;
- }
- if (is_numeric($value)) {
- return (string) $value;
- }
- if (is_object($value) && method_exists($value, '__toString')) {
- return (string) $value;
- }
-
- throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to string.");
- }
-
-
- /**
- * Find the value corresponding to <var>$key</var> in
- * <var>$props</var>. Then perform variable substitution on the
- * found value.
- *
- * @param string $key
- * @param array $props
- * @return string
- */
- public static function findAndSubst($key, $props) {
- $value = @$props[$key];
- // If coming from the LoggerConfiguratorIni, some options were
- // already mangled by parse_ini_file:
- //
- // not specified => never reaches this code
- // ""|off|false|null => string(0) ""
- // "1"|on|true => string(1) "1"
- // "true" => string(4) "true"
- // "false" => string(5) "false"
- //
- // As the integer 1 and the boolean true are therefore indistinguable
- // it's up to the setter how to deal with it, they can not be cast
- // into a boolean here. {@see toBoolean}
- // Even an empty value has to be given to the setter as it has been
- // explicitly set by the user and is different from an option which
- // has not been specified and therefore keeps its default value.
- //
- // if(!empty($value)) {
- return LoggerOptionConverter::substVars($value, $props);
- // }
- }
- /**
- * Perform variable substitution in string <var>$val</var> from the
- * values of keys found with the {@link getSystemProperty()} method.
- *
- * <p>The variable substitution delimeters are <b>${</b> and <b>}</b>.
- *
- * <p>For example, if the "MY_CONSTANT" contains "value", then
- * the call
- * <code>
- * $s = LoggerOptionConverter::substVars("Value of key is ${MY_CONSTANT}.");
- * </code>
- * will set the variable <i>$s</i> to "Value of key is value.".</p>
- *
- * <p>If no value could be found for the specified key, then the
- * <var>$props</var> parameter is searched, if the value could not
- * be found there, then substitution defaults to the empty string.</p>
- *
- * <p>For example, if {@link getSystemProperty()} cannot find any value for the key
- * "inexistentKey", then the call
- * <code>
- * $s = LoggerOptionConverter::substVars("Value of inexistentKey is [${inexistentKey}]");
- * </code>
- * will set <var>$s</var> to "Value of inexistentKey is []".</p>
- *
- * <p>A warn is thrown if <var>$val</var> contains a start delimeter "${"
- * which is not balanced by a stop delimeter "}" and an empty string is returned.</p>
- *
- * @param string $val The string on which variable substitution is performed.
- * @param array $props
- * @return string
- */
- // TODO: this method doesn't work correctly with key = true, it needs key = "true" which is odd
- public static function substVars($val, $props = null) {
- $sbuf = '';
- $i = 0;
- while(true) {
- $j = strpos($val, self::DELIM_START, $i);
- if($j === false) {
- // no more variables
- if($i == 0) { // this is a simple string
- return $val;
- } else { // add the tail string which contails no variables and return the result.
- $sbuf .= substr($val, $i);
- return $sbuf;
- }
- } else {
-
- $sbuf .= substr($val, $i, $j-$i);
- $k = strpos($val, self::DELIM_STOP, $j);
- if($k === false) {
- // LoggerOptionConverter::substVars() has no closing brace. Opening brace
- return '';
- } else {
- $j += self::DELIM_START_LEN;
- $key = substr($val, $j, $k - $j);
- // first try in System properties
- $replacement = LoggerOptionConverter::getSystemProperty($key, null);
- // then try props parameter
- if($replacement == null and $props !== null) {
- $replacement = @$props[$key];
- }
- if(!empty($replacement)) {
- // Do variable substitution on the replacement string
- // such that we can solve "Hello ${x2}" as "Hello p1"
- // the where the properties are
- // x1=p1
- // x2=${x1}
- $recursiveReplacement = LoggerOptionConverter::substVars($replacement, $props);
- $sbuf .= $recursiveReplacement;
- }
- $i = $k + self::DELIM_STOP_LEN;
- }
- }
- }
- }
- }