Location: PHPKode > scripts > Transparent PHP AOP > transparent-php-aop/class.Weave.php
<?php


require_once "class.Aspect.php";
require_once "class.Advice.php";


class Weave
{
	var $_initialized;
	var $_lastModified;
	var $_aspects;
	var $_directories;


	function Weave()
	{
		$this->_aspects = array();
		$this->_directories = array();

		$this->_initialized = false;
		$this->_lastModified = 0;

		// Loading Aspects
		$numArgs = func_num_args();

		for ($i = 0; $i < $numArgs; $i++) {
			$arg = & func_get_arg($i);
			$this->_handleLoad($arg);
		}
	}


	function addAspect(& $aspect)
	{
		if (is_a($aspect, "Aspect")) {
			$this->_aspects[count($this->_aspects)] = & $aspect;

			// Analising the most recent last modified aspect
			if ($this->_lastModified < $aspect->getLastModified()) {
                $this->_lastModified = $aspect->getLastModified();
			}

			return true;
		}

		return false;
	}


	function & getAspect($i)
	{
    	if ($this->_initialized === false) {
			$this->init();
		}

		if (array_key_exists($i, $this->_aspects)) {
			return $this->_aspects[$i];
		}

		return null;
	}
	
	
	function & getAspects()
	{
		if ($this->_initialized === false) {
			$this->init();
		}

		return $this->_aspects;
	}


	function getInitialized() { return $this->_initialized; }

	function getLastModified() { return $this->_lastModified; }
	
	
	function hasAspects()
	{
    	// Provides an alternative to lazy load (not 100% effective)
		if ($this->_initialized === false) {
    		if (count($this->_directories) > 0) {
    			return true;
			}

			if (count($this->_aspects) > 0) {
				return true;
			}
    	}

    	return ($this->getLength() > 0) ? true : false;
	}
	
	
	function getLength()
	{
    	if ($this->_initialized === false) {
			$this->init();
		}
		
		return count($this->_aspects);
	}


	function init()
	{
		if (($l = count($this->_directories)) > 0) {
			for ($i = 0; $i < $l; $i++) {
				$pos = $this->_directories[$i]["position"];
				$dir = $this->_directories[$i]["directory"];
				
				$this->_loadDirectory($dir, $pos);
			}
		}

		// Lazy load flag change
		$this->_initialized = true;
	}
	
	
	function _loadDirectory($dir, & $pos = 0)
	{
    	// Open Directory Handle
		$handle = dir($dir);

		// Loop through each item
		while (false !== ($file = $handle->read())) {
			// If it is not an alias
			if ($file != "." && $file != "..") {
				$file = $dir . "/" . $file;

                // If it is a directory
				if (is_dir($file)) {
					$this->_loadDirectory($file, $pos);
				// If it is a file and a XAD
				} else {
					$path = pathinfo($file);
					$mime = mime_content_type($file);

					if (($mime != "" && $mime == "text/xml") ||
						(is_readable($file) && $path["extension"] == "xml")) {
						// Load the aspect.
						$aspect = & Aspect::from($file);
                        
						// Define it in Aspects list.
						// Position is relative to defined in Weave constructor.
						// array_splice does work when replacing with objects.
						// As stated in the manual, you have to embed the object in an array.
						array_splice($this->_aspects, $pos++, 0, array($aspect));
					}
				}
			}
		}

		// Close Directory Handle
		$handle->close();
	}


	function _handleLoad(& $item)
	{
		// If the given argument is an Aspect (Object)
		if (is_a($item, "Aspect")) {
			$this->addAspect($item);
		// If the given argument is an array of unknown itens
		} elseif (is_array($item)) {
			$l = count($item);

			for ($i = 0; $i < $l; $i++) {
				$arg = & $item[$i];
				$this->_handleLoad($arg);
			}
		// If the given argument is a directory
		} elseif (is_string($item) && is_dir($item)) {
			// One directory may contain more than one file.
			// Prevent server overhead by lazy loading directory's content.
			$i = count($this->_directories);

			$this->_directories[$i]["position"] = count($this->_aspects);
            $this->_directories[$i]["directory"] = realpath($item);

            // Analising the most recent last modified (can be a file)
            $lastMod = filemtime($this->_directories[$i]["directory"]);

			if ($this->_lastModified < $lastMod) {
                $this->_lastModified = $lastMod;
			}
		// If the given argument is a XAD
		} elseif (is_string($item) && is_file($item)) {
			// Load the Aspect
			$aspect = & Aspect::from($item);

			// Insert the Aspect into Weave
			$this->addAspect($aspect);
		}
	}


	// Addon
	function & getAdviceFromCustomPointcut($className, $functionName, $pointcutName)
	{
		$advice = & new Advice();
		
		$aspects = & $this->getAspects();
		$l = count($aspects);

		for ($i = 0; $i < $l; $i++) {
			$aspect = & $this->_aspects[$i];

			$a = & $aspect->getAdviceFromCustomPointcut(
				$className, $functionName, $pointcutName
			);

			$advice->addData($a->getData());
		}

		return $advice;
	}


	function & getAdviceFromAutoPointcut($className, $functionName, $autoPointcut)
	{
		$advice = & new Advice();
		
		$aspects = & $this->getAspects();
		$l = count($aspects);

		for ($i = 0; $i < $l; $i++) {
			$aspect = & $this->_aspects[$i];

			$a = & $aspect->getAdviceFromAutoPointcut(
				$className, $functionName, $autoPointcut
			);

			$advice->addData($a->getData());
		}

		return $advice;
	}
}

?>
Return current item: Transparent PHP AOP