private function castObjectClass(): object
    {
        return new class($this->options) {
            /**
             * Console formatter configuration.
             *
             * @var array
             */
            private $options;

            public function __construct(array $options)
            {
                $this->options = $options;
            }

            /**
             * @param mixed                                    $value
             * @param array                                    $array
             * @param \Symfony\Component\VarDumper\Cloner\Stub $stub
             * @param mixed                                    $isNested
             *
             * @return array
             */
            public function castObject($value, array $array, Stub $stub, $isNested): array
            {
                if ($this->options['multiline']) {
                    return $array;
                }

                if ($isNested && ! $value instanceof DateTimeInterface) {
                    $stub->cut = -1;
                    $array     = [];
                }

                return $array;
            }
        };
    }

Return a anonymous class with a castObject function.

@return object

@codeCoverageIgnore

Return a anonymous class with a castObject function .


public function getCalledListeners(): array
    {
        $called = [];

        foreach ($this->called as $eventName => $listeners) {
            foreach ($listeners as $listener) {
                $called[$eventName][] = $listener->getInfo($eventName);
            }
        }

        return $called;
    }

public function getCalledListeners ( ) : array { $ called = [ ] ; foreach ( $ this -> called as $ eventName => $ listeners ) { foreach ( $ listeners as $ listener ) { $ called [ $ eventName ] [ ] = $ listener -> getInfo ( $ eventName ) ; } } return $ called ; }

Gets the called listeners.

@return array An array of called listeners


public function getNotCalledListeners(): array
    {
        try {
            $allListeners = $this->eventManager->getListeners();
        } catch (Throwable $e) {
            $this->logger->info('An exception was thrown while getting the uncalled listeners.', ['exception' => $e]);

            // unable to retrieve the uncalled listeners
            return [];
        }

        $notCalled = [];

        foreach ($allListeners as $eventName => $listeners) {
            foreach ($listeners as $listener) {
                $called = false;

                if (isset($this->called[$eventName])) {
                    foreach ($this->called[$eventName] as $calledListener) {
                        /** @var WrappedListener $calledListener */
                        if ($calledListener->getWrappedListener() === $listener) {
                            $called = true;

                            break;
                        }
                    }
                }

                if (! $called) {
                    if (! $listener instanceof WrappedListener) {
                        $listener = new WrappedListener($listener, null, $this->stopwatch, $this);
                    }

                    $notCalled[$eventName][] = $listener->getInfo($eventName);
                }
            }
        }

        \uasort($notCalled, [$this, 'sortListenersByPriority']);

        return $notCalled;
    }

Gets the not called listeners.

@return array An array of not called listeners


protected function validateSameSite($sameSite)
    {
        if (! \in_array($sameSite, [self::SAMESITE_STRICT, self::SAMESITE_LAX], true)) {
            return false;
        }

        return $sameSite;
    }

protected function validateSameSite ( $ sameSite ) { if ( ! \ in_array ( $ sameSite , [ self :: SAMESITE_STRICT , self :: SAMESITE_LAX ] , true ) ) { return false ; } return $ sameSite ; }

Validate SameSite value.

@param bool|string $sameSite

@return bool|string


protected function normalizeExpires($expiration = null): int
    {
        $expires   = $this->getTimestamp($expiration);
        $tsExpires = $expires;

        if (\is_string($expires)) {
            $tsExpires = \strtotime($expires);
            $is32Bit   = \PHP_INT_SIZE <= 4;

            // if $tsExpires is invalid and PHP is compiled as 32bit. Check if it fail reason is the 2038 bug
            if ($is32Bit && ! \is_int($tsExpires)) {
                $dateTime = new Chronos($expires);

                if ($dateTime->format('Y') > 2038) {
                    $tsExpires = \PHP_INT_MAX;
                }
            }
        }

        if (! \is_int($tsExpires) || $tsExpires < 0) {
            throw new InvalidArgumentException('Invalid expires time specified.');
        }

        return $tsExpires;
    }

Normalizes the expiration value.

@param null|\DateTimeInterface|int|string $expiration

@throws \Viserio\Component\Contract\Cookie\Exception\InvalidArgumentException

@return int


protected function normalizeDomain(string $domain = null): ?string
    {
        if ($domain !== null) {
            $domain = \mb_strtolower(\ltrim($domain, '.'));
        }

        return $domain;
    }

protected function normalizeDomain ( string $ domain = null ) : ? string { if ( $ domain !== null ) { $ domain = \ mb_strtolower ( \ ltrim ( $ domain , '.' ) ) ; } return $ domain ; }

Remove the leading '.' and lowercase the domain as per spec in RFC 6265.

@param null|string $domain

@return null|string

@see http://tools.ietf.org/html/rfc6265#section-4.1.2.3
@see http://tools.ietf.org/html/rfc6265#section-5.1.3
@see http://tools.ietf.org/html/rfc6265#section-5.2.3

Remove the leading . and lowercase the domain as per spec in RFC 6265 .


protected function normalizePath(string $path): string
    {
        $path = \rtrim($path, '/');

        if (empty($path) || \mb_strpos($path, '/')) {
            $path = '/';
        }

        return $path;
    }

protected function normalizePath ( string $ path ) : string { $ path = \ rtrim ( $ path , '/' ) ; if ( empty ( $ path ) || \ mb_strpos ( $ path , '/' ) ) { $ path = '/' ; } return $ path ; }

Processes path as per spec in RFC 6265.

@param string $path

@return string

@see http://tools.ietf.org/html/rfc6265#section-5.1.4
@see http://tools.ietf.org/html/rfc6265#section-5.2.4

Processes path as per spec in RFC 6265 .


protected function getTimestamp($expiration): ?string
    {
        if (\is_int($expiration) && \mb_strlen((string) $expiration) === 10 && $this->isValidTimeStamp($expiration)) {
            return Chronos::createFromTimestamp($expiration)->toCookieString();
        }

        if (\is_int($expiration)) {
            return Chronos::now()->addSeconds($expiration)->toCookieString();
        }

        if ($expiration instanceof DateTimeInterface) {
            return $expiration->format(DateTime::COOKIE);
        }

        if (\is_string($expiration)) {
            return $expiration;
        }

        return null;
    }

protected function getTimestamp ( $ expiration ) : ? string { if ( \ is_int ( $ expiration ) && \ mb_strlen ( ( string ) $ expiration ) === 10 && $ this -> isValidTimeStamp ( $ expiration ) ) { return Chronos :: createFromTimestamp ( $ expiration ) -> toCookieString ( ) ; } if ( \ is_int ( $ expiration ) ) { return Chronos :: now ( ) -> addSeconds ( $ expiration ) -> toCookieString ( ) ; } if ( $ expiration instanceof DateTimeInterface ) { return $ expiration -> format ( DateTime :: COOKIE ) ; } if ( \ is_string ( $ expiration ) ) { return $ expiration ; } return null ; }

Get timestamp as cookie string format.

@param null|\DateTimeInterface|int|string $expiration

@return null|string


private function start(string $name): TraceableCollector
    {
        $this->calls[] = $event = new TraceableCollector();

        $event->name  = $name;
        $event->start = \microtime(true);

        return $event;
    }

private function start ( string $ name ) : TraceableCollector { $ this -> calls [ ] = $ event = new TraceableCollector ( ) ; $ event -> name = $ name ; $ event -> start = \ microtime ( true ) ; return $ event ; }

Start new event.

@param string $name

@return \Viserio\Component\Profiler\DataCollector\Bridge\Cache\TraceableCollector


protected function applyHelpers(string $translation)
    {
        $helpers = $this->filterHelpersFromString($translation);

        if (\count($this->helpers) === 0 || \count($helpers) === 0) {
            return $translation;
        }

        foreach ($helpers as $helper) {
            if (! isset($this->helpers[$helper['name']])) {
                return $translation;
            }

            \array_unshift($helper['arguments'], $translation);

            $translation = \call_user_func_array($this->helpers[$helper['name']], $helper['arguments']);
        }

        return $translation;
    }

protected function applyHelpers ( string $ translation ) { $ helpers = $ this -> filterHelpersFromString ( $ translation ) ; if ( \ count ( $ this -> helpers ) === 0 || \ count ( $ helpers ) === 0 ) { return $ translation ; } foreach ( $ helpers as $ helper ) { if ( ! isset ( $ this -> helpers [ $ helper [ 'name' ] ] ) ) { return $ translation ; } \ array_unshift ( $ helper [ 'arguments' ] , $ translation ) ; $ translation = \ call_user_func_array ( $ this -> helpers [ $ helper [ 'name' ] ] , $ helper [ 'arguments' ] ) ; } return $ translation ; }

Apply helpers.

@param string $translation

@return mixed


protected function filterHelpersFromString(string $translation): array
    {
        $helpers = [];

        if (\preg_match('/^(.*?)\\[(.*?)\\]$/', $translation, $match) === 1) {
            $helpers = \explode('|', $match[2]);
            $helpers = \array_map(static function ($helper) {
                $name = $helper;
                $arguments = [];

                if (\preg_match('/^(.*?)\:(.*)$/', $helper, $match) === 1) {
                    $name = $match[1];
                    $arguments = \explode(':', $match[2]);
                }

                return [
                    'name'      => $name,
                    'arguments' => $arguments,
                ];
            }, $helpers);
        }

        return $helpers;
    }

protected function filterHelpersFromString ( string $ translation ) : array { $ helpers = [ ] ; if ( \ preg_match ( '/^(.*?)\\[(.*?)\\]$/' , $ translation , $ match ) === 1 ) { $ helpers = \ explode ( '|' , $ match [ 2 ] ) ; $ helpers = \ array_map ( static function ( $ helper ) { $ name = $ helper ; $ arguments = [ ] ; if ( \ preg_match ( '/^(.*?)\:(.*)$/' , $ helper , $ match ) === 1 ) { $ name = $ match [ 1 ] ; $ arguments = \ explode ( ':' , $ match [ 2 ] ) ; } return [ 'name' => $ name , 'arguments' => $ arguments , ] ; } , $ helpers ) ; } return $ helpers ; }

Filter a helper from string.

@param string $translation

@return array


protected function applyFilters(string $translation): string
    {
        if (\count($this->filters) === 0) {
            return $translation;
        }

        foreach ($this->filters as $filter) {
            $translation = $filter($translation);
        }

        return $translation;
    }

protected function applyFilters ( string $ translation ) : string { if ( \ count ( $ this -> filters ) === 0 ) { return $ translation ; } foreach ( $ this -> filters as $ filter ) { $ translation = $ filter ( $ translation ) ; } return $ translation ; }

Apply filter on string.

@param string $translation

@return string


