load($path); // Parse threshold if (isset($properties[self::THRESHOLD_PREFIX])) { $this->config['threshold'] = $properties[self::THRESHOLD_PREFIX]; } // Parse root logger if (isset($properties[self::ROOT_LOGGER_PREFIX])) { $this->parseLogger($properties[self::ROOT_LOGGER_PREFIX], self::ROOT_LOGGER_NAME); } $appenders = array(); foreach($properties as $key => $value) { // Parse loggers if ($this->beginsWith($key, self::LOGGER_PREFIX)) { $name = substr($key, strlen(self::LOGGER_PREFIX)); $this->parseLogger($value, $name); } // Parse additivity if ($this->beginsWith($key, self::ADDITIVITY_PREFIX)) { $name = substr($key, strlen(self::ADDITIVITY_PREFIX)); $this->config['loggers'][$name]['additivity'] = $value; } // Parse appenders else if ($this->beginsWith($key, self::APPENDER_PREFIX)) { $this->parseAppender($key, $value); } // Parse renderers else if ($this->beginsWith($key, self::RENDERER_PREFIX)) { $this->parseRenderer($key, $value); } } return $this->config; } /** * Parses a logger definition. * * Loggers are defined in the following manner: *
	 * log4php.logger. = [], [, , ...] 
	 * 
* * @param string $value The configuration value (level and appender-refs). * @param string $name Logger name. */ private function parseLogger($value, $name) { // Value is divided by commas $parts = explode(',', $value); if (empty($value) || empty($parts)) { return; } // The first value is the logger level $level = array_shift($parts); // The remaining values are appender references $appenders = array(); while($appender = array_shift($parts)) { $appender = trim($appender); if (!empty($appender)) { $appenders[] = trim($appender); } } // Find the target configuration if ($name == self::ROOT_LOGGER_NAME) { $this->config['rootLogger']['level'] = trim($level); $this->config['rootLogger']['appenders'] = $appenders; } else { $this->config['loggers'][$name]['level'] = trim($level); $this->config['loggers'][$name]['appenders'] = $appenders; } } /** * Parses an configuration line pertaining to an appender. * * Parses the following patterns: * * Appender class: *
	 * log4php.appender. = 
	 * 
* * Appender parameter: *
	 * log4php.appender.. = 
	 * 
* * Appender threshold: *
	 * log4php.appender..threshold = 
	 * 
* * Appender layout: *
	 * log4php.appender..layout = 
	 * 
* * Layout parameter: *
	 * log4php.appender..layout. = 
	 * 
* * For example, a full appender config might look like: *
	 * log4php.appender.myAppender = LoggerAppenderConsole
	 * log4php.appender.myAppender.threshold = info
	 * log4php.appender.myAppender.target = stdout
	 * log4php.appender.myAppender.layout = LoggerLayoutPattern
	 * log4php.appender.myAppender.layout.conversionPattern = "%d %c: %m%n"
	 * 
* * After parsing all these options, the following configuration can be * found under $this->config['appenders']['myAppender']: *
	 * array(
	 * 	'class' => LoggerAppenderConsole,
	 * 	'threshold' => info,
	 * 	'params' => array(
	 * 		'target' => 'stdout'
	 * 	),
	 * 	'layout' => array(
	 * 		'class' => 'LoggerAppenderConsole',
	 * 		'params' => array(
	 * 			'conversionPattern' => '%d %c: %m%n'
	 * 		)
	 * 	)
	 * )
	 * 
* * @param string $key * @param string $value */ private function parseAppender($key, $value) { // Remove the appender prefix from key $subKey = substr($key, strlen(self::APPENDER_PREFIX)); // Divide the string by dots $parts = explode('.', $subKey); $count = count($parts); // The first part is always the appender name $name = trim($parts[0]); // Only one part - this line defines the appender class if ($count == 1) { $this->config['appenders'][$name]['class'] = $value; return; } // Two parts - either a parameter, a threshold or layout class else if ($count == 2) { if ($parts[1] == 'layout') { $this->config['appenders'][$name]['layout']['class'] = $value; return; } else if ($parts[1] == 'threshold') { $this->config['appenders'][$name]['threshold'] = $value; return; } else { $this->config['appenders'][$name]['params'][$parts[1]] = $value; return; } } // Three parts - this can only be a layout parameter else if ($count == 3) { if ($parts[1] == 'layout') { $this->config['appenders'][$name]['layout']['params'][$parts[2]] = $value; return; } } trigger_error("log4php: Don't know how to parse the following line: \"$key = $value\". Skipping."); } /** * Parses a renderer definition. * * Renderers are defined as: *
	 * log4php.renderer. =  
	 * 
* * @param string $key log4php.renderer. * @param string $value */ private function parseRenderer($key, $value) { // Remove the appender prefix from key $renderedClass = substr($key, strlen(self::APPENDER_PREFIX)); $renderingClass = $value; $this->config['renderers'][] = compact('renderedClass', 'renderingClass'); } /** Helper method. Returns true if $str begins with $sub. */ private function beginsWith($str, $sub) { return (strncmp($str, $sub, strlen($sub)) == 0); } }