* @copyright 2007 - 2008 (C) by Wrzasq * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3 */ /** * Wrapper for monsters list. * * @package POT * @version 0.1.3 * @tutorial POT/data_directory.pkg#monsters */ class OTS_MonstersList implements Iterator, Countable, ArrayAccess { /** * Monsters directory. * * @var string */ private $monstersPath; /** * List of loaded monsters. * * @var array */ private $monsters = array(); private $lastMonsterFile = ''; private $hasErrors = false; /** * Loads monsters mapping file. * *

* Note: You pass directory path, not monsters.xml file name itself. *

* * @param string $path Monsters directory. * @throws DOMException On DOM operation error. */ public function __construct($path) { $this->monstersPath = $path; // makes sure it has directory separator at the end $last = substr($this->monstersPath, -1); if($last != '/' && $last != '\\') { $this->monstersPath .= '/'; } // check if monsters.xml exist if(!@file_exists($this->monstersPath . 'monsters.xml')) { log_append('error.log', '[OTS_MonstersList.php] Fatal error: Cannot load monsters.xml. File does not exist. (' . $this->monstersPath . 'monsters.xml' . ').'); throw new Exception('Error: Cannot load monsters.xml. File not found.'); } // loads monsters mapping file $monsters = new DOMDocument(); if(!@$monsters->load($this->monstersPath . 'monsters.xml')) { log_append('error.log', '[OTS_MonstersList.php] Fatal error: Cannot load monsters.xml (' . $this->monstersPath . 'monsters.xml' . '). Error: ' . print_r(error_get_last(), true)); throw new Exception('Error: Cannot load monsters.xml. File is invalid. More info in system/logs/error.log file.'); } foreach( $monsters->getElementsByTagName('monster') as $monster) { $this->monsters[ $monster->getAttribute('name') ] = $monster->getAttribute('file'); //echo $this->monsters[ $monster->getAttribute('name')]; } } /** * Magic PHP5 method. * * Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}. * * @param array $properties List of object properties. */ public static function __set_state($properties) { $object = new self(); // loads properties foreach($properties as $name => $value) { $object->$name = $value; } return $object; } /** * Checks if given monster ID exists on list. * * @version 0.1.3 * @since 0.1.3 * @param string $name Monster name. * @return bool If monster is set then true. */ public function hasMonster($name) { return isset($this->monsters[$name]); } function xmlErrorHandler($errno, $errstr, $errfile, $errline) { if($errno==E_WARNING && (substr_count($errstr,"DOMDocument::loadXML()")>0)) { //throw new DOMException($errstr); log_append('error.log', '[OTS_MonstersList.php] Fatal error: Cannot load ' . $this->lastMonsterFile . ' - ' . $errstr); $this->hasErrors = true; } else return false; } /** * Returns loaded data of given monster. * * @version 0.1.3 * @param string $name Monster name. * @return OTS_Monster Monster data. * @throws OutOfBoundsException If not exists. * @throws DOMException On DOM operation error. */ public function getMonster($name) { global $lastMonsterFile; // checks if monster exists if( isset($this->monsters[$name]) ) { // loads file $monster = new OTS_Monster(); //echo $this->monstersPath . $this->monsters[$name]; // check if monster file exist if(file_exists($this->monstersPath . $this->monsters[$name])) { set_error_handler(array($this, 'xmlErrorHandler')); $this->lastMonsterFile = $this->monstersPath . $this->monsters[$name]; @$monster->loadXML(trim(file_get_contents($this->monstersPath . $this->monsters[$name]))); restore_error_handler(); } return $monster; } throw new OutOfBoundsException(); } public function hasErrors() { return $this->hasErrors; } /** * Returns amount of monsters loaded. * * @return int Count of monsters. */ public function count(): int { return count($this->monsters); } /** * Returns monster at current position in iterator. * * @return OTS_Monster Monster. * @throws DOMException On DOM operation error. */ public function current() { return $this->getMonster( key($this->monsters) ); } public function currentFile() { return $this->monsters[key($this->monsters)]; } /** * Moves to next iterator monster. */ public function next() { next($this->monsters); } /** * Returns name of current position. * * @return string Current position key. */ public function key() { return key($this->monsters); } /** * Checks if there is anything more in interator. * * @return bool If iterator has anything more. */ public function valid() { return key($this->monsters) !== null; } /** * Resets iterator index. */ public function rewind() { reset($this->monsters); } /** * Checks if given element exists. * * @param string $offset Array key. * @return bool True if it's set. */ public function offsetExists($offset) { return isset($this->monsters[$offset]); } /** * Returns item from given position. * * @version 0.1.3 * @param string $offset Array key. * @return OTS_Monster Monster instance. * @throws DOMException On DOM operation error. */ public function offsetGet($offset) { return $this->getMonster($offset); } /** * This method is implemented for ArrayAccess interface. In fact you can't write/append to monsters list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise. * * @param string|int $offset Array key. * @param mixed $value Field value. * @throws E_OTS_ReadOnly Always - this class is read-only. */ public function offsetSet($offset, $value) { throw new E_OTS_ReadOnly(); } /** * This method is implemented for ArrayAccess interface. In fact you can't write/append to monsters list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise. * * @param string|int $offset Array key. * @throws E_OTS_ReadOnly Always - this class is read-only. */ public function offsetUnset($offset) { throw new E_OTS_ReadOnly(); } /** * Returns string representation of object. * *

* If any display driver is currently loaded then it uses it's method. *

* * @version 0.1.3 * @since 0.1.3 * @return string String representation of object. */ public function __toString() { $ots = POT::getInstance(); // checks if display driver is loaded if( $ots->isDataDisplayDriverLoaded() ) { return $ots->getDataDisplayDriver()->displayMonstersList($this); } return (string) $this->count(); } } /**#@-*/ ?>