protected function log(string $id, string $domain): void
    {
        $catalogue = $this->catalogue;

        if ($catalogue->defines($id, $domain)) {
            return;
        }

        if ($catalogue->has($id, $domain)) {
            $this->logger->debug(
                'Translation use fallback catalogue.',
                ['id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()]
            );
        } else {
            $this->logger->warning(
                'Translation not found.',
                ['id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()]
            );
        }
    }

protected
function
log
(
string
$
id
,
string
$
domain
)
:
void
{
$
catalogue
=
$
this
->
catalogue
;
if
(
$
catalogue
->
defines
(
$
id
,
$
domain
)
)
{
return
;
}
if
(
$
catalogue
->
has
(
$
id
,
$
domain
)
)
{
$
this
->
logger
->
debug
(
'Translation use fallback catalogue.'
,
[
'id'
=>
$
id
,
'domain'
=>
$
domain
,
'locale'
=>
$
catalogue
->
getLocale
(
)
]
)
;
}
else
{
$
this
->
logger
->
warning
(
'Translation not found.'
,
[
'id'
=>
$
id
,
'domain'
=>
$
domain
,
'locale'
=>
$
catalogue
->
getLocale
(
)
]
)
;
}
}

Logs for missing translations.

@param string $id
@param string $domain

@return void


protected function collectMessage(
        ?string $locale,
        string $domain,
        string $id,
        string $translation,
        array $parameters = []
    ): void {
        $catalogue = $this->catalogue;

        if ($catalogue->defines($id, $domain)) {
            $state = self::MESSAGE_DEFINED;
        } elseif ($catalogue->has($id, $domain)) {
            $state             = self::MESSAGE_EQUALS_FALLBACK;
            $fallbackCatalogue = $catalogue->getFallbackCatalogue();

            while ($fallbackCatalogue) {
                if ($fallbackCatalogue->defines($id, $domain)) {
                    $locale = $fallbackCatalogue->getLocale();

                    break;
                }

                $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
            }
        } else {
            $state = self::MESSAGE_MISSING;
        }

        $this->messages[] = [
            'locale'      => $locale,
            'domain'      => $domain,
            'id'          => $id,
            'translation' => $translation,
            'parameters'  => $parameters,
            'state'       => $state,
        ];
    }

protected function collectMessage ( ? string $ locale , string $ domain , string $ id , string $ translation , array $ parameters = [ ] ) : void { $ catalogue = $ this -> catalogue ; if ( $ catalogue -> defines ( $ id , $ domain ) ) { $ state = self :: MESSAGE_DEFINED ; } elseif ( $ catalogue -> has ( $ id , $ domain ) ) { $ state = self :: MESSAGE_EQUALS_FALLBACK ; $ fallbackCatalogue = $ catalogue -> getFallbackCatalogue ( ) ; while ( $ fallbackCatalogue ) { if ( $ fallbackCatalogue -> defines ( $ id , $ domain ) ) { $ locale = $ fallbackCatalogue -> getLocale ( ) ; break ; } $ fallbackCatalogue = $ fallbackCatalogue -> getFallbackCatalogue ( ) ; } } else { $ state = self :: MESSAGE_MISSING ; } $ this -> messages [ ] = [ 'locale' => $ locale , 'domain' => $ domain , 'id' => $ id , 'translation' => $ translation , 'parameters' => $ parameters , 'state' => $ state , ] ; }

Collect messages about all translations.

@param null|string $locale
@param string      $domain
@param string      $id
@param string      $translation
@param array       $parameters

@return void

Collect messages about all translations .


protected function display(array $files, string $format, bool $displayCorrectFiles): int
    {
        switch ($format) {
            case 'txt':
                return $this->displayTxt($files, $displayCorrectFiles);
            case 'json':
                return $this->displayJson($files);

            default:
                throw new InvalidArgumentException(\sprintf('The format [%s] is not supported.', $format));
        }
    }

protected
function
display
(
array
$
files
,
string
$
format
,
bool
$
displayCorrectFiles
)
:
int
{
switch
(
$
format
)
{
case
'txt'
:
return
$
this
->
displayTxt
(
$
files
,
$
displayCorrectFiles
)
;
case
'json'
:
return
$
this
->
displayJson
(
$
files
)
;
default
:
throw
new
InvalidArgumentException
(
\
sprintf
(
'The format [%s] is not supported.'
,
$
format
)
)
;
}
}

Get display type from format.

@param string $format
@param array  $files
@param bool   $displayCorrectFiles

@throws \Viserio\Component\Contract\Parser\Exception\InvalidArgumentException

@return int


protected function displayJson(array $filesInfo): int
    {
        $errors = 0;

        \array_walk($filesInfo, static function (&$v) use (&$errors): void {
            $v['file'] = (string) $v['file'];

            if (! $v['valid']) {
                $errors++;
            }
        });

        $this->getOutput()->writeln(\json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));

        return \min($errors, 1);
    }

protected function displayJson ( array $ filesInfo ) : int { $ errors = 0 ; \ array_walk ( $ filesInfo , static function ( & $ v ) use ( & $ errors ) : void { $ v [ 'file' ] = ( string ) $ v [ 'file' ] ; if ( ! $ v [ 'valid' ] ) { $ errors ++ ; } } ) ; $ this -> getOutput ( ) -> writeln ( \ json_encode ( $ filesInfo , \ JSON_PRETTY_PRINT | \ JSON_UNESCAPED_SLASHES ) ) ; return \ min ( $ errors , 1 ) ; }

Display errors in json format.

@param array $filesInfo

@return int


protected function getFiles(string $fileOrDirectory): Generator
    {
        if (\is_file($fileOrDirectory)) {
            yield $fileOrDirectory;

            return;
        }

        foreach (self::getDirectoryIterator($fileOrDirectory) as $file) {
            if (! \in_array($file->getExtension(), ['xlf', 'xliff'], true)) {
                continue;
            }

            yield (string) $file;
        }
    }

protected function getFiles ( string $ fileOrDirectory ) : Generator { if ( \ is_file ( $ fileOrDirectory ) ) { yield $ fileOrDirectory ; return ; } foreach ( self :: getDirectoryIterator ( $ fileOrDirectory ) as $ file ) { if ( ! \ in_array ( $ file -> getExtension ( ) , [ 'xlf' , 'xliff' ] , true ) ) { continue ; } yield ( string ) $ file ; } }

Get a generator of files.

@param string $fileOrDirectory

@return \Generator


protected function getStdin(): ?string
    {
        if (\ftell(\STDIN) !== 0) {
            return null;
        }

        $inputs = '';

        while (! \feof(\STDIN)) {
            $inputs .= \fread(\STDIN, 1024);
        }

        return $inputs;
    }

protected function getStdin ( ) : ? string { if ( \ ftell ( \ STDIN ) !== 0 ) { return null ; } $ inputs = '' ; while ( ! \ feof ( \ STDIN ) ) { $ inputs .= \ fread ( \ STDIN , 1024 ) ; } return $ inputs ; }

Get content from stdin.

@return null|string


protected static function getDirectoryIterator(string $directory): RecursiveIteratorIterator
    {
        return new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS),
            RecursiveIteratorIterator::LEAVES_ONLY
        );
    }

protected static function getDirectoryIterator ( string $ directory ) : RecursiveIteratorIterator { return new RecursiveIteratorIterator ( new RecursiveDirectoryIterator ( $ directory , FilesystemIterator :: SKIP_DOTS | FilesystemIterator :: FOLLOW_SYMLINKS ) , RecursiveIteratorIterator :: LEAVES_ONLY ) ; }

Get item from dirs.

@param string $directory

@return \RecursiveIteratorIterator


protected function validateEventName(string $eventName): void
    {
        \preg_match_all('/([a-zA-Z0-9_\\.]+)/', $eventName, $matches);

        if (\count($matches[0]) >= 2) {
            throw new InvalidArgumentException(
                'The event name must only contain the characters A-Z, a-z, 0-9, _, and \'.\'.'
            );
        }
    }

The event name must only contain the characters A-Z, a-z, 0-9, _, and '.'.

@param string $eventName

@throws \Viserio\Component\Contract\Events\Exception\InvalidArgumentException

@return void

The event name must only contain the characters A - Z a - z 0 - 9 _ and . .


protected static function convertToBytes(string $number): int
    {
        /**
         * Prefixes to specify unit of measure for memory amount.
         *
         * Warning: it is important to maintain the exact order of letters in this literal,
         * as it is used to convert string with units to bytes
         */
        $memoryUnits = 'BKMGTPE';

        if (\preg_match('/^(.*\d)\h*(\D)$/', $number, $matches) !== 1) {
            throw new InvalidArgumentException("Number format '{$number}' is not recognized.");
        }

        $unitSymbol = \mb_strtoupper($matches[2]);

        if (\mb_strpos($memoryUnits, $unitSymbol) === false) {
            throw new InvalidArgumentException("The number '{$number}' has an unrecognized unit: '{$unitSymbol}'.");
        }

        $result = self::convertToNumber($matches[1]);
        $pow    = $unitSymbol ? \mb_strpos($memoryUnits, $unitSymbol) : 0;

        if (\PHP_INT_SIZE <= 4 && $pow >= 4) {
            throw new OutOfBoundsException('A 32-bit system is unable to process such a number.');
        }

        if ($unitSymbol) {
            $result *= 1024 ** $pow;
        }

        return (int) $result;
    }

Convert a number string to bytes.

@param string $number

@throws \InvalidArgumentException
@throws \OutOfBoundsException

@return int limit in bytes or -1 if it's unlimited


private static function convertToNumber(string $number): string
    {
        \preg_match_all('/(\D+)/', $number, $matches);

        if (\count(\array_unique($matches[0])) > 1) {
            throw new InvalidArgumentException(
                "The number '{$number}' seems to have decimal part. Only integer numbers are supported."
            );
        }

        return \preg_replace('/\D+/', '', $number);
    }

Remove non-numeric characters in the string to cast it to a numeric value.

Incoming number can be presented in arbitrary format that depends on locale. We don't possess locale information.
So the best can be done is to treat number as an integer and eliminate delimiters.
Method will not behave correctly with non-integer numbers for the following reason:
- if value has more than one delimiter, such as in French notation: "1 234,56" -- then we can infer decimal part
- but the value has only one delimiter, such as "234,56", then it is impossible to know whether it is decimal
separator or not. Only knowing the right format would allow this.

@param string $number

@throws \InvalidArgumentException

@return string

Remove non - numeric characters in the string to cast it to a numeric value .


protected function getConfigFromName(string $name): array
    {
        $adapter = $this->resolvedOptions[static::CONFIG_LIST_NAME] ?? [];

        if (isset($adapter[$name]) && \is_array($adapter[$name])) {
            $config         = $adapter[$name];
            $config['name'] = $name;

            return $config;
        }

        return ['name' => $name];
    }

protected function getConfigFromName ( string $ name ) : array { $ adapter = $ this -> resolvedOptions [ static :: CONFIG_LIST_NAME ] ?? [ ] ; if ( isset ( $ adapter [ $ name ] ) && \ is_array ( $ adapter [ $ name ] ) ) { $ config = $ adapter [ $ name ] ; $ config [ 'name' ] = $ name ; return $ config ; } return [ 'name' => $ name ] ; }

Get config on adapter name.

@param string $name

@return array


protected function create(array $config, string $method, string $errorMessage)
    {
        if (isset($this->extensions[$config['name']])) {
            return $this->callCustomCreator($config['name'], $config);
        }

        if (\method_exists($this, $method)) {
            return $this->{$method}($config);
        }

        throw new InvalidArgumentException(\sprintf($errorMessage, $config['name']));
    }

protected function create ( array $ config , string $ method , string $ errorMessage ) { if ( isset ( $ this -> extensions [ $ config [ 'name' ] ] ) ) { return $ this -> callCustomCreator ( $ config [ 'name' ] , $ config ) ; } if ( \ method_exists ( $ this , $ method ) ) { return $ this -> { $ method } ( $ config ) ; } throw new InvalidArgumentException ( \ sprintf ( $ errorMessage , $ config [ 'name' ] ) ) ; }

Make a new driver instance.

@param array  $config
@param string $method
@param string $errorMessage

@throws \Viserio\Component\Contract\Manager\Exception\InvalidArgumentException

@return mixed


public function addExtractor(string $format, ExtractorContract $extractor): void
    {
        $this->extractors[$format] = $extractor;
    }

public function addExtractor ( string $ format , ExtractorContract $ extractor ) : void { $ this -> extractors [ $ format ] = $ extractor ; }

Adds a loader to the translation extractor.

@param string                                            $format
@param \Viserio\Component\Contract\Translation\Extractor $extractor

@return void

Adds a loader to the translation extractor .


public static function createAliasLoader(ContainerInterface $container): AliasLoaderContract
    {
        $options = self::resolveOptions($container->get('config'));

        $loader    = new AliasLoader($options['aliases']);
        $cachePath = self::getCachePath($container, $options);

        if ($cachePath !== null) {
            $loader->setCachePath($cachePath);

            if ($options['real_time_proxy'] === true) {
                $loader->enableRealTimeStaticalProxy();
            }
        }

        return $loader;
    }

public static function createAliasLoader ( ContainerInterface $ container ) : AliasLoaderContract { $ options = self :: resolveOptions ( $ container -> get ( 'config' ) ) ; $ loader = new AliasLoader ( $ options [ 'aliases' ] ) ; $ cachePath = self :: getCachePath ( $ container , $ options ) ; if ( $ cachePath !== null ) { $ loader -> setCachePath ( $ cachePath ) ; if ( $ options [ 'real_time_proxy' ] === true ) { $ loader -> enableRealTimeStaticalProxy ( ) ; } } return $ loader ; }

