myaac/system/libs/pot/OTS_MonstersList.php
slawkens1 66a3c46aaf * better error handling for monsters and spells loader
* check if file exist before loading
* save errors to system/logs/error.log
2017-10-16 23:31:28 +02:00

298 lines
7.3 KiB
PHP

<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @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.
*
* <p>
* Note: You pass directory path, not monsters.xml file name itself.
* </p>
*
* @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' . '). Error: ' . print_r(error_get_last(), true));
throw new Exception('Error: Cannot load monsters.xml. File not found. More info in system/logs/error.log file.');
}
// 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 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()
{
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.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @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();
}
}
/**#@-*/
?>