Location: PHPKode > scripts > Lagger > library/Lagger/Handler.php
<?php

/**
 *
 * @see http://code.google.com/p/lagger
 * @author Barbushin Sergey http://www.linkedin.com/in/barbushin
 *
 */
abstract class Lagger_Handler {

	protected $eventspace;
	protected $actions = array();
	protected $currentAction;
	protected $handling;
	public static $skipNexInternalException;
	protected static $internalErrorsActions = array();

	const tagSeparator = ',';

	public function __construct(Lagger_Eventspace $eventspace) {
		$this->eventspace = $eventspace;
		$this->init();
	}

	protected function init() {
	}

	public function getEventspace() {
		return $this->eventspace;
	}

	public function addAction(Lagger_Action $action, $tags = null, Lagger_Tagger $tagger = null) {
		if($tagger && $tagger->tagsRewrited()) {
			$tags = $tagger->getNewTags();
		}
		if($tags === '') {
			$tags = null;
		}
		if($tags || $tags === null) {
			$incTags = null;
			$excTags = null;
			self::parseActionTagsString($tags, $incTags, $excTags);
			$this->actions[] = array('object' => $action, 'included_tags' => $incTags, 'excluded_tags' => $excTags);
		}
		return $this;
	}

	protected static function convertTraceToString($traceData, $eventFile = null, $eventLine = null) {
		$trace = array();
		foreach($traceData as $i => $call) {
			if((isset($call['class']) && strpos($call['class'], 'Lagger_') === 0) || (!$trace && isset($call['file']) && $call['file'] == $eventFile && $call['line'] == $eventLine)) {
				$trace = array();
				continue;
			}
			$args = array();
			if(isset($call['args'])) {
				foreach($call['args'] as $arg) {
					if(is_object($arg)) {
						$args[] = get_class($arg);
					}
					elseif(is_array($arg)) {
						$args[] = 'Array';
					}
					else {
						$arg = var_export($arg, 1);
						$args[] = strlen($arg) > 12 ? substr($arg, 0, 8) . '...\'' : $arg;
					}
				}
			}
			$trace[] = (isset($call['file']) ? ($call['file'] . ':' . $call['line']) : '[internal call]') . ' - ' . (isset($call['class']) ? $call['class'] . $call['type'] : '') . $call['function'] . '(' . implode(', ', $args) . ')';
		}
		$trace = array_reverse($trace);
		foreach($trace as $i => &$call) {
			$call = '#' . ($i + 1) . ' ' . $call;
		}
		return implode("\n", $trace);
	}

	protected static function parseActionTagsString($tagsString, &$incTags, &$excTags = array()) {
		if(preg_match_all('/(-(\w+))|(\w+)/', $tagsString, $matches)) {
			foreach($matches[3] as $i => $incTag) {
				if($incTag === '') {
					$excTags[] = $matches[2][$i];
				}
				else {
					$incTags[] = $incTag;
				}
			}
		}
	}

	protected static function parseEventTagsString($tagsString) {
		return array_map('trim', explode(self::tagSeparator, $tagsString));
	}

	protected function handleActions(array $eventVars, $eventTags = null) {
		if(!$this->handling) { // TODO: require some handler for internal Lagger errors
			$this->handling = true;
			$eventVars['tags'] = $eventTags;
			if(!isset($eventVars['handler'])) {
				$eventVars['handler'] = get_class($this);
			}
			$this->eventspace->resetVarsValues($eventVars);
			$throwException = null;
			foreach($this->getActionsByTags($eventTags) as $action) {
				try {
					$this->currentAction = $action['object'];
					$action['object']->callMake($this->eventspace);
				}
				catch(Exception $e) {
					if(self::$skipNexInternalException) {
						self::$skipNexInternalException = false;
						$throwException = $e;
					}
					else {
						self::handleInternalError($this->eventspace, get_class($e), 'There is internal error during handling "' . get_class($this->currentAction) . '": ' . print_r($e, true));
					}
				}
			}
			$this->handling = false;
			if($throwException) {
				throw $throwException;
			}
		}
	}

	protected function getActionsByTags($eventTagsString) {
		$actions = array();
		$eventTags = self::parseEventTagsString($eventTagsString);
		foreach($this->actions as $action) {
			if($this->isTagsMatches($eventTags, $action['included_tags'], $action['excluded_tags'])) {
				$actions[] = $action;
			}
		}
		return $actions;
	}

	protected function isTagsMatches($eventTags, $incTags, $excTags) {
		return (!$excTags || !array_intersect($eventTags, $excTags)) && (!$incTags || array_intersect($incTags, $eventTags));
	}

	/**************************************************************
	INTERNAL ERROR HANDLING
	 **************************************************************/

	public static function addInternalErrorAction(Lagger_Action $action) {
		self::$internalErrorsActions[] = $action;
	}

	protected static function handleInternalError(Lagger_Eventspace $eventspace, $type, $message) {
		$newEventspace = clone $eventspace;
		$eventVars = array('message' => $message, 'type' => $type);
		$newEventspace->resetVarsValues($eventVars);
		foreach(self::$internalErrorsActions as $action) {
			$action->callMake($newEventspace);
		}
	}

	public function __destruct() {
		if($this->handling) {
			self::handleInternalError($this->eventspace, 'LAGGER_INTERNAL_FATAL', 'Unkown internal FATAL error in handling "' . get_class($this->currentAction) . '"');
		}
	}
}
Return current item: Lagger