Create a new Alias loader.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Contract\StaticalProxy\AliasLoader


private static function getCachePath(ContainerInterface $container, array $options): ?string
    {
        $cachePath = $options['cache_path'];

        if ($cachePath === null && $container->has(KernelContract::class)) {
            $cachePath = $container->get(KernelContract::class)->getStoragePath('staticalproxy');
        }

        return $cachePath;
    }

private static function getCachePath ( ContainerInterface $ container , array $ options ) : ? string { $ cachePath = $ options [ 'cache_path' ] ; if ( $ cachePath === null && $ container -> has ( KernelContract :: class ) ) { $ cachePath = $ container -> get ( KernelContract :: class ) -> getStoragePath ( 'staticalproxy' ) ; } return $ cachePath ; }

Get real-time proxy cache path.

@param \Psr\Container\ContainerInterface $container
@param array                             $options

@return null|string


protected function pushCommandToQueue(QueueContract $queue, $command)
    {
        if (isset($command->queue, $command->delay)) {
            return $queue->laterOn($command->queue, $command->delay, $command);
        }

        if (isset($command->queue)) {
            return $queue->pushOn($command->queue, $command);
        }

        if (isset($command->delay)) {
            return $queue->later($command->delay, $command);
        }

        return $queue->push($command);
    }

protected function pushCommandToQueue ( QueueContract $ queue , $ command ) { if ( isset ( $ command -> queue , $ command -> delay ) ) { return $ queue -> laterOn ( $ command -> queue , $ command -> delay , $ command ) ; } if ( isset ( $ command -> queue ) ) { return $ queue -> pushOn ( $ command -> queue , $ command ) ; } if ( isset ( $ command -> delay ) ) { return $ queue -> later ( $ command -> delay , $ command ) ; } return $ queue -> push ( $ command ) ; }

Push the command onto the given queue instance.

@param \Viserio\Component\Contract\Queue\QueueConnector $queue
@param mixed                                            $command

@return mixed

Push the command onto the given queue instance .


protected function commandShouldBeQueued($command): bool
    {
        if ($command instanceof ShouldQueueContract) {
            return true;
        }

        $reflection = new ReflectionClass($this->getHandlerClass($command));

        return $reflection->implementsInterface(ShouldQueueContract::class);
    }

protected function commandShouldBeQueued ( $ command ) : bool { if ( $ command instanceof ShouldQueueContract ) { return true ; } $ reflection = new ReflectionClass ( $ this -> getHandlerClass ( $ command ) ) ; return $ reflection -> implementsInterface ( ShouldQueueContract :: class ) ; }

Determine if the given command should be queued.

@param mixed $command

@return bool

Determine if the given command should be queued .


protected function createCookieDriver(): StoreContract
    {
        if ($this->cookieJar === null) {
            throw new RuntimeException(\sprintf('No instance of [%s] found.', JarContract::class));
        }

        return $this->buildSession(
            new CookieSessionHandler(
                $this->cookieJar,
                $this->resolvedOptions['lifetime']
            )
        );
    }

protected
function
createCookieDriver
(
)
:
StoreContract
{
if
(
$
this
->
cookieJar
===
)
{
throw
new
RuntimeException
(
\
sprintf
(
'No instance of [%s] found.'
,
JarContract
::
class
)
)
;
}
return
$
this
->
buildSession
(
new
CookieSessionHandler
(
$
this
->
cookieJar
,
$
this
->
resolvedOptions
[
'lifetime'
]
)
)
;
}

Create an instance of the "cookie" session driver.

@throws \Viserio\Component\Contract\Session\Exception\RuntimeException

@return \Viserio\Component\Contract\Session\Store

Create an instance of the cookie session driver .


protected function createMigratingDriver(array $config): StoreContract
    {
        if (! isset($config['current'], $config['write_only'])) {
            throw new RuntimeException('The MigratingSessionHandler needs a current and write only handler.');
        }

        $currentHandler   = $this->getDriver($config['current']);
        $writeOnlyHandler = $this->getDriver($config['write_only']);

        return $this->buildSession(
            new MigratingSessionHandler($currentHandler->getHandler(), $writeOnlyHandler->getHandler())
        );
    }

Create an instance of the Migrating session driver.

@param array $config

@throws \Viserio\Component\Contract\Session\Exception\RuntimeException

@return \Viserio\Component\Contract\Session\Store

Create an instance of the Migrating session driver .


protected function createCacheBased($driver): StoreContract
    {
        if ($this->cacheManager === null) {
            throw new RuntimeException(\sprintf('No instance of [%s] found.', CacheManagerContract::class));
        }

        return $this->buildSession(
            new Psr6SessionHandler(
                clone $this->cacheManager->getDriver($driver),
                ['ttl' => $this->resolvedOptions['lifetime'], 'prefix' => 'ns_ses_']
            )
        );
    }

protected
function
createCacheBased
(
$
driver
)
:
StoreContract
{
if
(
$
this
->
cacheManager
===
)
{
throw
new
RuntimeException
(
\
sprintf
(
'No instance of [%s] found.'
,
CacheManagerContract
::
class
)
)
;
}
return
$
this
->
buildSession
(
new
Psr6SessionHandler
(
clone
$
this
->
cacheManager
->
getDriver
(
$
driver
)
,
[
'ttl'
=>
$
this
->
resolvedOptions
[
'lifetime'
]
,
'prefix'
=>
'ns_ses_'
]
)
)
;
}

Create the cache based session handler instance.

@param string $driver

@throws \Viserio\Component\Contract\Session\Exception\RuntimeException

@return \Viserio\Component\Contract\Session\Store

Create the cache based session handler instance .


protected function buildSession(SessionHandlerInterface $handler): StoreContract
    {
        if ($this->resolvedOptions['encrypt'] === true) {
            return $this->buildEncryptedSession($handler);
        }

        return new Store($this->resolvedOptions['cookie']['name'], $handler);
    }

protected function buildSession ( SessionHandlerInterface $ handler ) : StoreContract { if ( $ this -> resolvedOptions [ 'encrypt' ] === true ) { return $ this -> buildEncryptedSession ( $ handler ) ; } return new Store ( $ this -> resolvedOptions [ 'cookie' ] [ 'name' ] , $ handler ) ; }

Build the session instance.

@param \SessionHandlerInterface $handler

@return \Viserio\Component\Contract\Session\Store


protected function buildEncryptedSession(SessionHandlerInterface $handler): StoreContract
    {
        return new EncryptedStore(
            $this->resolvedOptions['cookie']['name'],
            $handler,
            $this->key
        );
    }

protected function buildEncryptedSession ( SessionHandlerInterface $ handler ) : StoreContract { return new EncryptedStore ( $ this -> resolvedOptions [ 'cookie' ] [ 'name' ] , $ handler , $ this -> key ) ; }

Build the encrypted session instance.

@param \SessionHandlerInterface $handler

@return \Viserio\Component\Contract\Session\Store


public static function parse(string $uri, $action): array
    {
        // If no action is passed in right away, we assume the user will make use of
        // fluent routing. In that case, we set a default closure, to be executed
        // if the user never explicitly sets an action to handle the given uri.
        if ($action === null) {
            return static::missingAction($uri);
        }

        // If the action is already a Closure instance, we will just set that instance
        // as the "uses" property.
        if (\is_callable($action)) {
            return ['uses' => $action];
        }

        // If no "uses" property has been set, we will dig through the array to find a
        // Closure instance within this list. We will set the first Closure we come across.
        if (! isset($action['uses'])) {
            $callback = static function ($key, $value) {
                return \is_callable($value) && \is_numeric($key);
            };

            $action['uses'] = self::getFirst($action, $callback);
        }

        if (\is_string($action['uses']) && \strpos($action['uses'], '@') === false) {
            if (! \method_exists($action['uses'], '__invoke')) {
                throw new UnexpectedValueException(\sprintf(
                    'Invalid route action: [%s].',
                    $action['uses']
                ));
            }

            $action['uses'] = $action['uses'] . '@__invoke';
        }

        return $action;
    }

Parse the given action into an array.

@param string $uri
@param mixed  $action

@throws \Viserio\Component\Contract\Routing\Exception\UnexpectedValueException if invalid route action
@throws \Viserio\Component\Contract\Routing\Exception\LogicException           if no action found

@return array


protected static function getFirst(array $array, callable $callback)
    {
        foreach ($array as $key => $value) {
            if ($callback($key, $value)) {
                return $value;
            }
        }

        return null;
    }

protected static function getFirst ( array $ array , callable $ callback ) { foreach ( $ array as $ key => $ value ) { if ( $ callback ( $ key , $ value ) ) { return $ value ; } } return null ; }

Return the first element in an array passing a given truth test.

@param array    $array
@param callable $callback

@return mixed

Return the first element in an array passing a given truth test .


private static function parseNotes(SimpleXMLElement $noteElement, ?string $encoding = null): array
    {
        $notes = [];

        /** @var \SimpleXMLElement $xmlNote */
        foreach ($noteElement as $xmlNote) {
            $noteAttributes = $xmlNote->attributes();
            $note           = ['content' => self::utf8ToCharset((string) $xmlNote, $encoding)];

            if (isset($noteAttributes['priority'])) {
                $note['priority'] = (int) $noteAttributes['priority'];
            }

            if (isset($noteAttributes['from'])) {
                $note['from'] = (string) $noteAttributes['from'];
            }

            $notes[] = $note;
        }

        return $notes;
    }

private
static
function
parseNotes
(
SimpleXMLElement
$
noteElement
,
string
$
encoding
=
)
:
array
{
$
notes
=
[
]
;
/** @var \SimpleXMLElement $xmlNote */
foreach
(
$
noteElement
as
$
xmlNote
)
{
$
noteAttributes
=
$
xmlNote
->
attributes
(
)
;
$
note
=
[
'content'
=>
self
::
utf8ToCharset
(
(
string
)
$
xmlNote
,
$
encoding
)
]
;
if
(
isset
(
$
noteAttributes
[
'priority'
]
)
)
{
$
note
[
'priority'
]
=
(
int
)
$
noteAttributes
[
'priority'
]
;
}
if
(
isset
(
$
noteAttributes
[
'from'
]
)
)
{
$
note
[
'from'
]
=
(
string
)
$
noteAttributes
[
'from'
]
;
}
$
notes
[
]
=
$
note
;
}
return
$
notes
;
}

Parse xliff notes.

@param \SimpleXMLElement $noteElement
@param null|string       $encoding

@return array


private static function utf8ToCharset(string $content, string $encoding = null): string
    {
        if ($encoding !== 'UTF-8' && $encoding !== null) {
            return \mb_convert_encoding($content, $encoding, 'UTF-8');
        }

        return $content;
    }

private static function utf8ToCharset ( string $ content , string $ encoding = null ) : string { if ( $ encoding !== 'UTF-8' && $ encoding !== null ) { return \ mb_convert_encoding ( $ content , $ encoding , 'UTF-8' ) ; } return $ content ; }

Convert a UTF8 string to the specified encoding.

@param string      $content  String to decode
@param null|string $encoding Target encoding

@return string

Convert a UTF8 string to the specified encoding .


protected function tag(string $tag, array $data): array
    {
        $taggedData = [];

        foreach ($data as $key => $value) {
            $name = \sprintf(
                '%s' . self::TAG_DELIMITER . '%s',
                $tag,
                $key
            );

            $taggedData[$name] = $value;
        }

        return $taggedData;
    }

protected function tag ( string $ tag , array $ data ) : array { $ taggedData = [ ] ; foreach ( $ data as $ key => $ value ) { $ name = \ sprintf ( '%s' . self :: TAG_DELIMITER . '%s' , $ tag , $ key ) ; $ taggedData [ $ name ] = $ value ; } return $ taggedData ; }

Tag all keys with given tag.

@param string $tag
@param array  $data

@return array


public static function createLogManger(ContainerInterface $container): LogManager
    {
        $manager = new LogManager($container->get('config'));

        if ($container->has(EventManagerContract::class)) {
            $manager->setEventManager($container->get(EventManagerContract::class));
        }

        return $manager;
    }

public static function createLogManger ( ContainerInterface $ container ) : LogManager { $ manager = new LogManager ( $ container -> get ( 'config' ) ) ; if ( $ container -> has ( EventManagerContract :: class ) ) { $ manager -> setEventManager ( $ container -> get ( EventManagerContract :: class ) ) ; } return $ manager ; }

Create a log manager instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Log\LogManager


public function confirmToProceed(string $warning = 'Application is in Production mode!', $callback = null): bool
    {
        $callback      = $callback ?? $this->getDefaultConfirmCallback();
        $shouldConfirm = $callback instanceof Closure ? $callback() : $callback;

        if ($shouldConfirm) {
            if ($this->option('force')) {
                return true;
            }

            $this->comment(\str_repeat('*', \mb_strlen($warning) + 12));
            $this->comment('*     ' . $warning . '     *');
            $this->comment(\str_repeat('*', \mb_strlen($warning) + 12));
            $this->line('');

            $confirmed = $this->confirm('Do you really wish to run this command?');

            if (! $confirmed) {
                $this->comment('Command Cancelled!');

                return false;
            }
        }

        return true;
    }

Confirm before proceeding with the action.

@param string             $warning
@param null|bool|\Closure $callback

@return bool

Confirm before proceeding with the action .


protected function getDefaultConfirmCallback(): Closure
    {
        return function () {
            if ($this->container !== null && $this->container->has('env')) {
                return $this->container->get('env') === 'prod';
            }

            if (($env = \getenv('APP_ENV')) !== false) {
                return $env === 'prod';
            }

            return true;
        };
    }

protected function getDefaultConfirmCallback ( ) : Closure { return function ( ) { if ( $ this -> container !== null && $ this -> container -> has ( 'env' ) ) { return $ this -> container -> get ( 'env' ) === 'prod' ; } if ( ( $ env = \ getenv ( 'APP_ENV' ) ) !== false ) { return $ env === 'prod' ; } return true ; } ; }

Get the default confirmation callback.

@return \Closure


protected function injectProfiler(ResponseInterface $response, string $token): ResponseInterface
    {
        $content         = (string) $response->getBody();
        $renderedContent = $this->createTemplate($token);

        $pos = \mb_strripos($content, '</body>');

        if ($pos !== false) {
            $stream = $this->streamFactory->createStream(
                \mb_substr($content, 0, $pos) . $renderedContent . \mb_substr($content, $pos)
            );

            // Update the new content and reset the content length
            $response = $response->withoutHeader('content-length');

            return $response->withBody($stream);
        }

        $response->getBody()->write($renderedContent);

        return $response;
    }

Injects the web debug toolbar into the given Response.

@param \Psr\Http\Message\ResponseInterface $response
@param string                              $token

@return \Psr\Http\Message\ResponseInterface

@see https://github.com/symfony/ProfilerBundle/blob/master/EventListener/WebDebugToolbarListener.php

Injects the web debug toolbar into the given Response .


private function collectData(
        string $token,
        ServerRequestInterface $serverRequest,
        ResponseInterface $response
    ): void {
        // sort on priority
        \usort($this->collectors, static function ($a, $b) {
            return $a['priority'] <=> $b['priority'];
        });

        foreach ($this->collectors as $name => $collector) {
            $collector['collector']->collect($serverRequest, $response);

            $this->collectors[$name]['collector'] = $collector['collector'];
        }

        $ip = (new ClientIp($serverRequest))->getIpAddress();

        if ($this->cachePool !== null) {
            $this->createProfile(
                $token,
                $ip ?? 'Unknown',
                $serverRequest->getMethod(),
                (string) $serverRequest->getUri(),
                $response->getStatusCode(),
                \microtime(true),
                \date('Y-m-d H:i:s'),
                $this->collectors
            );
        }
    }

private
function
collectData
(
string
$
token
,
ServerRequestInterface
$
serverRequest
,
ResponseInterface
$
response
)
:
void
{
// sort on priority
\
usort
(
$
this
->
collectors
,
static
function
(
$
a
,
$
b
)
{
return
$
a
[
'priority'
]
<=>
$
b
[
'priority'
]
;
}
)
;
foreach
(
$
this
->
collectors
as
$
name
=>
$
collector
)
{
$
collector
[
'collector'
]
->
collect
(
$
serverRequest
,
$
response
)
;
$
this
->
collectors
[
$
name
]
[
'collector'
]
=
$
collector
[
'collector'
]
;
}
$
ip
=
(
new
ClientIp
(
$
serverRequest
)
)
->
getIpAddress
(
)
;
if
(
$
this
->
cachePool
!==
)
{
$
this
->
createProfile
(
$
token
,
$
ip
??
'Unknown'
,
$
serverRequest
->
getMethod
(
)
,
(
string
)
$
serverRequest
->
getUri
(
)
,
$
response
->
getStatusCode
(
)
,
\
microtime
(
true
)
,
\
date
(
'Y-m-d H:i:s'
)
,
$
this
->
collectors
)
;
}
}

Collect data and create a new profile and save it.

@param string                                   $token
@param \Psr\Http\Message\ServerRequestInterface $serverRequest
@param \Psr\Http\Message\ResponseInterface      $response

@return void

Collect data and create a new profile and save it .


private function createTemplate(string $token): string
    {
        $assets   = $this->getAssetsRenderer();
        $template = new TemplateManager(
            $this->collectors,
            $this->template,
            $token,
            $assets->getIcons()
        );

        return $assets->render() . $template->render();
    }

private function createTemplate ( string $ token ) : string { $ assets = $ this -> getAssetsRenderer ( ) ; $ template = new TemplateManager ( $ this -> collectors , $ this -> template , $ token , $ assets -> getIcons ( ) ) ; return $ assets -> render ( ) . $ template -> render ( ) ; }

Create template.

@param string $token

@return string


private function createProfile(
        string $token,
        string $ip,
        string $method,
        string $url,
        int $statusCode,
        float $time,
        string $date,
        array $collectors
    ): void {
        $profile = new Profile($token);
        $profile->setIp($ip);
        $profile->setMethod($method);
        $profile->setUrl($url);
        $profile->setTime($time);
        $profile->setDate($date);
        $profile->setStatusCode($statusCode);
        $profile->setCollectors($collectors);

        $item = $this->cachePool->getItem($token);
        $item->set($profile);
        $item->expiresAfter(60);

        $this->cachePool->save($item);
    }

private function createProfile ( string $ token , string $ ip , string $ method , string $ url , int $ statusCode , float $ time , string $ date , array $ collectors ) : void { $ profile = new Profile ( $ token ) ; $ profile -> setIp ( $ ip ) ; $ profile -> setMethod ( $ method ) ; $ profile -> setUrl ( $ url ) ; $ profile -> setTime ( $ time ) ; $ profile -> setDate ( $ date ) ; $ profile -> setStatusCode ( $ statusCode ) ; $ profile -> setCollectors ( $ collectors ) ; $ item = $ this -> cachePool -> getItem ( $ token ) ; $ item -> set ( $ profile ) ; $ item -> expiresAfter ( 60 ) ; $ this -> cachePool -> save ( $ item ) ; }

Create profile with all datas.

@param string $token
@param string $ip
@param string $method
@param string $url
@param int    $statusCode
@param float  $time
@param string $date
@param array  $collectors

@return void


public static function parseLevel(string $level): int
    {
        if (isset(self::$levels[$level])) {
            return self::$levels[$level];
        }

        throw new InvalidArgumentException('Invalid log level.');
    }

public
static
function
parseLevel
(
string
$
level
)
:
int
{
if
(
isset
(
self
::
$
levels
[
$
level
]
)
)
{
return
self
::
$
levels
[
$
level
]
;
}
throw
new
InvalidArgumentException
(
'Invalid log level.'
)
;
}

Parse the string level into a Monolog constant.

@param string $level

@throws \InvalidArgumentException

@return int

Parse the string level into a Monolog constant .


protected function startSession(ServerRequestInterface $request): StoreContract
    {
        $session   = $this->manager->getDriver();
        $cookies   = RequestCookies::fromRequest($request);

        $session->setId($cookies->has($session->getName()) ? $cookies->get($session->getName())->getValue() : '');

        foreach ($this->fingerprintGenerators as $fingerprintGenerator) {
            $session->addFingerprintGenerator(new $fingerprintGenerator($request));
        }

        if ($session->handlerNeedsRequest()) {
            $session->setRequestOnHandler($request);
        }

        if (! $session->open()) {
            $session->start();
        }

        return $session;
    }

protected function startSession ( ServerRequestInterface $ request ) : StoreContract { $ session = $ this -> manager -> getDriver ( ) ; $ cookies = RequestCookies :: fromRequest ( $ request ) ; $ session -> setId ( $ cookies -> has ( $ session -> getName ( ) ) ? $ cookies -> get ( $ session -> getName ( ) ) -> getValue ( ) : '' ) ; foreach ( $ this -> fingerprintGenerators as $ fingerprintGenerator ) { $ session -> addFingerprintGenerator ( new $ fingerprintGenerator ( $ request ) ) ; } if ( $ session -> handlerNeedsRequest ( ) ) { $ session -> setRequestOnHandler ( $ request ) ; } if ( ! $ session -> open ( ) ) { $ session -> start ( ) ; } return $ session ; }

Start the session for the given request.

@param \Psr\Http\Message\ServerRequestInterface $request

@return \Viserio\Component\Contract\Session\Store

Start the session for the given request .


protected function storeCurrentUrl(ServerRequestInterface $request, StoreContract $session): StoreContract
    {
        if ($request->getMethod() === 'GET' &&
            $request->getHeaderLine('x-requested-with') !== 'XMLHttpRequest'
        ) {
            $session->setPreviousUrl((string) $request->getUri());
        }

        return $session;
    }

protected function storeCurrentUrl ( ServerRequestInterface $ request , StoreContract $ session ) : StoreContract { if ( $ request -> getMethod ( ) === 'GET' && $ request -> getHeaderLine ( 'x-requested-with' ) !== 'XMLHttpRequest' ) { $ session -> setPreviousUrl ( ( string ) $ request -> getUri ( ) ) ; } return $ session ; }

Store the current URL for the request if necessary.

@param \Psr\Http\Message\ServerRequestInterface  $request
@param \Viserio\Component\Contract\Session\Store $session

@return \Viserio\Component\Contract\Session\Store

Store the current URL for the request if necessary .


protected function collectGarbage(StoreContract $session): void
    {
        $lottery     = $this->cookieConfig['lottery'];
        $hitsLottery = \random_int(1, $lottery[1]) <= $lottery[0];

        // Here we will see if this request hits the garbage collection lottery by hitting
        // the odds needed to perform garbage collection on any given request. If we do
        // hit it, we'll call this handler to let it delete all the expired sessions.
        if ($hitsLottery) {
            $session->getHandler()->gc($this->lifetime);
        }
    }

Remove the garbage from the session if necessary.

@param \Viserio\Component\Contract\Session\Store $session

@return void

Remove the garbage from the session if necessary .


protected function addCookieToResponse(
        ServerRequestInterface $request,
        ResponseInterface $response,
        StoreContract $session
    ): ResponseInterface {
        if ($session->getHandler() instanceof CookieSessionHandler) {
            $session->save();
        }

        $uri    = $request->getUri();

        $setCookie = new SetCookie(
            $session->getName(),
            $session->getId(),
            $this->cookieConfig['expire_on_close'] === true ? 0 : Chronos::now()->addSeconds($this->lifetime),
            $this->cookieConfig['path'] ?? '/',
            $this->cookieConfig['domain'] ?? $uri->getHost(),
            $this->cookieConfig['secure'] ?? ($uri->getScheme() === 'https'),
            $this->cookieConfig['http_only'] ?? true,
            $this->cookieConfig['samesite'] ?? false
        );

        return $response->withAddedHeader('set-cookie', (string) $setCookie);
    }

