      1: <?php
      2: /**
      3:  * Licensed to the Apache Software Foundation (ASF) under one or more
      4:  * contributor license agreements. See the NOTICE file distributed with
      5:  * this work for additional information regarding copyright ownership.
      6:  * The ASF licenses this file to You under the Apache License, Version 2.0
      7:  * (the "License"); you may not use this file except in compliance with
      8:  * the License. You may obtain a copy of the License at
      9:  *
     10:  *     http://www.apache.org/licenses/LICENSE-2.0
     11:  *
     12:  * Unless required by applicable law or agreed to in writing, software
     13:  * distributed under the License is distributed on an "AS IS" BASIS,
     14:  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15:  * See the License for the specific language governing permissions and
     16:  * limitations under the License.
     17:  *
     18:  * @package log4php
     19:  */
     20:
     21: /**
     22:  * A convenience class to convert property values to specific types.
     23:  *
     24:  * @version $Revision: 1374617 $
     25:  * @package log4php
     26:  * @subpackage helpers
     27:  * @since 0.5
     28:  */
     29: class LoggerOptionConverter {
     30:
     31:     /** String values which are converted to boolean TRUE. */
     32:     private static $trueValues = array('1', 'true', 'yes', 'on');
     33:
     34:     /**
     35:      * String values which are converted to boolean FALSE.
     36:      *
     37:      * Note that an empty string must convert to false, because
     38:      * parse_ini_file() which is used for parsing configuration
     39:      * converts the value _false_ to an empty string.
     40:      */
     41:     private static $falseValues = array('0', 'false', 'no', 'off', '');
     42:
     43:     /**
     44:      * Read a predefined var.
     45:      *
     46:      * It returns a value referenced by <var>$key</var> using this search criteria:
     47:      * - if <var>$key</var> is a constant then return it. Else
     48:      * - if <var>$key</var> is set in <var>$_ENV</var> then return it. Else
     49:      * - return <var>$def</var>.
     50:      *
     51:      * @param string $key The key to search for.
     52:      * @param string $def The default value to return.
     53:      * @return string   the string value of the system property, or the default
     54:      *                  value if there is no property with that key.
     55:      */
     56:     public static function getSystemProperty($key, $def) {
     57:         if(defined($key)) {
     58:             return (string)constant($key);
     59:         } else if(isset($_SERVER[$key])) {
     60:             return (string)$_SERVER[$key];
     61:         } else if(isset($_ENV[$key])) {
     62:             return (string)$_ENV[$key];
     63:         } else {
     64:             return $def;
     65:         }
     66:     }
     67:
     68:     /** Converts $value to boolean, or throws an exception if not possible. */
     69:     public static function toBooleanEx($value) {
     70:         if (isset($value)) {
     71:             if (is_bool($value)) {
     72:                 return $value;
     73:             }
     74:             $value = strtolower(trim($value));
     75:             if (in_array($value, self::$trueValues)) {
     76:                 return true;
     77:             }
     78:             if (in_array($value, self::$falseValues)) {
     79:                 return false;
     80:             }
     81:         }
     82:
     83:         throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to boolean.");
     84:     }
     85:
     86:     /**
     87:      * Converts $value to integer, or throws an exception if not possible.
     88:      * Floats cannot be converted to integer.
     89:      */
     90:     public static function toIntegerEx($value) {
     91:         if (is_integer($value)) {
     92:             return $value;
     93:         }
     94:         if (is_numeric($value) && ($value == (integer) $value)) {
     95:             return (integer) $value;
     96:         }
     97:
     98:         throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to integer.");
     99:     }
    100:
    101:     /**
    102:      * Converts $value to integer, or throws an exception if not possible.
    103:      * Floats cannot be converted to integer.
    104:      */
    105:     public static function toPositiveIntegerEx($value) {
    106:         if (is_integer($value) && $value > 0) {
    107:             return $value;
    108:         }
    109:         if (is_numeric($value) && ($value == (integer) $value) && $value > 0) {
    110:             return (integer) $value;
    111:         }
    112:
    113:         throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a positive integer.");
    114:     }
    115:
    116:     /** Converts the value to a level. Throws an exception if not possible. */
    117:     public static function toLevelEx($value) {
    118:         if ($value instanceof LoggerLevel) {
    119:             return $value;
    120:         }
    121:         $level = LoggerLevel::toLevel($value);
    122:         if ($level === null) {
    123:             throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a logger level.");
    124:         }
    125:         return $level;
    126:     }
    127:
    128:     /**
    129:      * Converts a value to a valid file size (integer).
    130:      *
    131:      * Supports 'KB', 'MB' and 'GB' suffixes, where KB = 1024 B etc.
    132:      *
    133:      * The final value will be rounded to the nearest integer.
    134:      *
    135:      * Examples:
    136:      * - '100' => 100
    137:      * - '100.12' => 100
    138:      * - '100KB' => 102400
    139:      * - '1.5MB' => 1572864
    140:      *
    141:      * @param mixed $value File size (optionally with suffix).
    142:      * @return integer Parsed file size.
    143:      */
    144:     public static function toFileSizeEx($value) {
    145:
    146:         if (empty($value)) {
    147:             throw new LoggerException("Empty value cannot be converted to a file size.");
    148:         }
    149:
    150:         if (is_numeric($value)) {
    151:             return (integer) $value;
    152:         }
    153:
    154:         if (!is_string($value)) {
    155:             throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to a file size.");
    156:         }
    157:
    158:         $str = strtoupper(trim($value));
    159:         $count = preg_match('/^([0-9.]+)(KB|MB|GB)?$/', $str, $matches);
    160:
    161:         if ($count > 0) {
    162:             $size = $matches[1];
    163:             $unit = $matches[2];
    164:
    165:             switch($unit) {
    166:                 case 'KB': $size *= pow(1024, 1); break;
    167:                 case 'MB': $size *= pow(1024, 2); break;
    168:                 case 'GB': $size *= pow(1024, 3); break;
    169:             }
    170:
    171:             return (integer) $size;
    172:         }
    173:
    174:         throw new LoggerException("Given value [$value] cannot be converted to a file size.");
    175:     }
    176:
    177:     /**
    178:      * Converts a value to string, or throws an exception if not possible.
    179:      *
    180:      * Objects can be converted to string if they implement the magic
    181:      * __toString() method.
    182:      *
    183:      */
    184:     public static function toStringEx($value) {
    185:         if (is_string($value)) {
    186:             return $value;
    187:         }
    188:         if (is_numeric($value)) {
    189:             return (string) $value;
    190:         }
    191:         if (is_object($value) && method_exists($value, '__toString')) {
    192:             return (string) $value;
    193:         }
    194:
    195:         throw new LoggerException("Given value [" . var_export($value, true) . "] cannot be converted to string.");
    196:     }
    197:
    198:     /**
    199:      * Performs value substitution for string options.
    200:      *
    201:      * An option can contain PHP constants delimited by '${' and '}'.
    202:      *
    203:      * E.g. for input string "some ${FOO} value", the method will attempt
    204:      * to substitute ${FOO} with the value of constant FOO if it exists.
    205:      *
    206:      * Therefore, if FOO is a constant, and it has value "bar", the resulting
    207:      * string will be "some bar value".
    208:      *
    209:      * If the constant is not defined, it will be replaced by an empty string,
    210:      * and the resulting string will be "some  value".
    211:      *
    212:      * @param string $string String on which to perform substitution.
    213:      * @return string
    214:      */
    215:     public static function substConstants($string) {
    216:         preg_match_all('/\${([^}]+)}/', $string, $matches);
    217:
    218:         foreach($matches[1] as $key => $match) {
    219:             $match = trim($match);
    220:             $search = $matches[0][$key];
    221:             $replacement = defined($match) ? constant($match) : '';
    222:             $string = str_replace($search, $replacement, $string);
    223:         }
    224:         return $string;
    225:     }
    226: }
    227: