/** * @covers \Erebot\DOM */ public function testValidationFailure() { $dom = new \Erebot\DOM(); $this->assertTrue($dom->load(__DIR__ . DIRECTORY_SEPARATOR . 'nok.xml')); $this->assertFalse($dom->relaxNGValidate(__DIR__ . DIRECTORY_SEPARATOR . 'test.rng')); $errors = $dom->getErrors(); $this->assertSame(1, count($errors)); // Inspect the error's contents. $this->assertSame(LIBXML_ERR_ERROR, $errors[0]->level); $this->assertSame('Wrong answer to life, the universe and everything', $errors[0]->message); $this->assertSame(__DIR__ . DIRECTORY_SEPARATOR . 'nok.xml', $errors[0]->file); $this->assertSame(2, $errors[0]->line); $this->assertSame('/Root', $errors[0]->path); }
/** * Parses a template into a DOM. * * \param string $source * Template to parse. * * \retval Erebot::DOM * DOM object constructed * from the template. * * \throw ::InvalidArgumentException * The template was malformed * or invalid. */ protected static function parseTemplate($source) { $source = '<msg xmlns="http://www.erebot.net/xmlns/erebot/styling">' . $source . '</msg>'; $schema = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'styling.rng'; $dom = new \Erebot\DOM(); $dom->substituteEntities = true; $dom->resolveExternals = false; $dom->recover = true; $ue = libxml_use_internal_errors(true); $dom->loadXML($source); $valid = $dom->relaxNGValidate($schema); $errors = $dom->getErrors(); libxml_use_internal_errors($ue); if (!$valid || count($errors)) { // Some unpredicted error occurred, // show some (hopefully) useful information. if (class_exists('\\Plop')) { $logger = \Plop::getInstance(); $logger->error(print_r($errors, true)); } throw new \InvalidArgumentException('Error while validating the message'); } return $dom; }
public function load($configData, $source) { $logger = \Plop\Plop::getInstance(); $possibleSources = array(self::LOAD_FROM_FILE, self::LOAD_FROM_STRING); if (!in_array($source, $possibleSources, true)) { throw new \Erebot\InvalidValueException('Invalid $source'); } if ($source == self::LOAD_FROM_FILE) { if (is_string($configData) && $configData != "") { if (!strncasecmp(PHP_OS, "Win", 3)) { if (!in_array($configData[0], array("/", "\\")) && strlen($configData) > 1 && $configData[1] != ":") { $configData = getcwd() . DIRECTORY_SEPARATOR . $configData; } } elseif ($configData[0] != DIRECTORY_SEPARATOR) { $configData = getcwd() . DIRECTORY_SEPARATOR . $configData; } $file = \Erebot\URI::fromAbsPath($configData, false); } elseif (is_object($configData) && $configData instanceof \Erebot\URIInterface) { $file = $configData; } else { throw new \Erebot\InvalidValueException("Invalid configuration file"); } } elseif (!is_string($configData)) { throw new \Erebot\InvalidValueException("Invalid configuration file"); } else { $file = null; } $mainSchema = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config.rng'; $mainSchema = file_get_contents($mainSchema); $ue = libxml_use_internal_errors(true); $domxml = new \Erebot\DOM(); if ($source == self::LOAD_FROM_FILE) { $domxml->load((string) $file); } else { $domxml->loadXML($configData); } $domxml->xinclude(LIBXML_NOBASEFIX); $this->stripXGlobWrappers($domxml); $ok = $domxml->relaxNGValidateSource($mainSchema); $errors = $domxml->getErrors(); libxml_use_internal_errors($ue); if (!$ok || count($errors)) { // Some unpredicted error occurred, // show some (hopefully) useful information. $logger->error(print_r($errors, true)); throw new \Erebot\InvalidValueException('Errors were found while validating the configuration file'); } $xml = simplexml_import_dom($domxml); parent::__construct($this, $xml); if (!isset($xml['version'])) { $this->version = null; } else { $this->version = (string) $xml['version']; } if (!isset($xml['timezone'])) { throw new \Erebot\InvalidValueException('No timezone defined'); } $this->timezone = (string) $xml['timezone']; // Set timezone information. // This is needed to configure the logging subsystem. if (function_exists('date_default_timezone_set')) { if (!date_default_timezone_set($this->timezone)) { throw \Erebot\InvalidValueException(sprintf('Invalid timezone: "%s"', $this->timezone)); } } $daemonize = isset($xml['daemon']) ? $this->parseBool((string) $xml['daemon']) : false; $userIdentity = isset($xml['uid']) ? (string) $xml['uid'] : null; $groupIdentity = isset($xml['gid']) ? (string) $xml['gid'] : null; $pidfile = isset($xml['pidfile']) ? (string) $xml['pidfile'] : null; if ($daemonize === null) { throw new \Erebot\InvalidValueException('Invalid "daemon" value'); } if (!isset($xml['commands-prefix'])) { $this->commandsPrefix = '!'; } else { $this->commandsPrefix = (string) $xml['commands-prefix']; if (strcspn($this->commandsPrefix, " \r\n\t") != strlen($this->commandsPrefix)) { throw new \Erebot\InvalidValueException('Invalid command prefix'); } } $logger->debug($this->coreTranslator->gettext('Loaded configuration data')); $this->networks = array(); foreach ($xml->networks->network as $netCfg) { /// @TODO use dependency injection instead. $newConfig = new \Erebot\Config\Network($this, $netCfg); $this->networks[$newConfig->getName()] = $newConfig; unset($newConfig); } if ($source == self::LOAD_FROM_FILE) { $this->configFile = $configData; } else { $this->configFile = null; } // Default values. $this->daemonize = $daemonize; $this->userIdentity = $userIdentity; $this->groupIdentity = $groupIdentity; $this->pidfile = $pidfile; }