protected function addCookieToResponse ( ServerRequestInterface $ request , ResponseInterface $ response , StoreContract $ session ) : ResponseInterface { if ( $ session -> getHandler ( ) instanceof CookieSessionHandler ) { $ session -> save ( ) ; } $ uri = $ request -> getUri ( ) ; $ setCookie = new SetCookie ( $ session -> getName ( ) , $ session -> getId ( ) , $ this -> cookieConfig [ 'expire_on_close' ] === true ? 0 : Chronos :: now ( ) -> addSeconds ( $ this -> lifetime ) , $ this -> cookieConfig [ 'path' ] ?? '/' , $ this -> cookieConfig [ 'domain' ] ?? $ uri -> getHost ( ) , $ this -> cookieConfig [ 'secure' ] ?? ( $ uri -> getScheme ( ) === 'https' ) , $ this -> cookieConfig [ 'http_only' ] ?? true , $ this -> cookieConfig [ 'samesite' ] ?? false ) ; return $ response -> withAddedHeader ( 'set-cookie' , ( string ) $ setCookie ) ; }

Add the session cookie to the application response.

@param \Psr\Http\Message\ServerRequestInterface  $request
@param \Psr\Http\Message\ResponseInterface       $response
@param \Viserio\Component\Contract\Session\Store $session

@throws \Viserio\Component\Contract\Cookie\Exception\InvalidArgumentException

@return \Psr\Http\Message\ResponseInterface

Add the session cookie to the application response .


public static function createResponseView(string $template, array $args = []): ResponseInterface
    {
        $response = self::$container->get(ResponseFactoryInterface::class)->createResponse();
        $response = $response->withAddedHeader('Content-Type', 'text/html');

        $stream = self::$container->get(StreamFactoryInterface::class)->createStream();
        $stream->write((string) self::$container->get(ViewFactory::class)->create($template, $args));

        return $response->withBody($stream);
    }

public static function createResponseView ( string $ template , array $ args = [ ] ) : ResponseInterface { $ response = self :: $ container -> get ( ResponseFactoryInterface :: class ) -> createResponse ( ) ; $ response = $ response -> withAddedHeader ( 'Content-Type' , 'text/html' ) ; $ stream = self :: $ container -> get ( StreamFactoryInterface :: class ) -> createStream ( ) ; $ stream -> write ( ( string ) self :: $ container -> get ( ViewFactory :: class ) -> create ( $ template , $ args ) ) ; return $ response -> withBody ( $ stream ) ; }

Create a response from string.

@param string $template
@param array  $args

@return ResponseInterface


public function findTemplate(string $name): string
    {
        if ($this->files->has($name)) {
            return $name;
        }

        $name = $this->normalizeName($name);

        if (isset($this->cache[$name])) {
            return $this->cache[$name];
        }

        try {
            $found              = $this->finder->find($name);
            $this->cache[$name] = $found['path'];
        } catch (InvalidArgumentException $exception) {
            throw new LoaderError($exception->getMessage());
        }

        return $this->cache[$name];
    }

public function findTemplate ( string $ name ) : string { if ( $ this -> files -> has ( $ name ) ) { return $ name ; } $ name = $ this -> normalizeName ( $ name ) ; if ( isset ( $ this -> cache [ $ name ] ) ) { return $ this -> cache [ $ name ] ; } try { $ found = $ this -> finder -> find ( $ name ) ; $ this -> cache [ $ name ] = $ found [ 'path' ] ; } catch ( InvalidArgumentException $ exception ) { throw new LoaderError ( $ exception -> getMessage ( ) ) ; } return $ this -> cache [ $ name ] ; }

Return path to template without the need for the extension.

@param string $name

@throws \Twig\Error\LoaderError

@return string

Return path to template without the need for the extension .


protected function normalizeName(string $name): string
    {
        if ($this->files->getExtension($name) === $this->extension) {
            $name = \mb_substr($name, 0, -(\mb_strlen($this->extension) + 1));
        }

        return $name;
    }

protected function normalizeName ( string $ name ) : string { if ( $ this -> files -> getExtension ( $ name ) === $ this -> extension ) { $ name = \ mb_substr ( $ name , 0 , - ( \ mb_strlen ( $ this -> extension ) + 1 ) ) ; } return $ name ; }

Normalize the Twig template name to a name the ViewFinder can use.

@param string $name

@return string

Normalize the Twig template name to a name the ViewFinder can use .


protected function parseView($view): array
    {
        if (\is_string($view)) {
            return [$view, null, null];
        }

        // If the given view is an array with numeric keys, we will just assume that
        // both a "pretty" and "plain" view were provided, so we will return this
        // array as is, since must should contain both views with numeric keys.
        if (\is_array($view) && isset($view[0])) {
            return [$view[0], $view[1], null];
        }

        // If the view is an array, but doesn't contain numeric keys, we will assume
        // the the views are being explicitly specified and will extract them via
        // named keys instead, allowing the developers to use one or the other.
        if (\is_array($view)) {
            return [
                $view['html'] ?? null,
                $view['text'] ?? null,
                $view['raw'] ?? null,
            ];
        }

        throw new UnexpectedValueException('Invalid view.');
    }

Parse the given view name or array.

@param array|string $view

@throws \Viserio\Component\Contract\Mail\Exception\UnexpectedValueException

@return array


protected function addContent(
        MessageContract $message,
        ?string $view,
        ?string $plain,
        ?string $raw,
        array $data
    ): void {
        if ($view !== null) {
            $message->setBody($this->createView($view, $data), 'text/html');
        }

        if ($plain !== null) {
            $method = $view !== null ? 'addPart' : 'setBody';

            $message->{$method}($this->createView($plain, $data), 'text/plain');
        }

        if ($raw !== null) {
            $method = ($view !== null || $plain !== null) ? 'addPart' : 'setBody';

            $message->{$method}($raw, 'text/plain');
        }
    }

protected function addContent ( MessageContract $ message , ? string $ view , ? string $ plain , ? string $ raw , array $ data ) : void { if ( $ view !== null ) { $ message -> setBody ( $ this -> createView ( $ view , $ data ) , 'text/html' ) ; } if ( $ plain !== null ) { $ method = $ view !== null ? 'addPart' : 'setBody' ; $ message -> { $ method } ( $ this -> createView ( $ plain , $ data ) , 'text/plain' ) ; } if ( $ raw !== null ) { $ method = ( $ view !== null || $ plain !== null ) ? 'addPart' : 'setBody' ; $ message -> { $ method } ( $ raw , 'text/plain' ) ; } }

Add the content to a given message.

@param \Viserio\Component\Contract\Mail\Message $message
@param null|string                              $view
@param null|string                              $plain
@param null|string                              $raw
@param array                                    $data


protected function sendSwiftMessage(Swift_Mime_SimpleMessage $message): int
    {
        if (! $this->shouldSendMessage($message)) {
            return 0;
        }

        try {
            return $this->swift->send($message, $this->failedRecipients);
        } finally {
            $this->forceReconnecting();
        }
    }

protected function sendSwiftMessage ( Swift_Mime_SimpleMessage $ message ) : int { if ( ! $ this -> shouldSendMessage ( $ message ) ) { return 0 ; } try { return $ this -> swift -> send ( $ message , $ this -> failedRecipients ) ; } finally { $ this -> forceReconnecting ( ) ; } }

Send a Swift Message instance.

@param \Swift_Mime_SimpleMessage $message

@return int


protected function shouldSendMessage(Swift_Mime_SimpleMessage $message): bool
    {
        if (! $this->eventManager) {
            return true;
        }

        return $this->eventManager->trigger(new MessageSendingEvent($this, $message)) !== false;
    }

protected function shouldSendMessage ( Swift_Mime_SimpleMessage $ message ) : bool { if ( ! $ this -> eventManager ) { return true ; } return $ this -> eventManager -> trigger ( new MessageSendingEvent ( $ this , $ message ) ) !== false ; }

Determines if the message can be sent.

@param \Swift_Mime_SimpleMessage $message

@return bool


protected function createMessage(): MessageContract
    {
        $message = new Message($this->swift->createMessage());

        // If a global from address has been specified we will set it on every message
        // instances so the developer does not have to repeat themselves every time
        // they create a new message. We will just go ahead and push the address.
        if (isset($this->from['address'])) {
            $message->from($this->from['address'], $this->from['name']);
        }

        // When a global reply address was specified we will set this on every message
        // instance so the developer does not have to repeat themselves every time
        // they create a new message. We will just go ahead and push this address.
        if (! empty($this->replyTo['address'])) {
            $message->replyTo($this->replyTo['address'], $this->replyTo['name']);
        }

        return $message;
    }

Create a new message instance.

@return \Viserio\Component\Contract\Mail\Message


protected function callMessageBuilder($callback, MessageContract $message)
    {
        if ($callback instanceof Closure) {
            return $callback($message);
        }

        if ($this->container !== null) {
            return $this->getInvoker()->call($callback)->mail($message);
        }

        throw new InvalidArgumentException('Callback is not valid.');
    }

protected
function
callMessageBuilder
(
$
callback
,
MessageContract
$
message
)
{
if
(
$
callback
instanceof
Closure
)
{
return
$
callback
(
$
message
)
;
}
if
(
$
this
->
container
!==
)
{
return
$
this
->
getInvoker
(
)
->
call
(
$
callback
)
->
mail
(
$
message
)
;
}
throw
new
InvalidArgumentException
(
'Callback is not valid.'
)
;
}

Call the provided message builder.

@param null|\Closure|string                     $callback
@param \Viserio\Component\Contract\Mail\Message $message

@throws \InvalidArgumentException

@return mixed


protected function createView(string $view, array $data): string
    {
        if ($this->viewFactory !== null) {
            return $this->viewFactory->create($view, $data)->render();
        }

        return \vsprintf($view, $data);
    }

protected function createView ( string $ view , array $ data ) : string { if ( $ this -> viewFactory !== null ) { return $ this -> viewFactory -> create ( $ view , $ data ) -> render ( ) ; } return \ vsprintf ( $ view , $ data ) ; }

Creates a view string for the email body.

@param string $view
@param array  $data

@return string

Creates a view string for the email body .


protected function handleFound(
        RouteCollectionContract $routes,
        ServerRequestInterface $request,
        string $identifier,
        array $segments
    ): ResponseInterface {
        $route = $routes->match($identifier);

        foreach ($segments as $key => $value) {
            $route->addParameter($key, \rawurldecode($value));
        }

        // Add route to the request's attributes in case a middleware or handler needs access to the route.
        $request = $request->withAttribute('_route', $route);

        $this->current = $route;

        if ($this->eventManager !== null) {
            $this->eventManager->trigger(new RouteMatchedEvent($this, $route, $request));
        }

        return $this->runRoute($route, $request);
    }

Handle dispatching of a found route.

@param \Viserio\Component\Contract\Routing\RouteCollection $routes
@param \Psr\Http\Message\ServerRequestInterface            $request
@param string                                              $identifier
@param array                                               $segments

@return \Psr\Http\Message\ResponseInterface


protected function prepareUriPath(string $path): string
    {
        $path = '/' . \ltrim($path, '/');

        if (\strlen($path) !== 1 && \substr($path, -1) === '/') {
            $path = \substr_replace($path, '', -1);
        }

        return $path;
    }

protected function prepareUriPath ( string $ path ) : string { $ path = '/' . \ ltrim ( $ path , '/' ) ; if ( \ strlen ( $ path ) !== 1 && \ substr ( $ path , - 1 ) === '/' ) { $ path = \ substr_replace ( $ path , '' , - 1 ) ; } return $ path ; }

Prepare the request uri path.

@param string $path

@return string


protected function generateRouterFile(RouteCollectionContract $routes): void
    {
        $routerCompiler = new RouteTreeCompiler(new RouteTreeBuilder(), new RouteTreeOptimizer());
        $closure        = $routerCompiler->compile($routes->getRoutes());

        \file_put_contents($this->path, $closure, \LOCK_EX);
    }

