HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/switch4u.komma.nl/vendor/phpbench/phpbench/lib/Serializer/XmlEncoder.php
<?php

/*
 * This file is part of the PHPBench package
 *
 * (c) Daniel Leech <daniel@dantleech.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 */

namespace PhpBench\Serializer;

use PhpBench\Dom\Document;
use PhpBench\Dom\Element;
use PhpBench\Model\Benchmark;
use PhpBench\Model\ResolvedExecutor;
use PhpBench\Model\Subject;
use PhpBench\Model\Suite;
use PhpBench\Model\SuiteCollection;
use PhpBench\Model\Variant;
use PhpBench\PhpBench;
use PhpBench\Util\TimeUnit;

/**
 * Encodes the Suite object graph into an XML document.
 */
class XmlEncoder
{
    /**
     * Encode a Suite object into a XML document.
     *
     * @param SuiteCollection $suiteCollection
     *
     * @return Document
     */
    public function encode(SuiteCollection $suiteCollection)
    {
        $dom = new Document();

        $rootEl = $dom->createRoot('phpbench');
        $rootEl->setAttribute('version', PhpBench::VERSION);
        $rootEl->setAttributeNS(
            'http://www.w3.org/2000/xmlns/',
            'xmlns:xsi',
            'http://www.w3.org/2001/XMLSchema-instance'
        );

        foreach ($suiteCollection->getSuites() as $suite) {
            $suiteEl = $rootEl->appendElement('suite');
            $suiteEl->setAttribute('tag', $suite->getTag());

            // @deprecated context is deprecated and replaced by `tag`, to be
            //             removed in version 1.0
            $suiteEl->setAttribute('context', $suite->getTag());
            $suiteEl->setAttribute('date', $suite->getDate()->format('c'));
            $suiteEl->setAttribute('config-path', $suite->getConfigPath());
            $suiteEl->setAttribute('uuid', $suite->getUuid());

            $envEl = $suiteEl->appendElement('env');

            foreach ($suite->getEnvInformations() as $information) {
                $infoEl = $envEl->appendElement($information->getName());

                foreach ($information as $key => $value) {
                    $infoEl->setAttribute($key, $value);
                }
            }

            foreach ($suite->getBenchmarks() as $benchmark) {
                $this->processBenchmark($benchmark, $suiteEl);
            }
        }

        return $dom;
    }

    private function processBenchmark(Benchmark $benchmark, Element $suiteEl)
    {
        $benchmarkEl = $suiteEl->appendElement('benchmark');
        $benchmarkEl->setAttribute('class', $benchmark->getClass());

        foreach ($benchmark->getSubjects() as $subject) {
            $this->processSubject($subject, $benchmarkEl);
        }
    }

    private function processSubject(Subject $subject, Element $benchmarkEl)
    {
        $subjectEl = $benchmarkEl->appendElement('subject');
        $subjectEl->setAttribute('name', $subject->getName());

        $this->appendExecutor($subjectEl, $subject->getExecutor());

        foreach ($subject->getGroups() as $group) {
            $groupEl = $subjectEl->appendElement('group');
            $groupEl->setAttribute('name', $group);
        }

        foreach ($subject->getVariants() as $variant) {
            $this->processVariant($subject, $variant, $subjectEl);
        }
    }

