* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup * @license http://code.google.com/p/php-reader/wiki/License New BSD License * @version $Rev: 108 $ */ abstract class ASF_Object_Container extends ASF_Object { /** @var Array */ private $_objects = array(); /** * Reads and constructs the objects found within this object. */ protected function constructObjects($defaultclassnames = array()) { while (true) { $offset = $this->_reader->getOffset(); if ($offset >= $this->getOffset() + $this->getSize()) break; $guid = $this->_reader->readGUID(); $size = $this->_reader->readInt64LE(); $this->_reader->setOffset($offset); if (isset($defaultclassnames[$guid])) { if (@fopen($filename = "ASF/Object/" . $defaultclassnames[$guid] . ".php", "r", true) !== false) require_once($filename); if (class_exists ($classname = "ASF_Object_" . $defaultclassnames[$guid])) $object = new $classname($this->_reader, $this->_options); else $object = new ASF_Object($this->_reader, $this->_options); } else $object = new ASF_Object($this->_reader, $this->_options); $object->setParent($this); if (!$this->hasObject($object->getIdentifier())) $this->_objects[$object->getIdentifier()] = array(); $this->_objects[$object->getIdentifier()][] = $object; $this->_reader->setOffset($offset + $size); } } /** * Checks whether the object with given GUID is present in the file. Returns * true if one or more objects are present, false * otherwise. * * @return boolean */ public function hasObject($identifier) { return isset($this->_objects[$identifier]); } /** * Returns all the objects the file contains as an associate array. The object * identifiers work as keys having an array of ASF objects as associated * value. * * @return Array */ public function getObjects() { return $this->_objects; } /** * Returns an array of objects matching the given object GUID or an empty * array if no object matched the identifier. * * The identifier may contain wildcard characters "*" and "?". The asterisk * matches against zero or more characters, and the question mark matches any * single character. * * Please note that one may also use the shorthand $obj->identifier to access * the first box with the identifier given. Wildcards cannot be used with * the shorthand and they will not work with user defined uuid types. * * @return Array */ public function getObjectsByIdentifier($identifier) { $matches = array(); $searchPattern = "/^" . str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; foreach ($this->_objects as $identifier => $objects) if (preg_match($searchPattern, $identifier)) foreach ($objects as $object) $matches[] = $object; return $matches; } /** * Adds a new object into the current object and returns it. * * @param ASF_Object The object to add * @return ASF_Object */ public function addObject($object) { $object->setParent($this); $object->setOptions($this->_options); if (!$this->hasObject($object->getIdentifier())) $this->_objects[$object->getIdentifier()] = array(); return $this->_objects[$object->getIdentifier()][] = $object; } /** * Override magic function so that $obj->value will work as expected. * * The method first attempts to call the appropriate getter method. If no * field with given name is found, the method attempts to return the right * object instead. In other words, calling $obj->value will attempt to return * the first object returned by $this->getObjectsByIdentifier(self::value). * * @param string $name The field or object name. * @return mixed */ public function __get($name) { if (method_exists($this, "get" . ucfirst($name))) return call_user_func(array($this, "get" . ucfirst($name))); if (defined($constname = get_class($this) . "::" . strtoupper (preg_replace("/[A-Z]/", "_$0", $name)))) { $objects = $this->getObjectsByIdentifier(constant($constname)); if (isset($objects[0])) return $objects[0]; } throw new ASF_Exception("Unknown field/object: " . $name); } /** * Magic function so that isset($obj->value) will work. This method checks * whether the object by given identifier is contained by this container. * * @param string $name The object name. * @return boolean */ public function __isset($name) { if (defined($constname = get_class($this) . "::" . strtoupper (preg_replace("/[A-Z]/", "_$0", $name)))) { $objects = $this->getObjectsByIdentifier(constant($constname)); return isset($objects[0]); } else return isset($this->_objects[$name]); } }