protected function generateRouterFile ( RouteCollectionContract $ routes ) : void { $ routerCompiler = new RouteTreeCompiler ( new RouteTreeBuilder ( ) , new RouteTreeOptimizer ( ) ) ; $ closure = $ routerCompiler -> compile ( $ routes -> getRoutes ( ) ) ; \ file_put_contents ( $ this -> path , $ closure , \ LOCK_EX ) ; }

Generates a router file with all routes.

@param \Viserio\Component\Contract\Routing\RouteCollection $routes

@return void

Generates a router file with all routes .


private static function generateDirectory(string $dir): void
    {
        if (\is_dir($dir) && \is_writable($dir)) {
            return;
        }

        if (! @\mkdir($dir, 0777, true) || ! \is_writable($dir)) {
            throw new RuntimeException(\sprintf(
                'Route cache directory [%s] cannot be created or is write protected.',
                $dir
            ));
        }
    }

Generate a cache directory.

@param string $dir

@throws \Viserio\Component\Contract\Routing\Exception\RuntimeException

@return void


protected function getPath(string $file): string
    {
        foreach ($this->directories as $directory) {
            $dirFile = $directory . \DIRECTORY_SEPARATOR . $file;

            if (\file_exists($dirFile)) {
                return $directory . \DIRECTORY_SEPARATOR;
            }
        }

        return '';
    }

protected function getPath ( string $ file ) : string { foreach ( $ this -> directories as $ directory ) { $ dirFile = $ directory . \ DIRECTORY_SEPARATOR . $ file ; if ( \ file_exists ( $ dirFile ) ) { return $ directory . \ DIRECTORY_SEPARATOR ; } } return '' ; }

Get the data path for a file.

@param string $file

@return string


protected function checkOption(?array $options): void
    {
        if (isset($options['tag'])) {
            return;
        }

        if (isset($options['group'])) {
            return;
        }

        if ($options !== null) {
            throw new NotSupportedException('Only the options "tag" and "group" are supported.');
        }
    }

Check if the right option are given.

@param null|array $options

@throws \Viserio\Component\Contract\Parser\Exception\NotSupportedException

@return void


protected function getParser(?array $options): Parser
    {
        if (($tag = $options['tag'] ?? null) !== null) {
            $class = self::TAG_PARSER;

            return (new $class())->setTag($tag);
        }

        if (($group = $options['group'] ?? null) !== null) {
            $class = self::GROUP_PARSER;

            return (new $class())->setGroup($group);
        }

        return new Parser();
    }

protected function getParser ( ? array $ options ) : Parser { if ( ( $ tag = $ options [ 'tag' ] ?? null ) !== null ) { $ class = self :: TAG_PARSER ; return ( new $ class ( ) ) -> setTag ( $ tag ) ; } if ( ( $ group = $ options [ 'group' ] ?? null ) !== null ) { $ class = self :: GROUP_PARSER ; return ( new $ class ( ) ) -> setGroup ( $ group ) ; } return new Parser ( ) ; }

Get the right parser.

@param null|array $options

@return \Viserio\Component\Parser\Parser


public function getRequire(string $path)
    {
        $path = $this->getTransformedPath($path);

        if ($this->isFile($path) && $this->has($path)) {
            return require $path;
        }

        throw new FileNotFoundException($path);
    }

public function getRequire ( string $ path ) { $ path = $ this -> getTransformedPath ( $ path ) ; if ( $ this -> isFile ( $ path ) && $ this -> has ( $ path ) ) { return require $ path ; } throw new FileNotFoundException ( $ path ) ; }

Require file.

@param string $path

@throws \Viserio\Component\Contract\Filesystem\Exception\FileNotFoundException

@return mixed


public function requireOnce(string $path)
    {
        $path = $this->getTransformedPath($path);

        if ($this->isFile($path) && $this->has($path)) {
            require_once $path;
        }

        throw new FileNotFoundException($path);
    }

public function requireOnce ( string $ path ) { $ path = $ this -> getTransformedPath ( $ path ) ; if ( $ this -> isFile ( $ path ) && $ this -> has ( $ path ) ) { require_once $ path ; } throw new FileNotFoundException ( $ path ) ; }

Require file once.

@param string $path

@throws \Viserio\Component\Contract\Filesystem\Exception\FileNotFoundException

@return mixed

@codeCoverageIgnore


public function link(string $target, string $link): ?bool
    {
        $target = $this->getTransformedPath($target);
        $link   = $this->getTransformedPath($link);

        if (! $this->isWindows()) {
            return \symlink($target, $link);
        }

        $mode   = $this->isDirectory($target) ? 'J' : 'H';
        $output = $return = false;

        \exec("mklink /{$mode} \"{$link}\" \"{$target}\"", $output, $return);

        return $return;
    }

Create a hard link to the target file or directory.

@param string $target
@param string $link

@return null|bool

@codeCoverageIgnore

Create a hard link to the target file or directory .


public function setDirectories(array $directories): self
    {
        foreach ($directories as $directory) {
            $this->addDirectory($directory);
        }

        return $this;
    }

public function setDirectories ( array $ directories ) : self { foreach ( $ directories as $ directory ) { $ this -> addDirectory ( $ directory ) ; } return $ this ; }

Set directories.

@param array $directories

@return $this


public function addDirectory(string $directory): self
    {
        if (! \in_array($directory, $this->directories, true)) {
            $this->directories[] = $directory;
        }

        return $this;
    }

public function addDirectory ( string $ directory ) : self { if ( ! \ in_array ( $ directory , $ this -> directories , true ) ) { $ this -> directories [ ] = $ directory ; } return $ this ; }

Add directory.

@param string $directory

@return $this


public function import(string $file): self
    {
        $loader = $this->getLoader();
        $loader->setDirectories($this->directories);

        $langFile = $loader->load($file);

        if (! isset($langFile['lang'])) {
            throw new InvalidArgumentException(\sprintf('File [%s] cant be imported. Key for language is missing.', $file));
        }

        $this->addMessageCatalogue(new MessageCatalogue($langFile['lang'], $langFile));

        return $this;
    }

Import a language from file.

@param string $file

@throws \Viserio\Component\Contract\Translation\Exception\InvalidArgumentException

@return $this


public function addMessageCatalogue(MessageCatalogueContract $messageCatalogue): self
    {
        $locale = $messageCatalogue->getLocale();

        if ($fallback = $this->getLanguageFallback($messageCatalogue->getLocale())) {
            $messageCatalogue->addFallbackCatalogue($fallback);
        } elseif ($this->defaultFallback !== null) {
            $messageCatalogue->addFallbackCatalogue($this->defaultFallback);
        }

        $translation = new Translator($messageCatalogue, $this->formatter);

        $translation->setLogger($this->logger);

        $this->translations[$locale] = $translation;

        return $this;
    }

public function addMessageCatalogue ( MessageCatalogueContract $ messageCatalogue ) : self { $ locale = $ messageCatalogue -> getLocale ( ) ; if ( $ fallback = $ this -> getLanguageFallback ( $ messageCatalogue -> getLocale ( ) ) ) { $ messageCatalogue -> addFallbackCatalogue ( $ fallback ) ; } elseif ( $ this -> defaultFallback !== null ) { $ messageCatalogue -> addFallbackCatalogue ( $ this -> defaultFallback ) ; } $ translation = new Translator ( $ messageCatalogue , $ this -> formatter ) ; $ translation -> setLogger ( $ this -> logger ) ; $ this -> translations [ $ locale ] = $ translation ; return $ this ; }

Add message catalogue.

@param \Viserio\Component\Contract\Translation\MessageCatalogue $messageCatalogue

@return $this


public function setLanguageFallback(string $lang, MessageCatalogueContract $fallback): self
    {
        $this->langFallback[$lang] = $fallback;

        return $this;
    }

public function setLanguageFallback ( string $ lang , MessageCatalogueContract $ fallback ) : self { $ this -> langFallback [ $ lang ] = $ fallback ; return $ this ; }

Set fallback for a language.

@param string                                                   $lang
@param \Viserio\Component\Contract\Translation\MessageCatalogue $fallback

@throws \RuntimeException

@return $this


public function getLanguageFallback(string $lang): ?MessageCatalogueContract
    {
        if (isset($this->langFallback[$lang])) {
            return $this->langFallback[$lang];
        }

        return null;
    }

public function getLanguageFallback ( string $ lang ) : ? MessageCatalogueContract { if ( isset ( $ this -> langFallback [ $ lang ] ) ) { return $ this -> langFallback [ $ lang ] ; } return null ; }

Get fallback for a language.

@param string $lang

@return null|\Viserio\Component\Contract\Translation\MessageCatalogue


public function addPresenter(string $key, PresenterContract $presenter): self
    {
        $this->presenter[$key] = $presenter;

        return $this;
    }

public function addPresenter ( string $ key , PresenterContract $ presenter ) : self { $ this -> presenter [ $ key ] = $ presenter ; return $ this ; }

Add a new presenter.

@param string                                           $key
@param \Viserio\Component\Contract\Pagination\Presenter $presenter

@return $this


protected function checkForMorePages(): void
    {
        $this->hasMore = \count($this->items) > $this->itemCountPerPage;

        $this->items = $this->items->slice(0, $this->itemCountPerPage);
    }

protected function checkForMorePages ( ) : void { $ this -> hasMore = \ count ( $ this -> items ) > $ this -> itemCountPerPage ; $ this -> items = $ this -> items -> slice ( 0 , $ this -> itemCountPerPage ) ; }

Check for more pages. The last item will be sliced off.

@return void

Check for more pages . The last item will be sliced off .


public function getDisplayAddress(): ?string
    {
        if ('0.0.0.0' !== $this->getHostname()) {
            return null;
        }

        if (false === $localHostname = \gethostname()) {
            return null;
        }

        return \gethostbyname($localHostname) . ':' . $this->getPort();
    }

public function getDisplayAddress ( ) : ? string { if ( '0.0.0.0' !== $ this -> getHostname ( ) ) { return null ; } if ( false === $ localHostname = \ gethostname ( ) ) { return null ; } return \ gethostbyname ( $ localHostname ) . ':' . $ this -> getPort ( ) ; }

Contains resolved hostname if available.

@return null|string

Contains resolved hostname if available .


private static function findFrontController(string $documentRoot, string $env): string
    {
        $fileNames = ['index_' . $env . '.php', 'index.php'];

        foreach ($fileNames as $fileName) {
            if (\file_exists($documentRoot . \DIRECTORY_SEPARATOR . $fileName)) {
                return $fileName;
            }
        }

        throw new InvalidArgumentException(
            \sprintf(
                'Unable to find the front controller under [%s] (none of these files exist: [%s]).',
                $documentRoot,
                \implode(', ', $fileNames)
            )
        );
    }

Finds the front controller in root path.

@param string $documentRoot
@param string $env

@throws \Viserio\Component\Contract\WebServer\Exception\InvalidArgumentException

@return string

Finds the front controller in root path .


private static function findHostnameAndPort(array $config): array
    {
        if ($config['host'] === null) {
            $config['host'] = '127.0.0.1';
            $config['port'] = self::findBestPort($config['host']);
        } elseif (isset($config['host'], $config['port']) && $config['port'] !== null && $config['host'] === '*') {
            $config['host'] = '0.0.0.0';
        } elseif ($config['port'] === null) {
            $config['port'] = self::findBestPort($config['host']);
        }

        if (! \ctype_digit((string) $config['port'])) {
            throw new InvalidArgumentException(\sprintf('Port [%s] is not valid.', (string) $config['port']));
        }

        $config['address'] = $config['host'] . ':' . $config['port'];

        return $config;
    }