    private function processVariant(Subject $subject, Variant $variant, Element $subjectEl)
    {
        $variantEl = $subjectEl->appendElement('variant');

        // TODO: These attributes should be on the subject, see
        // https://github.com/phpbench/phpbench/issues/307
        $variantEl->setAttribute('sleep', $subject->getSleep());
        $variantEl->setAttribute('output-time-unit', $subject->getOutputTimeUnit() ?: TimeUnit::MICROSECONDS);
        $variantEl->setAttribute('output-time-precision', $subject->getOutputTimePrecision());
        $variantEl->setAttribute('output-mode', $subject->getOutputMode() ?: TimeUnit::MODE_TIME);
        $variantEl->setAttribute('revs', (string) $variant->getRevolutions());
        $variantEl->setAttribute('warmup', (string) $variant->getWarmup());
        $variantEl->setAttribute('retry-threshold', $subject->getRetryThreshold());

        $parameterSetEl = $variantEl->appendElement('parameter-set');
        $parameterSetEl->setAttribute('name', $variant->getParameterSet()->getName());

        foreach ($variant->getParameterSet() as $name => $value) {
            $this->createParameter($parameterSetEl, $name, $value);
        }

        if ($variant->hasErrorStack()) {
            $errorsEl = $variantEl->appendElement('errors');

            foreach ($variant->getErrorStack() as $error) {
                $errorEl = $errorsEl->appendElement('error', $error->getMessage());
                $errorEl->setAttribute('exception-class', $error->getClass());
                $errorEl->setAttribute('code', $error->getCode());
                $errorEl->setAttribute('file', $error->getFile());
                $errorEl->setAttribute('line', $error->getLine());
            }

            return;
        }

        if ($variant->hasWarning()) {
            $warningsEl = $variantEl->appendElement('warnings');

            foreach ($variant->getWarnings() as $warning) {
                $warningEl = $warningsEl->appendElement('warning', $warning->getMessage());
            }
        }

        if ($variant->hasFailed()) {
            $failuresEl = $variantEl->appendElement('failures');

            foreach ($variant->getFailures() as $failure) {
                $failureEl = $failuresEl->appendElement('failure', $failure->getMessage());
            }
        }

        $stats = $variant->getStats();
        $stats = iterator_to_array($stats);
        $resultClasses = [];

        // ensure same order (for testing)
        ksort($stats);

        foreach ($variant as $iteration) {
            $iterationEl = $variantEl->appendElement('iteration');

            foreach ($iteration->getResults() as $result) {

                // we need to store the class FQNs of the results for deserialization later.
                if (!isset($resultClasses[$result->getKey()])) {
                    $resultClasses[$result->getKey()] = get_class($result);
                }

                $prefix = $result->getKey();
                $metrics = $result->getMetrics();

                foreach ($metrics as $key => $value) {
                    $iterationEl->setAttribute(sprintf(
                        '%s-%s',
                        $prefix,
                        str_replace('_', '-', $key)
                    ), $value);
                }
            }
        }

        $statsEl = $variantEl->appendElement('stats');

        foreach ($stats as $statName => $statValue) {
            $statsEl->setAttribute($statName, $statValue);
        }

        foreach ($resultClasses as $resultKey => $classFqn) {
            if ($subjectEl->queryOne('ancestor::suite/result[@key="' . $resultKey . '"]')) {
                continue;
            }

            $resultEl = $subjectEl->queryOne('ancestor::suite')->appendElement('result');
            $resultEl->setAttribute('key', $resultKey);
            $resultEl->setAttribute('class', $classFqn);
        }
    }

    private function createParameter($parentEl, $name, $value)
    {
        $parameterEl = $parentEl->appendElement('parameter');
        $parameterEl->setAttribute('name', $name);

        if (is_array($value)) {
            $parameterEl->setAttribute('type', 'collection');

            foreach ($value as $key => $element) {
                $this->createParameter($parameterEl, $key, $element);
            }

            return $parameterEl;
        }

        if (is_null($value)) {
            $parameterEl->setAttribute('xsi:nil', 'true');

            return $parameterEl;
        }

        if (is_scalar($value)) {
            $parameterEl->setAttribute('value', $value);

            return $parameterEl;
        }

        throw new \InvalidArgumentException(sprintf(
            'Parameters must be either scalars or arrays, got: %s',
            is_object($value) ? get_class($value) : gettype($value)
        ));
    }

    private function appendExecutor(Element $subjectEl, ResolvedExecutor $executor = null)
    {
        if (null === $executor) {
            return;
        }

        $executorEl = $subjectEl->appendElement('executor');
        $executorEl->setAttribute('name', $executor->getName());
        $subjectEl->appendChild($executorEl);

        foreach ($executor->getConfig() as $key => $value) {
            $this->createParameter($executorEl, $key, $value);
        }
    }
}