File: /var/www/payments-gateway/vendor/doctrine/migrations/src/Configuration/Migration/XmlFile.php
<?php
declare(strict_types=1);
namespace Doctrine\Migrations\Configuration\Migration;
use Doctrine\Migrations\Configuration\Configuration;
use Doctrine\Migrations\Configuration\Exception\FileNotFound;
use Doctrine\Migrations\Configuration\Migration\Exception\XmlNotValid;
use Doctrine\Migrations\Tools\BooleanStringFormatter;
use DOMDocument;
use SimpleXMLElement;
use function assert;
use function file_exists;
use function file_get_contents;
use function libxml_clear_errors;
use function libxml_use_internal_errors;
use function simplexml_load_string;
use function strtr;
use const DIRECTORY_SEPARATOR;
use const LIBXML_NOCDATA;
final class XmlFile extends ConfigurationFile
{
public function getConfiguration(): Configuration
{
if (! file_exists($this->file)) {
throw FileNotFound::new($this->file);
}
$this->validateXml($this->file);
$rawXML = file_get_contents($this->file);
assert($rawXML !== false);
$root = simplexml_load_string($rawXML, SimpleXMLElement::class, LIBXML_NOCDATA);
assert($root !== false);
$config = $this->extractParameters($root, true);
if (isset($config['all_or_nothing'])) {
$config['all_or_nothing'] = BooleanStringFormatter::toBoolean(
$config['all_or_nothing'],
false,
);
}
if (isset($config['transactional'])) {
$config['transactional'] = BooleanStringFormatter::toBoolean(
$config['transactional'],
true,
);
}
if (isset($config['migrations_paths'])) {
$config['migrations_paths'] = $this->getDirectoriesRelativeToFile(
$config['migrations_paths'],
$this->file,
);
}
return (new ConfigurationArray($config))->getConfiguration();
}
/** @return mixed[] */
private function extractParameters(SimpleXMLElement $root, bool $loopOverNodes): array
{
$config = [];
$itemsToCheck = $loopOverNodes ? $root->children() : $root->attributes();
if (! ($itemsToCheck instanceof SimpleXMLElement)) {
return $config;
}
foreach ($itemsToCheck as $node) {
$nodeName = strtr($node->getName(), '-', '_');
if ($nodeName === 'migrations_paths') {
$config['migrations_paths'] = [];
foreach ($node->path as $pathNode) {
$config['migrations_paths'][(string) $pathNode['namespace']] = (string) $pathNode;
}
} elseif ($nodeName === 'storage' && $node->{'table-storage'} instanceof SimpleXMLElement) {
$config['table_storage'] = $this->extractParameters($node->{'table-storage'}, false);
} elseif ($nodeName === 'migrations') {
$config['migrations'] = $this->extractMigrations($node);
} else {
$config[$nodeName] = (string) $node;
}
}
return $config;
}
/** @return list<string> */
private function extractMigrations(SimpleXMLElement $node): array
{
$migrations = [];
foreach ($node->migration as $pathNode) {
$migrations[] = (string) $pathNode;
}
return $migrations;
}
private function validateXml(string $file): void
{
try {
libxml_use_internal_errors(true);
$xml = new DOMDocument();
if ($xml->load($file) === false) {
throw XmlNotValid::malformed();
}
$xsdPath = __DIR__ . DIRECTORY_SEPARATOR . 'XML' . DIRECTORY_SEPARATOR . 'configuration.xsd';
if ($xml->schemaValidate($xsdPath) === false) {
throw XmlNotValid::failedValidation();
}
} finally {
libxml_clear_errors();
libxml_use_internal_errors(false);
}
}
}