private
static
function
findHostnameAndPort
(
array
$
config
)
:
array
{
if
(
$
config
[
'host'
]
===
)
{
$
config
[
'host'
]
=
'127.0.0.1'
;
$
config
[
'port'
]
=
self
::
findBestPort
(
$
config
[
'host'
]
)
;
}
elseif
(
isset
(
$
config
[
'host'
]
,
$
config
[
'port'
]
)
&&
$
config
[
'port'
]
!==
&&
$
config
[
'host'
]
===
'*'
)
{
$
config
[
'host'
]
=
'0.0.0.0'
;
}
elseif
(
$
config
[
'port'
]
===
)
{
$
config
[
'port'
]
=
self
::
findBestPort
(
$
config
[
'host'
]
)
;
}
if
(
!
\
ctype_digit
(
(
string
)
$
config
[
'port'
]
)
)
{
throw
new
InvalidArgumentException
(
\
sprintf
(
'Port [%s] is not valid.'
,
(
string
)
$
config
[
'port'
]
)
)
;
}
$
config
[
'address'
]
=
$
config
[
'host'
]
.
':'
.
$
config
[
'port'
]
;
return
$
config
;
}

Finds a host and port.

@param array $config

@throws \Viserio\Component\Contract\WebServer\Exception\InvalidArgumentException

@return array


private static function findBestPort(string $host): string
    {
        $port = 8000;

        while (false !== $fp = @\fsockopen($host, $port, $errno, $errstr, 1)) {
            \fclose($fp);

            if ($port++ >= 8100) {
                throw new RuntimeException('Unable to find a port available to run the web server.');
            }
        }

        return (string) $port;
    }

Searching for the port between 8000 and 8100.

@param string $host

@return string

Searching for the port between 8000 and 8100 .


public static function escape(string $raw): string
    {
        $flags = \ENT_QUOTES;

        if (\defined('ENT_SUBSTITUTE')) {
            $flags |= \ENT_SUBSTITUTE;
        }

        $raw = \str_replace(\chr(9), '    ', $raw);

        return \htmlspecialchars($raw, $flags);
    }

public
static
function
escape
(
string
$
raw
)
:
string
{
$
flags
=
\
ENT_QUOTES
;
if
(
\
defined
(
'ENT_SUBSTITUTE'
)
)
{
$
flags
|=
\
ENT_SUBSTITUTE
;
}
$
raw
=
\
str_replace
(
\
chr
(
9
)
,
'    '
,
$
raw
)
;
return
\
htmlspecialchars
(
$
raw
,
$
flags
)
;
}

Escapes a string for output in an HTML document.

@param string $raw

@return string

Escapes a string for output in an HTML document .


public function getSortedData(): array
    {
        $data = [
            'menus'  => [],
            'panels' => [],
            'icons'  => $this->icons,
        ];

        foreach ($this->collectors as $name => $collector) {
            $collector = $collector['collector'];

            if ($collector instanceof TooltipAwareContract) {
                $data['menus'][$collector->getName()] = [
                    'menu'     => $collector->getMenu(),
                    'tooltip'  => $collector->getTooltip(),
                    'position' => $collector->getMenuPosition(),
                ];
            } else {
                $data['menus'][$collector->getName()] = [
                    'menu'     => $collector->getMenu(),
                    'position' => $collector->getMenuPosition(),
                ];
            }

            if ($collector instanceof PanelAwareContract) {
                $class = '';
                $panel = $collector->getPanel();

                // @codeCoverageIgnoreStart
                if (\mb_strpos($panel, '<div class="profiler-tabs') !== false) {
                    $class = ' profiler-body-has-tabs';
                } elseif (\mb_strpos($panel, '<select class="content-selector"') !== false) {
                    $class = ' profiler-body-has-selector';
                } elseif (\mb_strpos($panel, 'getName()] = [
                    'content' => $panel,
                    'class'   => $class,
                ];
            }
        }

        return $data;
    }

public
function
getSortedData
(
)
:
array
{
$
data
=
[
'menus'
=>
[
]
,
'panels'
=>
[
]
,
'icons'
=>
$
this
->
icons
,
]
;
foreach
(
$
this
->
collectors
as
$
name
=>
$
collector
)
{
$
collector
=
$
collector
[
'collector'
]
;
if
(
$
collector
instanceof
TooltipAwareContract
)
{
$
data
[
'menus'
]
[
$
collector
->
getName
(
)
]
=
[
'menu'
=>
$
collector
->
getMenu
(
)
,
'tooltip'
=>
$
collector
->
getTooltip
(
)
,
'position'
=>
$
collector
->
getMenuPosition
(
)
,
]
;
}
else
{
$
data
[
'menus'
]
[
$
collector
->
getName
(
)
]
=
[
'menu'
=>
$
collector
->
getMenu
(
)
,
'position'
=>
$
collector
->
getMenuPosition
(
)
,
]
;
}
if
(
$
collector
instanceof
PanelAwareContract
)
{
$
class
=
''
;
$
panel
=
$
collector
->
getPanel
(
)
;
// @codeCoverageIgnoreStart
if
(
\
mb_strpos
(
$
panel
,
'<div class="profiler-tabs'
)
!==
false
)
{
$
class
=
' profiler-body-has-tabs'
;
}
elseif
(
\
mb_strpos
(
$
panel
,
'<select class="content-selector"'
)
!==
false
)
{
$
class
=
' profiler-body-has-selector'
;
}
elseif
(
\
mb_strpos
(
$
panel
,
'
getName
(
)
]
=
[
'content'
=>
$
panel
,
'class'
=>
$
class
,
]
;
}
}
return
$
data
;
}

Sort all datas from collectors.

@return array


private function createAppendStream(array $elements): StreamInterface
    {
        $stream = new AppendStream();

        foreach ($elements as $element) {
            $this->addElement($stream, $element);
        }

        // Add the trailing boundary with CRLF
        $stream->addStream(Util::createStreamFor("--{$this->boundary}--\r\n"));

        return $stream;
    }

private
function
createAppendStream
(
array
$
elements
)
:
StreamInterface
{
$
stream
=
new
AppendStream
(
)
;
foreach
(
$
elements
as
$
element
)
{
$
this
->
addElement
(
$
stream
,
$
element
)
;
}
// Add the trailing boundary with CRLF
$
stream
->
addStream
(
Util
::
createStreamFor
(
"--{$this->boundary}--\r\n"
)
)
;
return
$
stream
;
}

Create the aggregate stream that will be used to upload the POST data.

@param array $elements

@return \Psr\Http\Message\StreamInterface

Create the aggregate stream that will be used to upload the POST data .


protected function parseTokens(array $tokens): array
    {
        $tokenIterator = new ArrayIterator($tokens);
        $messages      = [];

        for ($key = 0; $key < $tokenIterator->count(); $key++) {
            foreach ($this->sequences as $sequence) {
                $message = '';
                $domain  = $this->defaultDomain;
                $tokenIterator->seek($key);

                foreach ($sequence as $sequenceKey => $item) {
                    $this->seekToNextRelevantToken($tokenIterator);

                    if ($this->normalizeToken($tokenIterator->current()) === $item) {
                        $tokenIterator->next();

                        continue;
                    }

                    if (self::MESSAGE_TOKEN === $item) {
                        $message = $this->getValue($tokenIterator);

                        if (\count($sequence) === ($sequenceKey + 1)) {
                            break;
                        }
                    } elseif (self::METHOD_ARGUMENTS_TOKEN === $item) {
                        $this->skipMethodArgument($tokenIterator);
                    } elseif (self::DOMAIN_TOKEN === $item) {
                        $domain = $this->getValue($tokenIterator);

                        break;
                    } else {
                        break;
                    }
                }

                if ($message) {
                    $messages[$domain][\trim($message)] = $this->prefix . \trim($message);

                    break;
                }
            }
        }

        return $messages;
    }

protected function parseTokens ( array $ tokens ) : array { $ tokenIterator = new ArrayIterator ( $ tokens ) ; $ messages = [ ] ; for ( $ key = 0 ; $ key < $ tokenIterator -> count ( ) ; $ key ++ ) { foreach ( $ this -> sequences as $ sequence ) { $ message = '' ; $ domain = $ this -> defaultDomain ; $ tokenIterator -> seek ( $ key ) ; foreach ( $ sequence as $ sequenceKey => $ item ) { $ this -> seekToNextRelevantToken ( $ tokenIterator ) ; if ( $ this -> normalizeToken ( $ tokenIterator -> current ( ) ) === $ item ) { $ tokenIterator -> next ( ) ; continue ; } if ( self :: MESSAGE_TOKEN === $ item ) { $ message = $ this -> getValue ( $ tokenIterator ) ; if ( \ count ( $ sequence ) === ( $ sequenceKey + 1 ) ) { break ; } } elseif ( self :: METHOD_ARGUMENTS_TOKEN === $ item ) { $ this -> skipMethodArgument ( $ tokenIterator ) ; } elseif ( self :: DOMAIN_TOKEN === $ item ) { $ domain = $ this -> getValue ( $ tokenIterator ) ; break ; } else { break ; } } if ( $ message ) { $ messages [ $ domain ] [ \ trim ( $ message ) ] = $ this -> prefix . \ trim ( $ message ) ; break ; } } } return $ messages ; }

Extracts trans message from PHP tokens.

@param array $tokens

@return array

Extracts trans message from PHP tokens .


private function seekToNextRelevantToken(Iterator $tokenIterator): void
    {
        for (; $tokenIterator->valid(); $tokenIterator->next()) {
            $token = $tokenIterator->current();

            if ($token[0] !== \T_WHITESPACE) {
                break;
            }
        }
    }

private function seekToNextRelevantToken ( Iterator $ tokenIterator ) : void { for ( ; $ tokenIterator -> valid ( ) ; $ tokenIterator -> next ( ) ) { $ token = $ tokenIterator -> current ( ) ; if ( $ token [ 0 ] !== \ T_WHITESPACE ) { break ; } } }

Seeks to a non-whitespace token.

@param \Iterator $tokenIterator

@return void


private function getValue(Iterator $tokenIterator): string
    {
        $message  = '';
        $docToken = '';

        for (; $tokenIterator->valid(); $tokenIterator->next()) {
            $t = $tokenIterator->current();

            if (! isset($t[1])) {
                break;
            }

            switch ($t[0]) {
                case \T_START_HEREDOC:
                    $docToken = $t[1];

                    break;
                case \T_ENCAPSED_AND_WHITESPACE:
                case \T_CONSTANT_ENCAPSED_STRING:
                    $message .= $t[1];

                    break;
                case \T_END_HEREDOC:
                    return ScalarString::parseDocString($docToken, $message);

                default:
                    break 2;
            }
        }

        if ($message) {
            $message = ScalarString::parse($message);
        }

        return $message;
    }

private function getValue ( Iterator $ tokenIterator ) : string { $ message = '' ; $ docToken = '' ; for ( ; $ tokenIterator -> valid ( ) ; $ tokenIterator -> next ( ) ) { $ t = $ tokenIterator -> current ( ) ; if ( ! isset ( $ t [ 1 ] ) ) { break ; } switch ( $ t [ 0 ] ) { case \ T_START_HEREDOC : $ docToken = $ t [ 1 ] ; break ; case \ T_ENCAPSED_AND_WHITESPACE : case \ T_CONSTANT_ENCAPSED_STRING : $ message .= $ t [ 1 ] ; break ; case \ T_END_HEREDOC : return ScalarString :: parseDocString ( $ docToken , $ message ) ; default : break 2 ; } } if ( $ message ) { $ message = ScalarString :: parse ( $ message ) ; } return $ message ; }

Extracts the message from the iterator while the tokens
match allowed message tokens.

@param \Iterator $tokenIterator

@return string

Extracts the message from the iterator while the tokens match allowed message tokens .


public static function createTraceablePDODecorator(
        ContainerInterface $container,
        ?PDO $pdo = null
    ): ?TraceablePDODecorater {
        if ($pdo === null) {
            return null;
        }

        return new TraceablePDODecorater($pdo);
    }

public static function createTraceablePDODecorator ( ContainerInterface $ container , ? PDO $ pdo = null ) : ? TraceablePDODecorater { if ( $ pdo === null ) { return null ; } return new TraceablePDODecorater ( $ pdo ) ; }

Extend PDO with our TraceablePDODecorater.

@param \Psr\Container\ContainerInterface $container
@param null|\PDO                         $pdo

@return null|\Viserio\Component\Profiler\DataCollector\Bridge\PDO\TraceablePDODecorater

Extend PDO with our TraceablePDODecorater .


protected function decrypt(ServerRequestInterface $request): ServerRequestInterface
    {
        $cookies = RequestCookies::fromRequest($request);

        /** @var Cookie $cookie */
        foreach ($cookies->getAll() as $cookie) {
            $name = $cookie->getName();

            if ($this->isDisabled($name)) {
                continue;
            }

            try {
                $decryptedValue = Crypto::decrypt($cookie->getValue(), $this->key);
                $cookies        = $cookies->forget($name);
                $cookie         = $cookie->withValue($decryptedValue->getString());

                $cookies = $cookies->add($cookie);
            } catch (InvalidMessage $exception) {
                $cookies = $cookies->add(new Cookie($name, null));
            }
        }

        return $cookies->renderIntoCookieHeader($request);
    }

protected
function
decrypt
(
ServerRequestInterface
$
request
)
:
ServerRequestInterface
{
$
cookies
=
RequestCookies
::
fromRequest
(
$
request
)
;
/** @var Cookie $cookie */
foreach
(
$
cookies
->
getAll
(
)
as
$
cookie
)
{
$
name
=
$
cookie
->
getName
(
)
;
if
(
$
this
->
isDisabled
(
$
name
)
)
{
continue
;
}
try
{
$
decryptedValue
=
Crypto
::
decrypt
(
$
cookie
->
getValue
(
)
,
$
this
->
key
)
;
$
cookies
=
$
cookies
->
forget
(
$
name
)
;
$
cookie
=
$
cookie
->
withValue
(
$
decryptedValue
->
getString
(
)
)
;
$
cookies
=
$
cookies
->
add
(
$
cookie
)
;
}
catch
(
InvalidMessage
$
exception
)
{
$
cookies
=
$
cookies
->
add
(
new
Cookie
(
$
name
,
)
)
;
}
}
return
$
cookies
->
renderIntoCookieHeader
(
$
request
)
;
}

Decrypt the cookies on the request.

@param \Psr\Http\Message\ServerRequestInterface $request

@return \Psr\Http\Message\ServerRequestInterface


protected function encrypt(ResponseInterface $response): ResponseInterface
    {
        $cookies = ResponseCookies::fromResponse($response);

        /** @var SetCookie $cookie */
        foreach ($cookies->getAll() as $cookie) {
            $name = $cookie->getName();

            if ($this->isDisabled($name)) {
                continue;
            }

            $cookies        = $cookies->forget($name);
            $encryptedValue = Crypto::encrypt(
                new HiddenString($cookie->getValue()),
                $this->key
            );

            $cookies = $cookies->add(
                $this->duplicate(
                    $cookie,
                    $encryptedValue
                )
            );
        }

        return $cookies->renderIntoSetCookieHeader($response);
    }

protected
function
encrypt
(
ResponseInterface
$
response
)
:
ResponseInterface
{
$
cookies
=
ResponseCookies
::
fromResponse
(
$
response
)
;
/** @var SetCookie $cookie */
foreach
(
$
cookies
->
getAll
(
)
as
$
cookie
)
{
$
name
=
$
cookie
->
getName
(
)
;
if
(
$
this
->
isDisabled
(
$
name
)
)
{
continue
;
}
$
cookies
=
$
cookies
->
forget
(
$
name
)
;
$
encryptedValue
=
Crypto
::
encrypt
(
new
HiddenString
(
$
cookie
->
getValue
(
)
)
,
$
this
->
key
)
;
$
cookies
=
$
cookies
->
add
(
$
this
->
duplicate
(
$
cookie
,
$
encryptedValue
)
)
;
}
return
$
cookies
->
renderIntoSetCookieHeader
(
$
response
)
;
}

Encrypt the cookies on an outgoing response.

@param \Psr\Http\Message\ResponseInterface $response

@return \Psr\Http\Message\ResponseInterface

Encrypt the cookies on an outgoing response .


protected function duplicate(CookieContract $cookie, string $value): CookieContract
    {
        return new SetCookie(
            $cookie->getName(),
            $value,
            $cookie->getExpiresTime(),
            $cookie->getPath(),
            $cookie->getDomain(),
            $cookie->isSecure(),
            $cookie->isHttpOnly()
        );
    }

protected function duplicate ( CookieContract $ cookie , string $ value ) : CookieContract { return new SetCookie ( $ cookie -> getName ( ) , $ value , $ cookie -> getExpiresTime ( ) , $ cookie -> getPath ( ) , $ cookie -> getDomain ( ) , $ cookie -> isSecure ( ) , $ cookie -> isHttpOnly ( ) ) ; }

Duplicate a cookie with a new value.

@param \Viserio\Component\Contract\Cookie\Cookie $cookie
@param string                                    $value

@return \Viserio\Component\Contract\Cookie\Cookie


public function registerCommand(SymfonyCommand $command): void
    {
        $this->bootstrap();

        $this->getConsole()->add($command);
    }

public function registerCommand ( SymfonyCommand $ command ) : void { $ this -> bootstrap ( ) ; $ this -> getConsole ( ) -> add ( $ command ) ; }

Register the given command with the console application.

@param \Symfony\Component\Console\Command\Command $command

@return void

Register the given command with the console application .


protected function getConsole(): Cerebro
    {
        if ($this->console === null) {
            $console = $this->getContainer()->get(Cerebro::class);

            $console->setVersion($this->resolvedOptions['version']);
            $console->setName($this->resolvedOptions['console_name']);

            return $this->console = $console;
        }

        return $this->console;
    }

protected function getConsole ( ) : Cerebro { if ( $ this -> console === null ) { $ console = $ this -> getContainer ( ) -> get ( Cerebro :: class ) ; $ console -> setVersion ( $ this -> resolvedOptions [ 'version' ] ) ; $ console -> setName ( $ this -> resolvedOptions [ 'console_name' ] ) ; return $ this -> console = $ console ; } return $ this -> console ; }

Get the cerebro application instance.

@return \Viserio\Component\Console\Application


protected function initProjectDirs(): array
    {
        if ($this->projectDirs === null) {
            $jsonFile = $this->rootDir . \DIRECTORY_SEPARATOR . 'composer.json';
            $dirs     = [
                'app-dir'       => $this->rootDir . \DIRECTORY_SEPARATOR . 'app',
                'config-dir'    => $this->rootDir . \DIRECTORY_SEPARATOR . 'config',
                'database-dir'  => $this->rootDir . \DIRECTORY_SEPARATOR . 'database',
                'public-dir'    => $this->rootDir . \DIRECTORY_SEPARATOR . 'public',
                'resources-dir' => $this->rootDir . \DIRECTORY_SEPARATOR . 'resources',
                'routes-dir'    => $this->rootDir . \DIRECTORY_SEPARATOR . 'routes',
                'tests-dir'     => $this->rootDir . \DIRECTORY_SEPARATOR . 'tests',
                'storage-dir'   => $this->rootDir . \DIRECTORY_SEPARATOR . 'storage',
            ];

            if (\file_exists($jsonFile)) {
                $jsonData = \json_decode(\file_get_contents($jsonFile), true);
                $extra    = $jsonData['extra'] ?? [];

                foreach ($extra as $key => $value) {
                    if (\array_key_exists($key, $dirs)) {
                        $dirs[$key] = $this->rootDir . \DIRECTORY_SEPARATOR . \ltrim($value, '/\\');
                    }
                }
            }

            $this->projectDirs = $dirs;
        }

        return $this->projectDirs;
    }

protected function initProjectDirs ( ) : array { if ( $ this -> projectDirs === null ) { $ jsonFile = $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'composer.json' ; $ dirs = [ 'app-dir' => $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'app' , 'config-dir' => $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'config' , 'database-dir' => $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'database' , 'public-dir' => $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'public' , 'resources-dir' => $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'resources' , 'routes-dir' => $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'routes' , 'tests-dir' => $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'tests' , 'storage-dir' => $ this -> rootDir . \ DIRECTORY_SEPARATOR . 'storage' , ] ; if ( \ file_exists ( $ jsonFile ) ) { $ jsonData = \ json_decode ( \ file_get_contents ( $ jsonFile ) , true ) ; $ extra = $ jsonData [ 'extra' ] ?? [ ] ; foreach ( $ extra as $ key => $ value ) { if ( \ array_key_exists ( $ key , $ dirs ) ) { $ dirs [ $ key ] = $ this -> rootDir . \ DIRECTORY_SEPARATOR . \ ltrim ( $ value , '/\\' ) ; } } } $ this -> projectDirs = $ dirs ; } return $ this -> projectDirs ; }

Merge composer project dir settings with the default narrowspark dir settings.

@return array

Merge composer project dir settings with the default narrowspark dir settings .


protected function findNamedPathView(string $name): array
    {
        [$namespace, $view] = $this->getNamespaceSegments($name);

        return $this->findInPaths($view, $this->hints[$namespace]);
    }

protected function findNamedPathView ( string $ name ) : array { [ $ namespace , $ view ] = $ this -> getNamespaceSegments ( $ name ) ; return $ this -> findInPaths ( $ view , $ this -> hints [ $ namespace ] ) ; }

Get the path to a template with a named path.

@param string $name

@return array

Get the path to a template with a named path .


protected function getNamespaceSegments(string $name): array
    {
        $segments = \explode(FinderContract::HINT_PATH_DELIMITER, $name);

        if (\count($segments) !== 2) {
            throw new InvalidArgumentException(\sprintf('View [%s] has an invalid name.', $name));
        }

        if (! isset($this->hints[$segments[0]])) {
            throw new InvalidArgumentException(\sprintf('No hint path defined for [%s].', $segments[0]));
        }

        return $segments;
    }

protected
function
getNamespaceSegments
(
string
$
name
)
:
array
{
$
segments
=
\
explode
(
FinderContract
::
HINT_PATH_DELIMITER
,
$
name
)
;
if
(
\
count
(
$
segments
)
!==
2
)
{
throw
new
InvalidArgumentException
(
\
sprintf
(
'View [%s] has an invalid name.'
,
$
name
)
)
;
}
if
(
!
isset
(
$
this
->
hints
[
$
segments
[
0
]
]
)
)
{
throw
new
InvalidArgumentException
(
\
sprintf
(
'No hint path defined for [%s].'
,
$
segments
[
0
]
)
)
;
}
return
$
segments
;
}

Get the segments of a template with a named path.

@param string $name

@throws \Viserio\Component\Contract\View\Exception\InvalidArgumentException

@return array

Get the segments of a template with a named path .


protected function findInPaths(string $name, array $paths): array
    {
        foreach ($paths as $path) {
            foreach ($this->getPossibleViewFiles($name) as $fileInfos) {
                $viewPath = $path . \DIRECTORY_SEPARATOR . $fileInfos['file'];

                if ($this->files->has($viewPath)) {
                    return [
                        'path'      => $viewPath,
                        'name'      => $fileInfos['file'],
                        'extension' => $fileInfos['extension'],
                    ];
                }
            }
        }

        throw new InvalidArgumentException(\sprintf('View [%s] not found.', $name));
    }

protected
function
findInPaths
(
string
$
name
,
array
$
paths
)
:
array
{
foreach
(
$
paths
as
$
path
)
{
foreach
(
$
this
->
getPossibleViewFiles
(
$
name
)
as
$
fileInfos
)
{
$
viewPath
=
$
path
.
\
DIRECTORY_SEPARATOR
.
$
fileInfos
[
'file'
]
;
if
(
$
this
->
files
->
has
(
$
viewPath
)
)
{
return
[
'path'
=>
$
viewPath
,
'name'
=>
$
fileInfos
[
'file'
]
,
'extension'
=>
$
fileInfos
[
'extension'
]
,
]
;
}
}
}
throw
new
InvalidArgumentException
(
\
sprintf
(
'View [%s] not found.'
,
$
name
)
)
;
}

Find the given view in the list of paths.

@param string $name
@param array  $paths

@throws \Viserio\Component\Contract\View\Exception\InvalidArgumentException

@return array

Find the given view in the list of paths .