protected function getPossibleViewFiles(string $name): array
    {
        return \array_map(static function ($extension) use ($name) {
            return [
                'extension' => $extension,
                'file'      => \str_replace('.', \DIRECTORY_SEPARATOR, $name) . '.' . $extension,
            ];
        }, self::$extensions);
    }

protected function getPossibleViewFiles ( string $ name ) : array { return \ array_map ( static function ( $ extension ) use ( $ name ) { return [ 'extension' => $ extension , 'file' => \ str_replace ( '.' , \ DIRECTORY_SEPARATOR , $ name ) . '.' . $ extension , ] ; } , self :: $ extensions ) ; }

Get an array of possible view files.

@param string $name

@return array


public function getInfo(string $eventName): array
    {
        if ($this->stub === null) {
            $this->stub = self::$hasClassStub ? new ClassStub($this->pretty . '()', $this->listener) : $this->pretty . '()';
        }

        return [
            'priority' => $this->eventManager !== null ? $this->eventManager->getListenerPriority($eventName, $this->listener) : null,
            'pretty'   => $this->pretty,
            'stub'     => $this->stub,
        ];
    }

public function getInfo ( string $ eventName ) : array { if ( $ this -> stub === null ) { $ this -> stub = self :: $ hasClassStub ? new ClassStub ( $ this -> pretty . '()' , $ this -> listener ) : $ this -> pretty . '()' ; } return [ 'priority' => $ this -> eventManager !== null ? $ this -> eventManager -> getListenerPriority ( $ eventName , $ this -> listener ) : null , 'pretty' => $ this -> pretty , 'stub' => $ this -> stub , ] ; }

Get information's about given event.

@param string $eventName

@return array


public function renderIntoSetCookieHeader(ResponseInterface $response): ResponseInterface
    {
        $response = $response->withoutHeader('set-cookie');

        foreach ($this->cookies as $cookies) {
            $response = $response->withAddedHeader('set-cookie', (string) $cookies);
        }

        return $response;
    }

public function renderIntoSetCookieHeader ( ResponseInterface $ response ) : ResponseInterface { $ response = $ response -> withoutHeader ( 'set-cookie' ) ; foreach ( $ this -> cookies as $ cookies ) { $ response = $ response -> withAddedHeader ( 'set-cookie' , ( string ) $ cookies ) ; } return $ response ; }

Render Cookies into a response.

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

@return \Psr\Http\Message\ResponseInterface


public static function extendTwigEnvironment(
        ContainerInterface $container,
        ?TwigEnvironment $twig = null
    ): ?TwigEnvironment {
        if ($twig !== null) {
            $options = self::resolveOptions($container->get('config'));

            if ($options['collector']['twig'] === true) {
                $twig->addExtension(new ProfilerExtension(
                    $container->get(Profile::class)
                ));
            }
        }

        return $twig;
    }

public static function extendTwigEnvironment ( ContainerInterface $ container , ? TwigEnvironment $ twig = null ) : ? TwigEnvironment { if ( $ twig !== null ) { $ options = self :: resolveOptions ( $ container -> get ( 'config' ) ) ; if ( $ options [ 'collector' ] [ 'twig' ] === true ) { $ twig -> addExtension ( new ProfilerExtension ( $ container -> get ( Profile :: class ) ) ) ; } } return $ twig ; }

Wrap Twig Environment.

@param \Psr\Container\ContainerInterface $container
@param null|\Twig\Environment            $twig

@return null|\Twig\Environment


public function getMessages(): array
    {
        $messages = $this->messages;

        // sort messages by their timestamp
        \usort($messages, static function ($a, $b) {
            if ($a['time'] === $b['time']) {
                return 0;
            }

            return $a['time'] < $b['time'] ? -1 : 1;
        });

        return $messages;
    }

public
function
getMessages
(
)
:
array
{
$
messages
=
$
this
->
messages
;
// sort messages by their timestamp
\
usort
(
$
messages
,
static
function
(
$
a
,
$
b
)
{
if
(
$
a
[
'time'
]
===
$
b
[
'time'
]
)
{
return
0
;
}
return
$
a
[
'time'
]
<
$
b
[
'time'
]
1
:
1
;
}
)
;
return
$
messages
;
}

Returns collected messages.

@return array


public function addMessage($message, string $label = 'info'): void
    {
        if (! \is_string($message)) {
            $message = $this->cloneVar($message);
        }

        $this->messages[] = [
            'message' => \is_string($message) ? $message : $this->cloneVar($message),
            'label'   => $label,
            'time'    => \microtime(true),
        ];
    }

public function addMessage ( $ message , string $ label = 'info' ) : void { if ( ! \ is_string ( $ message ) ) { $ message = $ this -> cloneVar ( $ message ) ; } $ this -> messages [ ] = [ 'message' => \ is_string ( $ message ) ? $ message : $ this -> cloneVar ( $ message ) , 'label' => $ label , 'time' => \ microtime ( true ) , ] ; }

Adds a message.

A message can be anything from an object to a string.

@param mixed  $message
@param string $label

@return void


public function aliasMiddleware(string $name, $middleware)
    {
        if (isset($this->middleware[$name])) {
            throw new RuntimeException(\sprintf('Alias [%s] already exists.', $name));
        }

        if (\is_string($middleware) || \is_object($middleware)) {
            $className = $this->getMiddlewareClassName($middleware);

            if (\class_exists($className)) {
                $this->validateMiddleware($className);
            }

            $this->middleware[$name] = $middleware;

            return $this;
        }

        throw new UnexpectedValueException(\sprintf('Expected string or object; received [%s].', \gettype($middleware)));
    }

Register a short-hand name for a middleware.

@param string                                      $name
@param \Psr\Http\Server\MiddlewareInterface|string $middleware

@throws \Viserio\Component\Contract\Routing\Exception\RuntimeException         if alias exists
@throws \Viserio\Component\Contract\Routing\Exception\UnexpectedValueException if wrong type is given

@return $this

Register a short - hand name for a middleware .


private function getLogs($socket): ?\Generator
    {
        $sockets = [\fstat($socket)['size'] => $socket];
        $write   = [];

        while (true) {
            $read = $sockets;
            \stream_select($read, $write, $write, null);

            foreach ($read as $stream) {
                $size = \fstat($stream)['size'];

                if ($socket === $stream) {
                    $stream                 = \stream_socket_accept($socket);
                    $sockets[$size]         = $stream;
                } elseif (\feof($stream)) {
                    unset($sockets[$size]);

                    \fclose($stream);
                } else {
                    yield $size => \fgets($stream);
                }
            }
        }
    }

private function getLogs ( $ socket ) : ? \ Generator { $ sockets = [ \ fstat ( $ socket ) [ 'size' ] => $ socket ] ; $ write = [ ] ; while ( true ) { $ read = $ sockets ; \ stream_select ( $ read , $ write , $ write , null ) ; foreach ( $ read as $ stream ) { $ size = \ fstat ( $ stream ) [ 'size' ] ; if ( $ socket === $ stream ) { $ stream = \ stream_socket_accept ( $ socket ) ; $ sockets [ $ size ] = $ stream ; } elseif ( \ feof ( $ stream ) ) { unset ( $ sockets [ $ size ] ) ; \ fclose ( $ stream ) ; } else { yield $ size => \ fgets ( $ stream ) ; } } } }

Get collected logs.

@param resource $socket

@return null|\Generator


protected function handleViewException(Throwable $exception, int $obLevel): void
    {
        while (\ob_get_level() > $obLevel) {
            \ob_end_clean();
        }

        throw $exception;
    }

protected function handleViewException ( Throwable $ exception , int $ obLevel ) : void { while ( \ ob_get_level ( ) > $ obLevel ) { \ ob_end_clean ( ) ; } throw $ exception ; }

Handle a view exception.

@param \Throwable $exception
@param int        $obLevel

@throws \Throwable


private function getErrorException($exception): ErrorException
    {
        // @codeCoverageIgnoreStart
        if ($exception instanceof ParseError) {
            $message  = 'Parse error: ' . $exception->getMessage();
            $severity = \E_PARSE;
        } elseif ($exception instanceof TypeError) {
            $message  = 'Type error: ' . $exception->getMessage();
            $severity = \E_RECOVERABLE_ERROR;
        } else {
            $message  = $exception->getMessage();
            $severity = \E_ERROR;
        }
        // @codeCoverageIgnoreEnd

        return new ErrorException(
            $message,
            $exception->getCode(),
            $severity,
            $exception->getFile(),
            $exception->getLine()
        );
    }

private
function
getErrorException
(
$
exception
)
:
ErrorException
{
// @codeCoverageIgnoreStart
if
(
$
exception
instanceof
ParseError
)
{
$
message
=
'Parse error: '
.
$
exception
->
getMessage
(
)
;
$
severity
=
\
E_PARSE
;
}
elseif
(
$
exception
instanceof
TypeError
)
{
$
message
=
'Type error: '
.
$
exception
->
getMessage
(
)
;
$
severity
=
\
E_RECOVERABLE_ERROR
;
}
else
{
$
message
=
$
exception
->
getMessage
(
)
;
$
severity
=
\
E_ERROR
;
}
// @codeCoverageIgnoreEnd
return
new
ErrorException
(
$
message
,
$
exception
->
getCode
(
)
,
$
severity
,
$
exception
->
getFile
(
)
,
$
exception
->
getLine
(
)
)
;
}

Get a ErrorException instance.

@param \ParseError|\Throwable|\TypeError $exception

@return \ErrorException


public function getCachePath(): ?string
    {
        if ($this->realTimeStaticalProxyActivated === true && $this->cachePath === null) {
            throw new RuntimeException('Please provide a valid cache path.');
        }

        return $this->cachePath;
    }

public
function
getCachePath
(
)
:
string
{
if
(
$
this
->
realTimeStaticalProxyActivated
===
true
&&
$
this
->
cachePath
===
)
{
throw
new
RuntimeException
(
'Please provide a valid cache path.'
)
;
}
return
$
this
->
cachePath
;
}

Get the cache path.

@throws \RuntimeException If real-time statical proxy is active and no cache path is given

@return null|string


protected function ensureStaticalProxyExists(string $alias): string
    {
        $path = $this->getCachePath() . \DIRECTORY_SEPARATOR . 'staticalproxy-' . \sha1($alias) . '.php';

        if (\file_exists($path)) {
            return $path;
        }

        \file_put_contents(
            $path,
            $this->formatStaticalProxyStub(
                $alias,
                \file_get_contents(__DIR__ . \DIRECTORY_SEPARATOR . 'Stubs' . \DIRECTORY_SEPARATOR . 'StaticalProxy.stub')
            )
        );

        return $path;
    }

protected function ensureStaticalProxyExists ( string $ alias ) : string { $ path = $ this -> getCachePath ( ) . \ DIRECTORY_SEPARATOR . 'staticalproxy-' . \ sha1 ( $ alias ) . '.php' ; if ( \ file_exists ( $ path ) ) { return $ path ; } \ file_put_contents ( $ path , $ this -> formatStaticalProxyStub ( $ alias , \ file_get_contents ( __DIR__ . \ DIRECTORY_SEPARATOR . 'Stubs' . \ DIRECTORY_SEPARATOR . 'StaticalProxy.stub' ) ) ) ; return $ path ; }

Ensure that the given alias has an existing real-time statical proxy class.

@param string $alias

@return string

Ensure that the given alias has an existing real - time statical proxy class .


protected function formatStaticalProxyStub(string $alias, string $stub): string
    {
        $replacements = [
            \str_replace('/', '\\', \dirname(\str_replace('\\', '/', $alias))),
            self::getClassBasename($alias),
            \mb_substr($alias, \mb_strlen($this->staticalProxyNamespace)),
        ];

        return \str_replace(
            ['DummyNamespace', 'DummyClass', 'DummyTarget'],
            $replacements,
            $stub
        );
    }

protected function formatStaticalProxyStub ( string $ alias , string $ stub ) : string { $ replacements = [ \ str_replace ( '/' , '\\' , \ dirname ( \ str_replace ( '\\' , '/' , $ alias ) ) ) , self :: getClassBasename ( $ alias ) , \ mb_substr ( $ alias , \ mb_strlen ( $ this -> staticalProxyNamespace ) ) , ] ; return \ str_replace ( [ 'DummyNamespace' , 'DummyClass' , 'DummyTarget' ] , $ replacements , $ stub ) ; }

Format the statical proxy stub with the proper namespace and class.

@param string $alias
@param string $stub

@return string

Format the statical proxy stub with the proper namespace and class .


protected static function registerMarkdownEngine(EngineResolver $engines, ContainerInterface $container): void
    {
        $markdown = null;

        if ($container->has(ParsedownExtra::class)) {
            $markdown = $container->get(ParsedownExtra::class);
        } elseif ($container->has(Parsedown::class)) {
            $markdown = $container->get(Parsedown::class);
        }

        $engines->register('md', static function () use ($markdown) {
            return new MarkdownEngine($markdown);
        });
    }

protected static function registerMarkdownEngine ( EngineResolver $ engines , ContainerInterface $ container ) : void { $ markdown = null ; if ( $ container -> has ( ParsedownExtra :: class ) ) { $ markdown = $ container -> get ( ParsedownExtra :: class ) ; } elseif ( $ container -> has ( Parsedown :: class ) ) { $ markdown = $ container -> get ( Parsedown :: class ) ; } $ engines -> register ( 'md' , static function ( ) use ( $ markdown ) { return new MarkdownEngine ( $ markdown ) ; } ) ; }

Register the Markdown engine implementation.

@param \Viserio\Component\View\Engine\EngineResolver $engines
@param \Psr\Container\ContainerInterface             $container

@return void

Register the Markdown engine implementation .


protected function cleanExport(string $string): string
    {
        $replaces = [
            '\\' => '\\\\',
            '"'  => '\"',
            "\t" => '\t',
        ];

        $string = \str_replace(\array_keys($replaces), \array_values($replaces), $string);
        $po     = '"' . \implode('$' . "\n" . '"' . $this->eol . '"', \explode($this->eol, $string)) . '"';

        // remove empty strings
        return \str_replace($this->eol . '""', '', $po);
    }

protected
function
cleanExport
(
string
$
string
)
:
string
{
$
replaces
=
[
'\\'
=>
'\\\\'
,
'"'
=>
'\"'
,
"\t"
=>
'\t'
,
]
;
$
string
=
\
str_replace
(
\
array_keys
(
$
replaces
)
,
\
array_values
(
$
replaces
)
,
$
string
)
;
$
po
=
'"'
.
\
implode
(
'$'
.
"\n"
.
'"'
.
$
this
->
eol
.
'"'
,
\
explode
(
$
this
->
eol
,
$
string
)
)
.
'"'
;
// remove empty strings
return
\
str_replace
(
$
this
->
eol
.
'""'
,
''
,
$
po
)
;
}

Prepares a string to be outputed into a file.

@param string $string the string to be converted

@return string

Prepares a string to be outputed into a file .


private function addTCommentToOutput(array $entry, string $output): array
    {
        if (isset($entry['tcomment']) && \count($entry['tcomment']) !== 0) {
            foreach ($entry['tcomment'] as $comment) {
                $output .= '# ' . $comment . $this->eol;
            }
        }

        return [$entry, $output];
    }

private
function
addTCommentToOutput
(
array
$
entry
,
string
$
output
)
:
array
{
if
(
isset
(
$
entry
[
'tcomment'
]
)
&&
\
count
(
$
entry
[
'tcomment'
]
)
!==
0
)
{
foreach
(
$
entry
[
'tcomment'
]
as
$
comment
)
{
$
output
.=
'# '
.
$
comment
.
$
this
->
eol
;
}
}
return
[
$
entry
,
$
output
]
;
}

Adds tcomment to the output.

@param array  $entry
@param string $output

@return array


private function addReferencesToOutput(array $entry, string $output): array
    {
        if (isset($entry['references']) && \count($entry['references']) !== 0) {
            foreach ($entry['references'] as $ref => $value) {
                $output .= '#: ' . \str_replace(['{', '}'], '', $ref) . $this->eol;
            }
        }

        return [$entry, $output];
    }

private
function
addReferencesToOutput
(
array
$
entry
,
string
$
output
)
:
array
{
if
(
isset
(
$
entry
[
'references'
]
)
&&
\
count
(
$
entry
[
'references'
]
)
!==
0
)
{
foreach
(
$
entry
[
'references'
]
as
$
ref
=>
$
value
)
{
$
output
.=
'#: '
.
\
str_replace
(
[
'{'
,
'}'
]
,
''
,
$
ref
)
.
$
this
->
eol
;
}
}
return
[
$
entry
,
$
output
]
;
}

Adds reference to the output.

@param array  $entry
@param string $output

@return array


private function addFlagsToOutput(array $entry, string $output): array
    {
        if (isset($entry['flags']) && \count($entry['flags']) !== 0) {
            $output .= '#, ' . \implode(', ', $entry['flags']) . $this->eol;
        }

        return [$entry, $output];
    }

private
function
addFlagsToOutput
(
array
$
entry
,
string
$
output
)
:
array
{
if
(
isset
(
$
entry
[
'flags'
]
)
&&
\
count
(
$
entry
[
'flags'
]
)
!==
0
)
{
$
output
.=
'#, '
.
\
implode
(
', '
,
$
entry
[
'flags'
]
)
.
$
this
->
eol
;
}
return
[
$
entry
,
$
output
]
;
}

Adds flags infos to the output.

@param array  $entry
@param string $output

@return array


private function addPreviousToOutput(array $entry, string $output): array
    {
        if (isset($entry['previous']) && \count($entry['previous']) !== 0) {
            foreach ((array) $entry['previous'] as $key => $value) {
                if (\is_string($value)) {
                    $output .= '#| ' . $key . ' ' . $this->cleanExport($value) . $this->eol;
                } elseif (\is_array($value) && \count($value) > 0) {
                    foreach ($value as $line) {
                        $output .= '#| ' . $key . ' ' . $this->cleanExport($line) . $this->eol;
                    }
                }
            }
        }

        return [$entry, $output];
    }

private
function
addPreviousToOutput
(
array
$
entry
,
string
$
output
)
:
array
{
if
(
isset
(
$
entry
[
'previous'
]
)
&&
\
count
(
$
entry
[
'previous'
]
)
!==
0
)
{
foreach
(
(
array
)
$
entry
[
'previous'
]
as
$
key
=>
$
value
)
{
if
(
\
is_string
(
$
value
)
)
{
$
output
.=
'#| '
.
$
key
.
' '
.
$
this
->
cleanExport
(
$
value
)
.
$
this
->
eol
;
}
elseif
(
\
is_array
(
$
value
)
&&
\
count
(
$
value
)
>
0
)
{
foreach
(
$
value
as
$
line
)
{
$
output
.=
'#| '
.
$
key
.
' '
.
$
this
->
cleanExport
(
$
line
)
.
$
this
->
eol
;
}
}
}
}
return
[
$
entry
,
$
output
]
;
}

Adds previous info to the output.

@param array  $entry
@param string $output

@return array


private function addMsgidToOutput(array $entry, string $output, bool $isObsolete): array
    {
        if (isset($entry['msgid'])) {
            // Special clean for msgid
            if (\is_string($entry['msgid'])) {
                $msgid = \explode($this->eol, $entry['msgid']);
            } elseif (\is_array($entry['msgid']) && \count($entry['msgid']) !== 0) {
                $msgid = $entry['msgid'];
            } else {
                throw new DumpException('msgid not string or array.');
            }

            $output .= 'msgid ';

            foreach ((array) $msgid as $i => $id) {
                if ($i > 0 && $isObsolete) {
                    $output .= '#~ ';
                }

                $output .= $this->cleanExport($id) . $this->eol;
            }
        }

        return [$entry, $output];
    }

private
function
addMsgidToOutput
(
array
$
entry
,
string
$
output
,
bool
$
isObsolete
)
:
array
{
if
(
isset
(
$
entry
[
'msgid'
]
)
)
{
// Special clean for msgid
if
(
\
is_string
(
$
entry
[
'msgid'
]
)
)
{
$
msgid
=
\
explode
(
$
this
->
eol
,
$
entry
[
'msgid'
]
)
;
}
elseif
(
\
is_array
(
$
entry
[
'msgid'
]
)
&&
\
count
(
$
entry
[
'msgid'
]
)
!==
0
)
{
$
msgid
=
$
entry
[
'msgid'
]
;
}
else
{
throw
new
DumpException
(
'msgid not string or array.'
)
;
}
$
output
.=
'msgid '
;
foreach
(
(
array
)
$
msgid
as
$
i
=>
$
id
)
{
if
(
$
i
>
0
&&
$
isObsolete
)
{
$
output
.=
'#~ '
;
}
$
output
.=
$
this
->
cleanExport
(
$
id
)
.
$
this
->
eol
;
}
}
return
[
$
entry
,
$
output
]
;
}

Adds msgid to the output.

@param array  $entry
@param string $output
@param bool   $isObsolete

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

@return array


private function addMsgidPluralToOutput(array $entry, string $output): array
    {
        if (isset($entry['msgid_plural'])) {
            // Special clean for msgid_plural
            if (\is_string($entry['msgid_plural'])) {
                $msgidPlural = \explode($this->eol, $entry['msgid_plural']);
            } elseif (\is_array($entry['msgid_plural']) && \count($entry['msgid_plural']) !== 0) {
                $msgidPlural = $entry['msgid_plural'];
            } else {
                throw new DumpException('msgid_plural not string or array.');
            }

            $output .= 'msgid_plural ';

            foreach ((array) $msgidPlural as $plural) {
                $output .= $this->cleanExport($plural) . $this->eol;
            }
        }

        return [$entry, $output];
    }

private
function
addMsgidPluralToOutput
(
array
$
entry
,
string
$
output
)
:
array
{
if
(
isset
(
$
entry
[
'msgid_plural'
]
)
)
{
// Special clean for msgid_plural
if
(
\
is_string
(
$
entry
[
'msgid_plural'
]
)
)
{
$
msgidPlural
=
\
explode
(
$
this
->
eol
,
$
entry
[
'msgid_plural'
]
)
;
}
elseif
(
\
is_array
(
$
entry
[
'msgid_plural'
]
)
&&
\
count
(
$
entry
[
'msgid_plural'
]
)
!==
0
)
{
$
msgidPlural
=
$
entry
[
'msgid_plural'
]
;
}
else
{
throw
new
DumpException
(
'msgid_plural not string or array.'
)
;
}
$
output
.=
'msgid_plural '
;
foreach
(
(
array
)
$
msgidPlural
as
$
plural
)
{
$
output
.=
$
this
->
cleanExport
(
$
plural
)
.
$
this
->
eol
;
}
}
return
[
$
entry
,
$
output
]
;
}

Add msgid_plural to the output.

@param array  $entry
@param string $output

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

@return array


private function addMsgstrToOutput(array $entry, bool $isPlural, string $output, bool $isObsolete): string
    {
        // checks if there is a key starting with msgstr
        if (\count(\preg_grep('/^msgstr/', \array_keys($entry))) !== 0) {
            if ($isPlural) {
                $noTranslation = true;

                foreach ($entry as $key => $value) {
                    if (\mb_strpos($key, 'msgstr[') === false) {
                        continue;
                    }

                    $output .= $key . ' ';
                    $noTranslation = false;

                    foreach ($value as $i => $t) {
                        $output .= $this->cleanExport($t) . $this->eol;
                    }
                }

                if ($noTranslation) {
                    $output .= 'msgstr[0] ' . $this->cleanExport('') . $this->eol;
                    $output .= 'msgstr[1] ' . $this->cleanExport('') . $this->eol;
                }
            } else {
                foreach ((array) $entry['msgstr'] as $i => $t) {
                    if ($isObsolete) {
                        $output .= '#~ ';
                    }

                    if ($i === 0) {
                        $output .= 'msgstr ';
                    }

                    $output .= $this->cleanExport($t) . $this->eol;
                }
            }
        }

        return $output;
    }

Adds key with msgstr to the output.

@param array  $entry
@param bool   $isPlural
@param string $output
@param bool   $isObsolete

@return string


private function addHeaderToOutput(array $data, string $output): array
    {
        if (isset($data['headers']) && \count($data['headers']) !== 0) {
            $output .= 'msgid ""' . $this->eol;
            $output .= 'msgstr ""' . $this->eol;

            foreach ($data['headers'] as $key => $value) {
                if (\is_array($value)) {
                    $first = true;

                    foreach ($value as $h) {
                        if ($first) {
                            $first = false;
                            $output .= \sprintf('"%s: %s"', $key, $h) . $this->eol;
                        } else {
                            $output .= \sprintf('"%s\n"', $h) . $this->eol;
                        }
                    }
                } else {
                    $output .= \sprintf('"%s: %s\n"', $key, $value) . $this->eol;
                }
            }

            unset($data['headers']);

            $output .= $this->eol;
        }

        return [$data, $output];
    }

private
function
addHeaderToOutput
(
array
$
data
,
string
$
output
)
:
array
{
if
(
isset
(
$
data
[
'headers'
]
)
&&
\
count
(
$
data
[
'headers'
]
)
!==
0
)
{
$
output
.=
'msgid ""'
.
$
this
->
eol
;
$
output
.=
'msgstr ""'
.
$
this
->
eol
;
foreach
(
$
data
[
'headers'
]
as
$
key
=>
$
value
)
{
if
(
\
is_array
(
$
value
)
)
{
$
first
=
true
;
foreach
(
$
value
as
$
h
)
{
if
(
$
first
)
{
$
first
=
false
;
$
output
.=
\
sprintf
(
'"%s: %s"'
,
$
key
,
$
h
)
.
$
this
->
eol
;
}
else
{
$
output
.=
\
sprintf
(
'"%s\n"'
,
$
h
)
.
$
this
->
eol
;
}
}
}
else
{
$
output
.=
\
sprintf
(
'"%s: %s\n"'
,
$
key
,
$
value
)
.
$
this
->
eol
;
}
}
unset
(
$
data
[
'headers'
]
)
;
$
output
.=
$
this
->
eol
;
}
return
[
$
data
,
$
output
]
;
}

Adds a header to the output.

@param array  $data
@param string $output

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

@return array


private function getPaginationsLinks(array $items, $pagination): void
    {
        foreach ($items as $item) {
            if (\is_string($item)) {
                $pagination .= '' . $item . '';
            }

            // Array Of Links
            if (\is_array($item)) {
                foreach ($item as $page => $url) {
                    if ($this->paginator->getCurrentPage() === $page) {
                        $pagination .= '' . $page . '';
                    } else {
                        $pagination .= '' . $page . '';
                    }
                }
            }
        }
    }

private
function
getPaginationsLinks
(
array
$
items
,
$
pagination
)
:
void
{
foreach
(
$
items
as
$
item
)
{
if
(
\
is_string
(
$
item
)
)
{
$
pagination
.=
''
.
$
item
.
''
;
}
// Array Of Links
if
(
\
is_array
(
$
item
)
)
{
foreach
(
$
item
as
$
page
=>
$
url
)
{
if
(
$
this
->
paginator
->
getCurrentPage
(
)
===
$
page
)
{
$
pagination
.=
''
.
$
page
.
''
;
}
else
{
$
pagination
.=
''
.
$
page
.
''
;
}
}
}
}
}

Get all paginations page links.

@param array  $items
@param string $pagination


protected function createConnector(array $config): CacheInterface
    {
        $cacheConfig = $config['cache'];

        if (($cache = $this->cacheManager) !== null) {
            if ($cache->hasDriver($cacheConfig['driver'])) {
                return new Psr6Cache(
                    $cache->getDriver($cacheConfig['driver']),
                    $cacheConfig['key'],
                    $cacheConfig['expire']
                );
            }
        }

        if ($this->manager->hasConnection($cacheConfig['driver'])) {
            return new Adapter(
                $this->manager->createConnection($config),
                $cacheConfig['key'],
                $cacheConfig['expire']
            );
        }

        throw new InvalidArgumentException(\sprintf('Unsupported driver [%s].', $cacheConfig['driver']));
    }

protected
function
createConnector
(
array
$
config
)
:
CacheInterface
{
$
cacheConfig
=
$
config
[
'cache'
]
;
if
(
(
$
cache
=
$
this
->
cacheManager
)
!==
)
{
if
(
$
cache
->
hasDriver
(
$
cacheConfig
[
'driver'
]
)
)
{
return
new
Psr6Cache
(
$
cache
->
getDriver
(
$
cacheConfig
[
'driver'
]
)
,
$
cacheConfig
[
'key'
]
,
$
cacheConfig
[
'expire'
]
)
;
}
}
if
(
$
this
->
manager
->
hasConnection
(
$
cacheConfig
[
'driver'
]
)
)
{
return
new
Adapter
(
$
this
->
manager
->
createConnection
(
$
config
)
,
$
cacheConfig
[
'key'
]
,
$
cacheConfig
[
'expire'
]
)
;
}
throw
new
InvalidArgumentException
(
\
sprintf
(
'Unsupported driver [%s].'
,
$
cacheConfig
[
'driver'
]
)
)
;
}

Create a connector instance based on the configuration.

@param array $config

@throws \InvalidArgumentException

@return \League\Flysystem\Cached\CacheInterface

Create a connector instance based on the configuration .


protected function ensureCorrectUser(string $command): string
    {
        if ($this->user && ! $this->isWindows()) {
            return 'sudo -u ' . $this->user . ' -- sh -c \'' . $command . '\'';
        }

        // http://de2.php.net/manual/en/function.exec.php#56599
        // The "start" command will start a detached process, a similar effect to &. The "/B" option prevents
        // start from opening a new terminal window if the program you are running is a console application.
        if ($this->user && $this->isWindows()) {
            // https://superuser.com/questions/42537/is-there-any-sudo-command-for-windows
            // Options for runas : [{/profile|/noprofile}] [/env] [/netonly] [/smartcard] [/showtrustlevels] [/trustlevel] /user:UserAccountName

            return 'runas ' . $this->user . 'start /B ' . $command;
        }

        if ($this->isWindows()) {
            return 'start /B ' . $command;
        }

        return $command;
    }

Finalize the event's command syntax with the correct user.

@param string $command

@return string

Finalize the event s command syntax with the correct user .


protected function expressionPasses(): bool
    {
        $date = Chronos::now();

        if ($this->timezone !== null) {
            $date->setTimezone($this->timezone);
        }

        return CronExpression::factory($this->expression)->isDue($date->toDateTimeString());
    }

protected function expressionPasses ( ) : bool { $ date = Chronos :: now ( ) ; if ( $ this -> timezone !== null ) { $ date -> setTimezone ( $ this -> timezone ) ; } return CronExpression :: factory ( $ this -> expression ) -> isDue ( $ date -> toDateTimeString ( ) ) ; }

Determine if the Cron expression passes.

@return bool

Determine if the Cron expression passes .


protected function runCommandInForeground(): int
    {
        $this->callBeforeCallbacks();

        $process = Process::fromShellCommandline(
            \trim($this->buildCommand(), ' &'),
            $this->path,
            null,
            null,
            null
        );

        $run = $process->run();

        $this->callAfterCallbacks();

        return $run;
    }

protected
function
runCommandInForeground
(
)
:
int
{
$
this
->
callBeforeCallbacks
(
)
;
$
process
=
Process
::
fromShellCommandline
(
\
trim
(
$
this
->
buildCommand
(
)
,
' &'
)
,
$
this
->
path
,
,
,
)
;
$
run
=
$
process
->
run
(
)
;
$
this
->
callAfterCallbacks
(
)
;
return
$
run
;
}

Run the command in the foreground.

@return int The exit status code


protected function runCommandInBackground(): int
    {
        $process = Process::fromShellCommandline(
            $this->buildCommand(),
            $this->path,
            null,
            null,
            null
        );

        return $process->run();
    }

protected function runCommandInBackground ( ) : int { $ process = Process :: fromShellCommandline ( $ this -> buildCommand ( ) , $ this -> path , null , null , null ) ; return $ process -> run ( ) ; }

Run the command in the background.

@return int The exit status code


protected function callBeforeCallbacks(): void
    {
        foreach ($this->beforeCallbacks as $callback) {
            $this->getInvoker()->call($callback);
        }
    }

protected function callBeforeCallbacks ( ) : void { foreach ( $ this -> beforeCallbacks as $ callback ) { $ this -> getInvoker ( ) -> call ( $ callback ) ; } }

Call all of the "before" callbacks for the cron job.

@return void

Call all of the before callbacks for the cron job .


protected function callAfterCallbacks(): void
    {
        foreach ($this->afterCallbacks as $callback) {
            $this->getInvoker()->call($callback);
        }
    }

protected function callAfterCallbacks ( ) : void { foreach ( $ this -> afterCallbacks as $ callback ) { $ this -> getInvoker ( ) -> call ( $ callback ) ; } }

Call all of the "after" callbacks for the cron job.

@return void

Call all of the after callbacks for the cron job .


protected function inTimeInterval(string $startTime, string $endTime): Closure
    {
        if ($this->isMidnightBetween($startTime, $endTime)) {
            $endTime .= ' +1 day';
        }

        return function () use ($startTime, $endTime) {
            return Chronos::now($this->timezone)->between(
                Chronos::parse($startTime, $this->timezone),
                Chronos::parse($endTime, $this->timezone)
            );
        };
    }

protected
function
inTimeInterval
(
string
$
startTime
,
string
$
endTime
)
:
Closure
{
if
(
$
this
->
isMidnightBetween
(
$
startTime
,
$
endTime
)
)
{
$
endTime
.=
' +1 day'
;
}
return
function
(
)
use
(
$
startTime
,
$
endTime
)
{
return
Chronos
::
now
(
$
this
->
timezone
)
->
between
(
Chronos
::
parse
(
$
startTime
,
$
this
->
timezone
)
,
Chronos
::
parse
(
$
endTime
,
$
this
->
timezone
)
)
;
}
;
}

Schedule the cron job to run between start and end time.

@param string $startTime
@param string $endTime

@return \Closure

Schedule the cron job to run between start and end time .


private function isMidnightBetween(string $startTime, string $endTime): bool
    {
        return \strtotime($startTime) > \strtotime($endTime);
    }

private function isMidnightBetween ( string $ startTime , string $ endTime ) : bool { return \ strtotime ( $ startTime ) > \ strtotime ( $ endTime ) ; }

Check if startTime and endTime are before and after midnight.

@param string $startTime
@param string $endTime

@return bool

Check if startTime and endTime are before and after midnight .


public static function mergeMatchers(array $parentMatchers, array $childMatchers): array
    {
        $mergedMatchers = $parentMatchers;

        foreach ($childMatchers as $segment => $childMatcher) {
            if (isset($mergedMatchers[$segment])) {
                $mergedMatchers[$segment] = new CompoundMatcher([$mergedMatchers[$segment], $childMatcher]);
            } else {
                $mergedMatchers[$segment] = $childMatcher;
            }
        }

        return $mergedMatchers;
    }

public static function mergeMatchers ( array $ parentMatchers , array $ childMatchers ) : array { $ mergedMatchers = $ parentMatchers ; foreach ( $ childMatchers as $ segment => $ childMatcher ) { if ( isset ( $ mergedMatchers [ $ segment ] ) ) { $ mergedMatchers [ $ segment ] = new CompoundMatcher ( [ $ mergedMatchers [ $ segment ] , $ childMatcher ] ) ; } else { $ mergedMatchers [ $ segment ] = $ childMatcher ; } } return $ mergedMatchers ; }

Merge same matcher together.

@param array $parentMatchers
@param array $childMatchers

@return array


public static function optimizeMatchers(array $matchers): array
    {
        foreach ($matchers as $key => $matcher) {
            $matchers[$key] = self::optimizeMatcher($matcher);
        }

        return self::optimizeMatcherOrder($matchers);
    }

public static function optimizeMatchers ( array $ matchers ) : array { foreach ( $ matchers as $ key => $ matcher ) { $ matchers [ $ key ] = self :: optimizeMatcher ( $ matcher ) ; } return self :: optimizeMatcherOrder ( $ matchers ) ; }

Optimize matcher and matcher order.

@param array $matchers

@return array


private static function optimizeMatcher(SegmentMatcherContract $matcher): SegmentMatcherContract
    {
        if ($matcher instanceof RegexMatcher && $matcher->getGroupCount() === 1) {
            $parameterKeys = $matcher->getParameterKeys();

            switch ($matcher->getRegex()) {
                case '/^(' . Pattern::ANY . ')$/':
                    return new AnyMatcher($parameterKeys);
                case '/^(' . Pattern::DIGITS . ')$/':
                    return new ExpressionMatcher('ctype_digit({segment})', $parameterKeys);
                case '/^(' . Pattern::ALPHA . ')$/':
                    return new ExpressionMatcher('ctype_alpha({segment})', $parameterKeys);
                case '/^(' . Pattern::ALPHA_LOWER . ')$/':
                    return new ExpressionMatcher('ctype_lower({segment})', $parameterKeys);
                case '/^(' . Pattern::ALPHA_UPPER . ')$/':
                    return new ExpressionMatcher('ctype_upper({segment})', $parameterKeys);
                case '/^(' . Pattern::ALPHA_NUM . ')$/':
                    return new ExpressionMatcher('ctype_alnum({segment})', $parameterKeys);
                case '/^(' . Pattern::ALPHA_NUM_DASH . ')$/':
                    return new ExpressionMatcher('ctype_alnum(str_replace(\'-\', \'\', {segment}))', $parameterKeys);

                default:
                    return $matcher;
            }
        }

        return $matcher;
    }

Change matcher for a faster one, if available.

@param \Viserio\Component\Contract\Routing\SegmentMatcher $matcher

@return \Viserio\Component\Contract\Routing\SegmentMatcher

Change matcher for a faster one if available .


private static function optimizeMatcherOrder(array $matchers): array
    {
        $computationalCostOrder = [
            AnyMatcher::class,
            StaticMatcher::class,
            ExpressionMatcher::class,
            RegexMatcher::class,
            // Unknown types last
            SegmentMatcherContract::class,
        ];

        $groups = [];

        foreach ($computationalCostOrder as $type) {
            foreach ($matchers as $index => $matcher) {
                if ($matcher instanceof $type) {
                    unset($matchers[$index]);
                    $groups[$index] = $matcher;
                }
            }
        }

        return $groups;
    }

private
static
function
optimizeMatcherOrder
(
array
$
matchers
)
:
array
{
$
computationalCostOrder
=
[
AnyMatcher
::
class
,
StaticMatcher
::
class
,
ExpressionMatcher
::
class
,
RegexMatcher
::
class
,
// Unknown types last
SegmentMatcherContract
::
class
,
]
;
$
groups
=
[
]
;
foreach
(
$
computationalCostOrder
as
$
type
)
{
foreach
(
$
matchers
as
$
index
=>
$
matcher
)
{
if
(
$
matcher
instanceof
$
type
)
{
unset
(
$
matchers
[
$
index
]
)
;
$
groups
[
$
index
]
=
$
matcher
;
}
}
}
return
$
groups
;
}

Optimizing the matcher order, unknown types are added last.

@param array $matchers

@return array

Optimizing the matcher order unknown types are added last .


public static function createHtmlDisplayer(ContainerInterface $container): HtmlDisplayer
    {
        return new HtmlDisplayer(
            $container->get(ResponseFactoryInterface::class),
            $container->get('config')
        );
    }

public static function createHtmlDisplayer ( ContainerInterface $ container ) : HtmlDisplayer { return new HtmlDisplayer ( $ container -> get ( ResponseFactoryInterface :: class ) , $ container -> get ( 'config' ) ) ; }

Create a new HtmlDisplayer instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Exception\Displayer\HtmlDisplayer


public static function createViewDisplayer(ContainerInterface $container): ViewDisplayer
    {
        return new ViewDisplayer(
            $container->get(ResponseFactoryInterface::class),
            $container->get(FactoryContract::class)
        );
    }

public static function createViewDisplayer ( ContainerInterface $ container ) : ViewDisplayer { return new ViewDisplayer ( $ container -> get ( ResponseFactoryInterface :: class ) , $ container -> get ( FactoryContract :: class ) ) ; }

Create a new ViewDisplayer instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Exception\Displayer\ViewDisplayer


public static function createWhoopsPrettyDisplayer(ContainerInterface $container): WhoopsPrettyDisplayer
    {
        return new WhoopsPrettyDisplayer(
            $container->get(ResponseFactoryInterface::class),
            $container->get('config')
        );
    }

public static function createWhoopsPrettyDisplayer ( ContainerInterface $ container ) : WhoopsPrettyDisplayer { return new WhoopsPrettyDisplayer ( $ container -> get ( ResponseFactoryInterface :: class ) , $ container -> get ( 'config' ) ) ; }

Create a new WhoopsPrettyDisplayer instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Exception\Displayer\WhoopsPrettyDisplayer

Create a new WhoopsPrettyDisplayer instance .


protected function numberOfRecipients(Swift_Mime_SimpleMessage $message): int
    {
        $to  = $message->getTo()  ?? [];
        $cc  = $message->getCc()  ?? [];
        $bcc = $message->getBcc() ?? [];

        return \count(\array_merge($to, $cc, $bcc));
    }

protected function numberOfRecipients ( Swift_Mime_SimpleMessage $ message ) : int { $ to = $ message -> getTo ( ) ?? [ ] ; $ cc = $ message -> getCc ( ) ?? [ ] ; $ bcc = $ message -> getBcc ( ) ?? [ ] ; return \ count ( \ array_merge ( $ to , $ cc , $ bcc ) ) ; }

Get the number of recipients.

@param \Swift_Mime_SimpleMessage $message

@return int


public function bootstrap(): void
    {
        $container        = $this->getContainer();
        $bootstrapManager = $container->get(BootstrapManager::class);

        if (! $bootstrapManager->hasBeenBootstrapped()) {
            $bootstraps = [];

            foreach ($this->getPreparedBootstraps() as $classes) {
                /** @var \Viserio\Component\Contract\Foundation\BootstrapState $class */
                foreach ($classes as $class) {
                    if (\in_array(BootstrapStateContract::class, \class_implements($class), true)) {
                        $method = 'add' . $class::getType() . 'Bootstrapping';

                        $bootstrapManager->{$method}($class::getBootstrapper(), [$class, 'bootstrap']);
                    } else {
                        /** @var \Viserio\Component\Contract\Foundation\Bootstrap $class */
                        $bootstraps[] = $class;
                    }
                }
            }

            $bootstrapManager->bootstrapWith($bootstraps);

            if ($this->isDebug() && ! isset($_ENV['SHELL_VERBOSITY']) && ! isset($_SERVER['SHELL_VERBOSITY'])) {
                \putenv('SHELL_VERBOSITY=3');

                $_ENV['SHELL_VERBOSITY']    = 3;
                $_SERVER['SHELL_VERBOSITY'] = 3;
            }

            $dispatcher = $container->get(DispatcherContract::class);

            if ($dispatcher instanceof MiddlewareBasedDispatcher) {
                $dispatcher->setMiddlewarePriorities($this->resolvedOptions['middleware_priority']);
                $dispatcher->withMiddleware($this->resolvedOptions['route_middleware']);

                foreach ($this->resolvedOptions['middleware_groups'] as $key => $middleware) {
                    $dispatcher->setMiddlewareGroup($key, $middleware);
                }
            }
        }
    }

Bootstrap the kernel for HTTP requests.

@return void

Bootstrap the kernel for HTTP requests .


protected function handleRequest(
        ServerRequestInterface $serverRequest,
        ?EventManagerContract $events
    ): ResponseInterface {
        try {
            if ($events !== null) {
                $events->trigger(new KernelFinishRequestEvent($this, $serverRequest));
            }

            $response = $this->sendRequestThroughRouter($serverRequest);
        } catch (Throwable $exception) {
            $this->reportException($exception);

            $response = $this->renderException($serverRequest, $exception);

            if ($events !== null) {
                $events->trigger(new KernelExceptionEvent($this, $serverRequest, $response));
            }
        }

        return $response;
    }

protected function handleRequest ( ServerRequestInterface $ serverRequest , ? EventManagerContract $ events ) : ResponseInterface { try { if ( $ events !== null ) { $ events -> trigger ( new KernelFinishRequestEvent ( $ this , $ serverRequest ) ) ; } $ response = $ this -> sendRequestThroughRouter ( $ serverRequest ) ; } catch ( Throwable $ exception ) { $ this -> reportException ( $ exception ) ; $ response = $ this -> renderException ( $ serverRequest , $ exception ) ; if ( $ events !== null ) { $ events -> trigger ( new KernelExceptionEvent ( $ this , $ serverRequest , $ response ) ) ; } } return $ response ; }

Convert request into response.

@param \Psr\Http\Message\ServerRequestInterface             $serverRequest
@param null|\Viserio\Component\Contract\Events\EventManager $events

@return \Psr\Http\Message\ResponseInterface


protected function renderException(ServerRequestInterface $request, Throwable $exception): ResponseInterface
    {
        $container = $this->getContainer();

        if ($container->has(HttpHandlerContract::class)) {
            return $container->get(HttpHandlerContract::class)->render($request, $exception);
        }

        throw $exception;
    }

protected function renderException ( ServerRequestInterface $ request , Throwable $ exception ) : ResponseInterface { $ container = $ this -> getContainer ( ) ; if ( $ container -> has ( HttpHandlerContract :: class ) ) { return $ container -> get ( HttpHandlerContract :: class ) -> render ( $ request , $ exception ) ; } throw $ exception ; }

Render the exception to a response.

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

@return \Psr\Http\Message\ResponseInterface


protected function pipeRequestThroughMiddlewareAndRouter(
        ServerRequestInterface $request,
        RouterContract $router
    ): ResponseInterface {
        $container = $this->getContainer();

        return (new RoutingPipeline())
            ->setContainer($container)
            ->send($request)
            ->through($this->resolvedOptions['skip_middleware'] ? [] : $this->resolvedOptions['middleware'])
            ->then(static function ($request) use ($router, $container) {
                $container->instance(ServerRequestInterface::class, $request);

                return $router->dispatch($request);
            });
    }

protected function pipeRequestThroughMiddlewareAndRouter ( ServerRequestInterface $ request , RouterContract $ router ) : ResponseInterface { $ container = $ this -> getContainer ( ) ; return ( new RoutingPipeline ( ) ) -> setContainer ( $ container ) -> send ( $ request ) -> through ( $ this -> resolvedOptions [ 'skip_middleware' ] ? [ ] : $ this -> resolvedOptions [ 'middleware' ] ) -> then ( static function ( $ request ) use ( $ router , $ container ) { $ container -> instance ( ServerRequestInterface :: class , $ request ) ; return $ router -> dispatch ( $ request ) ; } ) ; }

Pipes the request through given middleware and dispatch a response.

@param \Psr\Http\Message\ServerRequestInterface   $request
@param \Viserio\Component\Contract\Routing\Router $router

@return \Psr\Http\Message\ResponseInterface

Pipes the request through given middleware and dispatch a response .


protected function compileParameters(array $parameters): string
    {
        $keys = \array_keys($parameters);

        $items = \array_map(static function ($value, $key) {
            if (\is_array($value)) {
                $value = \array_map('escapeshellarg', $value);

                $value = \implode(' ', $value);
            } elseif (! \is_numeric($value) && ! \preg_match('/^(-.$|--.*)/', $value)) {
                $value = \escapeshellarg($value);
            }

            return \is_numeric($key) ? $value : \sprintf('%s=%s', $key, $value);
        }, $parameters, $keys);

        return \implode(' ', \array_combine($keys, $items));
    }

protected
function
compileParameters
(
array
$
parameters
)
:
string
{
$
keys
=
\
array_keys
(
$
parameters
)
;
$
items
=
\
array_map
(
static
function
(
$
value
,
$
key
)
{
if
(
\
is_array
(
$
value
)
)
{
$
value
=
\
array_map
(
'escapeshellarg'
,
$
value
)
;
$
value
=
\
implode
(
' '
,
$
value
)
;
}
elseif
(
!
\
is_numeric
(
$
value
)
&&
!
\
preg_match
(
'/^(-.$|--.*)/'
,
$
value
)
)
{
$
value
=
\
escapeshellarg
(
$
value
)
;
}
return
\
is_numeric
(
$
key
)
$
value
:
\
sprintf
(
'%s=%s'
,
$
key
,
$
value
)
;
}
,
$
parameters
,
$
keys
)
;
return
\
implode
(
' '
,
\
array_combine
(
$
keys
,
$
items
)
)
;
}

Compile parameters for a command.

@param array $parameters

@return string


public function offsetSet($offset, $value): void
    {
        if (\is_string($value)) {
            $this->bindPlain($offset, $value);
        } else {
            $this->bindService($offset, $value);
        }
    }

public function offsetSet ( $ offset , $ value ) : void { if ( \ is_string ( $ value ) ) { $ this -> bindPlain ( $ offset , $ value ) ; } else { $ this -> bindService ( $ offset , $ value ) ; } }

Set the value at a given offset.

@param string $offset
@param mixed  $value


protected function getInvoker(): InvokerInterface
    {
        if (! $this->invoker) {
            $parameterResolver = [
                new NumericArrayResolver(),
                new AssociativeArrayResolver(),
                new DefaultValueResolver(),
                new TypeHintContainerResolver($this),
                new ParameterNameContainerResolver($this),
            ];

            $this->invoker = new Invoker(new ResolverChain($parameterResolver), $this);
        }

        return $this->invoker;
    }

protected function getInvoker ( ) : InvokerInterface { if ( ! $ this -> invoker ) { $ parameterResolver = [ new NumericArrayResolver ( ) , new AssociativeArrayResolver ( ) , new DefaultValueResolver ( ) , new TypeHintContainerResolver ( $ this ) , new ParameterNameContainerResolver ( $ this ) , ] ; $ this -> invoker = new Invoker ( new ResolverChain ( $ parameterResolver ) , $ this ) ; } return $ this -> invoker ; }

Get a configured instance of invoker.

@return \Invoker\InvokerInterface

@codeCoverageIgnore


protected function bindPlain(string $abstract, $concrete): void
    {
        $this->bindings[$abstract] = [
            TypesContract::VALUE        => $concrete,
            TypesContract::IS_RESOLVED  => false,
            TypesContract::BINDING_TYPE => TypesContract::PLAIN,
        ];
    }

protected function bindPlain ( string $ abstract , $ concrete ) : void { $ this -> bindings [ $ abstract ] = [ TypesContract :: VALUE => $ concrete , TypesContract :: IS_RESOLVED => false , TypesContract :: BINDING_TYPE => TypesContract :: PLAIN , ] ; }

Bind a plain value.

@param string $abstract
@param mixed  $concrete


protected function bindService(string $abstract, $concrete): void
    {
        $this->bindings[$abstract] = [
            TypesContract::VALUE        => $concrete,
            TypesContract::IS_RESOLVED  => false,
            TypesContract::BINDING_TYPE => TypesContract::SERVICE,
        ];
    }

protected function bindService ( string $ abstract , $ concrete ) : void { $ this -> bindings [ $ abstract ] = [ TypesContract :: VALUE => $ concrete , TypesContract :: IS_RESOLVED => false , TypesContract :: BINDING_TYPE => TypesContract :: SERVICE , ] ; }

Bind a value which need to be resolved each time.

@param string $abstract
@param mixed  $concrete

Bind a value which need to be resolved each time .


protected function bindSingleton(string $abstract, $concrete): void
    {
        $this->bindings[$abstract] = [
            TypesContract::VALUE        => $concrete,
            TypesContract::IS_RESOLVED  => false,
            TypesContract::BINDING_TYPE => TypesContract::SINGLETON,
        ];
    }

protected function bindSingleton ( string $ abstract , $ concrete ) : void { $ this -> bindings [ $ abstract ] = [ TypesContract :: VALUE => $ concrete , TypesContract :: IS_RESOLVED => false , TypesContract :: BINDING_TYPE => TypesContract :: SINGLETON , ] ; }

Bind a value which need to be resolved one time.

@param string $abstract
@param mixed  $concrete

Bind a value which need to be resolved one time .


protected function resolvePlain(string $abstract)
    {
        $binding                             = &$this->bindings[$abstract];
        $binding[TypesContract::IS_RESOLVED] = true;

        return $binding[TypesContract::VALUE];
    }

protected function resolvePlain ( string $ abstract ) { $ binding = & $ this -> bindings [ $ abstract ] ; $ binding [ TypesContract :: IS_RESOLVED ] = true ; return $ binding [ TypesContract :: VALUE ] ; }

Resolve a plain value from the container.

@param string $abstract

@return mixed

Resolve a plain value from the container .


protected function resolveService(string $abstract, array $parameters = [])
    {
        $binding                             = &$this->bindings[$abstract];
        $binding[TypesContract::IS_RESOLVED] = true;

        return parent::resolve($binding[TypesContract::VALUE], $parameters);
    }

protected function resolveService ( string $ abstract , array $ parameters = [ ] ) { $ binding = & $ this -> bindings [ $ abstract ] ; $ binding [ TypesContract :: IS_RESOLVED ] = true ; return parent :: resolve ( $ binding [ TypesContract :: VALUE ] , $ parameters ) ; }

Resolve a service from the container.

@param string $abstract
@param array  $parameters

@return mixed


protected function resolveSingleton(string $abstract, array $parameters = [])
    {
        $binding = &$this->bindings[$abstract];

        $binding[TypesContract::VALUE]       = parent::resolve($binding[TypesContract::VALUE], $parameters);
        $binding[TypesContract::IS_RESOLVED] = true;

        return $binding[TypesContract::VALUE];
    }

protected function resolveSingleton ( string $ abstract , array $ parameters = [ ] ) { $ binding = & $ this -> bindings [ $ abstract ] ; $ binding [ TypesContract :: VALUE ] = parent :: resolve ( $ binding [ TypesContract :: VALUE ] , $ parameters ) ; $ binding [ TypesContract :: IS_RESOLVED ] = true ; return $ binding [ TypesContract :: VALUE ] ; }

Resolve a singleton from the container.

@param string $abstract
@param array  $parameters

@return mixed

Resolve a singleton from the container .


protected function extendResolved($abstract, &$resolved): void
    {
        if (! isset($this->extenders[$abstract])) {
            return;
        }

        $binding = $this->bindings[$abstract];

        foreach ($this->extenders[$abstract] as $extender) {
            $resolved = $this->extendConcrete($resolved, $extender);
        }

        if ($binding && $binding[TypesContract::BINDING_TYPE] !== TypesContract::SERVICE) {
            unset($this->extenders[$abstract]);

            $this->bindings[$abstract][TypesContract::VALUE] = $resolved;
        }
    }

protected function extendResolved ( $ abstract , & $ resolved ) : void { if ( ! isset ( $ this -> extenders [ $ abstract ] ) ) { return ; } $ binding = $ this -> bindings [ $ abstract ] ; foreach ( $ this -> extenders [ $ abstract ] as $ extender ) { $ resolved = $ this -> extendConcrete ( $ resolved , $ extender ) ; } if ( $ binding && $ binding [ TypesContract :: BINDING_TYPE ] !== TypesContract :: SERVICE ) { unset ( $ this -> extenders [ $ abstract ] ) ; $ this -> bindings [ $ abstract ] [ TypesContract :: VALUE ] = $ resolved ; } }

Extend a resolved subject.

@param string $abstract
@param mixed  $resolved

@return void


protected function contextualBindingFormat($implementation, ReflectionClass $parameterClass)
    {
        if ($implementation instanceof Closure || $implementation instanceof $parameterClass->name) {
            return $implementation;
        }

        return static function (ContainerContract $container) use ($implementation) {
            return $container->resolve($implementation);
        };
    }

protected function contextualBindingFormat ( $ implementation , ReflectionClass $ parameterClass ) { if ( $ implementation instanceof Closure || $ implementation instanceof $ parameterClass -> name ) { return $ implementation ; } return static function ( ContainerContract $ container ) use ( $ implementation ) { return $ container -> resolve ( $ implementation ) ; } ; }

Format a class binding.

@param \Closure|object|string $implementation
@param \ReflectionClass       $parameterClass

@return mixed


protected function getMessageId(?ResponseInterface $response): string
    {
        if ($response === null) {
            return '';
        }

        $content = \json_decode($response->getBody()->getContents(), true);

        return $content['MessageID'];
    }

protected function getMessageId ( ? ResponseInterface $ response ) : string { if ( $ response === null ) { return '' ; } $ content = \ json_decode ( $ response -> getBody ( ) -> getContents ( ) , true ) ; return $ content [ 'MessageID' ] ; }

Get the message ID from the response.

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

@return string


protected function convertEmailsArray(array $emails): array
    {
        $convertedEmails = [];

        foreach ($emails as $email => $name) {
            $convertedEmails[] = $name ?
            '"' . \str_replace('"', '\\"', $name) . "\" <{$email}>" :
            $email;
        }

        return $convertedEmails;
    }

protected
function
convertEmailsArray
(
array
$
emails
)
:
array
{
$
convertedEmails
=
[
]
;
foreach
(
$
emails
as
$
email
=>
$
name
)
{
$
convertedEmails
[
]
=
$
name
'"'
.
\
str_replace
(
'"'
,
'\\"'
,
$
name
)
.
"\" <{$email}>"
:
$
email
;
}
return
$
convertedEmails
;
}

Convert email dictionary with emails and names
to array of emails with names.

@param string[] $emails

@return array

Convert email dictionary with emails and names to array of emails with names .


protected function getMIMEPart(Swift_Mime_SimpleMessage $message, $mimeType): ?Swift_Mime_SimpleMimeEntity
    {
        foreach ($message->getChildren() as $part) {
            if (! ($part instanceof Swift_Mime_Attachment) && \mb_strpos($part->getContentType(), $mimeType) === 0) {
                return $part;
            }
        }

        return null;
    }

protected function getMIMEPart ( Swift_Mime_SimpleMessage $ message , $ mimeType ) : ? Swift_Mime_SimpleMimeEntity { foreach ( $ message -> getChildren ( ) as $ part ) { if ( ! ( $ part instanceof Swift_Mime_Attachment ) && \ mb_strpos ( $ part -> getContentType ( ) , $ mimeType ) === 0 ) { return $ part ; } } return null ; }

Gets MIME parts that match the message type.
Excludes parts of type \Swift_Mime_Attachment as those
are handled later.

@param \Swift_Mime_SimpleMessage $message
@param string                    $mimeType

@return null|\Swift_Mime_SimpleMimeEntity

Gets MIME parts that match the message type . Excludes parts of type \ Swift_Mime_Attachment as those are handled later .


protected function getMessagePayload(Swift_Mime_SimpleMessage $message): array
    {
        $payload = [];

        $payload = $this->processRecipients($payload, $message);
        $payload = $this->processMessageParts($payload, $message);

        return $this->processHeaders($payload, $message);
    }

protected function getMessagePayload ( Swift_Mime_SimpleMessage $ message ) : array { $ payload = [ ] ; $ payload = $ this -> processRecipients ( $ payload , $ message ) ; $ payload = $ this -> processMessageParts ( $ payload , $ message ) ; return $ this -> processHeaders ( $ payload , $ message ) ; }

Convert a Swift Mime Message to a Postmark Payload.

@param \Swift_Mime_SimpleMessage $message

@return array

Convert a Swift Mime Message to a Postmark Payload .


protected function processRecipients(array $payload, Swift_Mime_SimpleMessage $message): array
    {
        $payload['From']    = \implode(',', $this->convertEmailsArray($message->getFrom()));
        $payload['To']      = \implode(',', $this->convertEmailsArray($message->getTo()));
        $payload['Subject'] = $message->getSubject() ?? '';

        $tags = $message->getHeaders()->getAll('tag');
        /** @var \Swift_Mime_Header $tag */
        $tag = \end($tags);

        $payload['Tag'] = $tag !== false ? $tag->getFieldBody() : '';

        $cc = $message->getCc();

        if (\is_array($cc)) {
            $payload['Cc'] = \implode(',', $this->convertEmailsArray($cc));
        }

        $replyTo = $message->getReplyTo();

        if (\is_string($replyTo)) {
            $payload['ReplyTo'] = $replyTo;
        }

        $bcc = $message->getBcc();

        if (\is_array($bcc)) {
            $payload['Bcc'] = \implode(',', $this->convertEmailsArray($bcc));
        }

        return $payload;
    }

protected
function
processRecipients
(
array
$
payload
,
Swift_Mime_SimpleMessage
$
message
)
:
array
{
$
payload
[
'From'
]
=
\
implode
(
','
,
$
this
->
convertEmailsArray
(
$
message
->
getFrom
(
)
)
)
;
$
payload
[
'To'
]
=
\
implode
(
','
,
$
this
->
convertEmailsArray
(
$
message
->
getTo
(
)
)
)
;
$
payload
[
'Subject'
]
=
$
message
->
getSubject
(
)
??
''
;
$
tags
=
$
message
->
getHeaders
(
)
->
getAll
(
'tag'
)
;
/** @var \Swift_Mime_Header $tag */
$
tag
=
\
end
(
$
tags
)
;
$
payload
[
'Tag'
]
=
$
tag
!==
false
$
tag
->
getFieldBody
(
)
:
''
;
$
cc
=
$
message
->
getCc
(
)
;
if
(
\
is_array
(
$
cc
)
)
{
$
payload
[
'Cc'
]
=
\
implode
(
','
,
$
this
->
convertEmailsArray
(
$
cc
)
)
;
}
$
replyTo
=
$
message
->
getReplyTo
(
)
;
if
(
\
is_string
(
$
replyTo
)
)
{
$
payload
[
'ReplyTo'
]
=
$
replyTo
;
}
$
bcc
=
$
message
->
getBcc
(
)
;
if
(
\
is_array
(
$
bcc
)
)
{
$
payload
[
'Bcc'
]
=
\
implode
(
','
,
$
this
->
convertEmailsArray
(
$
bcc
)
)
;
}
return
$
payload
;
}

Applies the recipients of the message into the API Payload.

@param array                     $payload
@param \Swift_Mime_SimpleMessage $message

@return array

Applies the recipients of the message into the API Payload .


protected function processMessageParts(array $payload, Swift_Mime_SimpleMessage $message): array
    {
        //Get the primary message.
        switch ($message->getContentType()) {
            case 'text/html':
            case 'multipart/mixed':
            case 'multipart/related':
            case 'multipart/alternative':
                $payload['HtmlBody'] = $message->getBody();

                break;

            default:
                $payload['TextBody'] = $message->getBody();

                break;
        }

        // Provide an alternate view from the secondary parts.
        if ($plain = $this->getMIMEPart($message, 'text/plain')) {
            $payload['TextBody'] = $plain->getBody();
        }

        if ($html = $this->getMIMEPart($message, 'text/html')) {
            $payload['HtmlBody'] = $html->getBody();
        }

        if ($message->getChildren()) {
            $payload['Attachments'] = [];

            foreach ($message->getChildren() as $attachment) {
                if (\is_object($attachment) && $attachment instanceof Swift_Mime_Attachment) {
                    $attachments = [
                        'Name'        => $attachment->getFilename(),
                        'Content'     => \base64_encode($attachment->getBody()),
                        'ContentType' => $attachment->getContentType(),
                    ];

                    if ($attachment->getDisposition() !== 'attachment' &&
                        $attachment->getId() !== null
                    ) {
                        $attachments['ContentID'] = 'cid:' . $attachment->getId();
                    }

                    $payload['Attachments'][] = $attachments;
                }
            }
        }

        return $payload;
    }

Applies the message parts and attachments
into the API Payload.

@param array                     $payload
@param \Swift_Mime_SimpleMessage $message

@return array

Applies the message parts and attachments into the API Payload .


protected function processHeaders(array $payload, Swift_Mime_SimpleMessage $message): array
    {
        $headers = [];

        foreach ($message->getHeaders()->getAll() as $key => $value) {
            $fieldName       = $value->getFieldName();
            $excludedHeaders = ['Subject', 'Content-Type', 'MIME-Version', 'Date'];

            if (! \in_array($fieldName, $excludedHeaders, true)) {
                if ($value instanceof Swift_Mime_Headers_UnstructuredHeader) {
                    $headers[] = [
                        'Name'  => $fieldName,
                        'Value' => $value->getValue(),
                    ];
                } elseif ($value instanceof Swift_Mime_Headers_DateHeader ||
                    $value instanceof Swift_Mime_Headers_IdentificationHeader ||
                    $value instanceof Swift_Mime_Headers_ParameterizedHeader ||
                    $value instanceof Swift_Mime_Headers_PathHeader
                ) {
                    $headers[] = [
                        'Name'  => $fieldName,
                        'Value' => $value->getFieldBody(),
                    ];

                    if ($value->getFieldName() === 'Message-ID') {
                        $headers[] = [
                            'Name'  => 'X-PM-KeepID',
                            'Value' => 'true',
                        ];
                    }
                }
            }
        }

        $payload['Headers'] = $headers;

        return $payload;
    }

protected function processHeaders ( array $ payload , Swift_Mime_SimpleMessage $ message ) : array { $ headers = [ ] ; foreach ( $ message -> getHeaders ( ) -> getAll ( ) as $ key => $ value ) { $ fieldName = $ value -> getFieldName ( ) ; $ excludedHeaders = [ 'Subject' , 'Content-Type' , 'MIME-Version' , 'Date' ] ; if ( ! \ in_array ( $ fieldName , $ excludedHeaders , true ) ) { if ( $ value instanceof Swift_Mime_Headers_UnstructuredHeader ) { $ headers [ ] = [ 'Name' => $ fieldName , 'Value' => $ value -> getValue ( ) , ] ; } elseif ( $ value instanceof Swift_Mime_Headers_DateHeader || $ value instanceof Swift_Mime_Headers_IdentificationHeader || $ value instanceof Swift_Mime_Headers_ParameterizedHeader || $ value instanceof Swift_Mime_Headers_PathHeader ) { $ headers [ ] = [ 'Name' => $ fieldName , 'Value' => $ value -> getFieldBody ( ) , ] ; if ( $ value -> getFieldName ( ) === 'Message-ID' ) { $ headers [ ] = [ 'Name' => 'X-PM-KeepID' , 'Value' => 'true' , ] ; } } } } $ payload [ 'Headers' ] = $ headers ; return $ payload ; }

Applies the headers into the API Payload.

@param array                     $payload
@param \Swift_Mime_SimpleMessage $message

@return array

Applies the headers into the API Payload .


protected function checkRequirements(): int
    {
        if ($this->documentRoot === null) {
            if ($this->hasOption('docroot')) {
                $this->documentRoot = $this->option('docroot');
            } else {
                $this->error('The document root directory must be either passed as first argument of the constructor or through the "--docroot" input option.');

                return 1;
            }
        }

        if ($this->environment === null) {
            if ($this->hasOption('env')) {
                if (\is_string($env = $this->option('env'))) {
                    $this->environment = $env;
                } else {
                    $this->error('The environment must be either passed as second argument of the constructor or through the "--env" input option.');

                    return 1;
                }
            } else {
                $this->error('The environment must be passed as second argument of the constructor.');

                return 1;
            }
        }

        if ($this->environment === 'prod') {
            $this->error('Running this server in production environment is NOT recommended!');
        }

        return 0;
    }

Check the requirements for the command.

@return int

Check the requirements for the command .


protected function getExtension(string $path): ?string
    {
        $callback = function ($value) use ($path) {
            return $this->endsWith($path, $value);
        };

        foreach (\array_keys(self::$extensions) as $key => $value) {
            if ($callback($value)) {
                return $value;
            }
        }

        return null;
    }

protected function getExtension ( string $ path ) : ? string { $ callback = function ( $ value ) use ( $ path ) { return $ this -> endsWith ( $ path , $ value ) ; } ; foreach ( \ array_keys ( self :: $ extensions ) as $ key => $ value ) { if ( $ callback ( $ value ) ) { return $ value ; } } return null ; }

Get the extension used by the view file.

@param string $path

@return null|string

Get the extension used by the view file .


protected function getView(
        FactoryContract $factory,
        EngineContract $engine,
        string $view,
        array $fileInfo,
        $data = []
    ): View {
        return new View($factory, $engine, $view, $fileInfo, $data);
    }

protected function getView ( FactoryContract $ factory , EngineContract $ engine , string $ view , array $ fileInfo , $ data = [ ] ) : View { return new View ( $ factory , $ engine , $ view , $ fileInfo , $ data ) ; }

Get the right view object.

@param \Viserio\Component\Contract\View\Factory            $factory
@param \Viserio\Component\Contract\View\Engine             $engine
@param string                                              $view
@param array                                               $fileInfo
@param array|\Viserio\Component\Contract\Support\Arrayable $data

@return \Viserio\Component\View\View


private function endsWith(string $haystack, string $needle): bool
    {
        $length = \mb_strlen($needle);

        if ($length === 0) {
            return true;
        }

        return \mb_substr($haystack, -$length) === $needle;
    }

private function endsWith ( string $ haystack , string $ needle ) : bool { $ length = \ mb_strlen ( $ needle ) ; if ( $ length === 0 ) { return true ; } return \ mb_substr ( $ haystack , - $ length ) === $ needle ; }

Determine if a given string ends with a given substring.

@param string $haystack
@param string $needle

@return bool

Determine if a given string ends with a given substring .


public function renderIntoCookieHeader(ServerRequestInterface $request): ServerRequestInterface
    {
        $cookieString = \implode('; ', $this->cookies);

        return $request->withHeader('cookie', $cookieString);
    }

public
function
renderIntoCookieHeader
(
ServerRequestInterface
$
request
)
:
ServerRequestInterface
{
$
cookieString
=
\
implode
(
'; '
,
$
this
->
cookies
)
;
return
$
request
->
withHeader
(
'cookie'
,
$
cookieString
)
;
}

Render Cookies into a Request.

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

@return \Psr\Http\Message\ServerRequestInterface


protected static function listFromCookieString(string $string): array
    {
        $cookies = self::splitOnAttributeDelimiter($string);

        return \array_map(static function ($cookiePair) {
            return self::oneFromCookiePair($cookiePair);
        }, $cookies);
    }

protected static function listFromCookieString ( string $ string ) : array { $ cookies = self :: splitOnAttributeDelimiter ( $ string ) ; return \ array_map ( static function ( $ cookiePair ) { return self :: oneFromCookiePair ( $ cookiePair ) ; } , $ cookies ) ; }

Create a list of Cookies from a Cookie header value string.

@param string $string

@return array

Create a list of Cookies from a Cookie header value string .


public function setError(Throwable $error): void
    {
        $this->parameters['error']     = $error;
        $this->parameters['exit_code'] = $error->getCode() ?: 1;
    }

public function setError ( Throwable $ error ) : void { $ this -> parameters [ 'error' ] = $ error ; $ this -> parameters [ 'exit_code' ] = $ error -> getCode ( ) ? : 1 ; }

Replaces the thrown exception.

This exception will be thrown if no response is set in the event.

@param \Throwable $error

@return void


public function setExitCode(int $exitCode): void
    {
        $this->parameters['exit_code'] = $exitCode;

        $r = new ReflectionProperty($this->parameters['error'], 'code');
        $r->setAccessible(true);
        $r->setValue($this->parameters['error'], $this->parameters['exit_code']);
    }

public function setExitCode ( int $ exitCode ) : void { $ this -> parameters [ 'exit_code' ] = $ exitCode ; $ r = new ReflectionProperty ( $ this -> parameters [ 'error' ] , 'code' ) ; $ r -> setAccessible ( true ) ; $ r -> setValue ( $ this -> parameters [ 'error' ] , $ this -> parameters [ 'exit_code' ] ) ; }

Sets the exit code.

@param int $exitCode The command exit code

@throws \ReflectionException

@return void


protected function toRoute(RouteContract $route, array $parameters, int $referenceType): string
    {
        $path = $this->prepareRoutePath($route, $parameters);
        $uri  = $this->uriFactory->createUri('/' . \ltrim($path, '/'));

        if (($host = $route->getDomain()) !== null) {
            $uri = $uri->withHost($host);
        } else {
            $uri = $uri->withHost($this->request->getUri()->getHost());
        }

        $requiredSchemes = $this->isSchemeRequired($route);

        if ($referenceType === self::ABSOLUTE_URL || $requiredSchemes || $referenceType === self::NETWORK_PATH) {
            $uri = $this->addPortAndSchemeToUri($uri, $route);
        }

        if ($referenceType === self::ABSOLUTE_URL || $requiredSchemes) {
            return (string) $uri;
        }

        if ($referenceType === self::NETWORK_PATH) {
            $uri = $uri->withScheme('');

            return (string) $uri;
        }

        return '/' . self::getRelativePath('//' . $uri->getHost() . '/', (string) $uri);
    }

protected function toRoute ( RouteContract $ route , array $ parameters , int $ referenceType ) : string { $ path = $ this -> prepareRoutePath ( $ route , $ parameters ) ; $ uri = $ this -> uriFactory -> createUri ( '/' . \ ltrim ( $ path , '/' ) ) ; if ( ( $ host = $ route -> getDomain ( ) ) !== null ) { $ uri = $ uri -> withHost ( $ host ) ; } else { $ uri = $ uri -> withHost ( $ this -> request -> getUri ( ) -> getHost ( ) ) ; } $ requiredSchemes = $ this -> isSchemeRequired ( $ route ) ; if ( $ referenceType === self :: ABSOLUTE_URL || $ requiredSchemes || $ referenceType === self :: NETWORK_PATH ) { $ uri = $ this -> addPortAndSchemeToUri ( $ uri , $ route ) ; } if ( $ referenceType === self :: ABSOLUTE_URL || $ requiredSchemes ) { return ( string ) $ uri ; } if ( $ referenceType === self :: NETWORK_PATH ) { $ uri = $ uri -> withScheme ( '' ) ; return ( string ) $ uri ; } return '/' . self :: getRelativePath ( '//' . $ uri -> getHost ( ) . '/' , ( string ) $ uri ) ; }

Get the URL for a given route instance.

@param \Viserio\Component\Contract\Routing\Route $route
@param array                                     $parameters
@param int                                       $referenceType

@return string

Get the URL for a given route instance .


protected function prepareRoutePath(RouteContract $route, array $parameters): string
    {
        $parameters = \array_replace($route->getParameters(), $parameters);

        // First we will construct the entire URI including the root and query string. Once it
        // has been constructed, we'll make sure we don't have any missing parameters or we
        // will need to throw the exception to let the developers know one was not given.
        $path = $this->addQueryString(
            $this->replaceRouteParameters($route->getUri(), $parameters),
            $parameters
        );

        \preg_match('/\\{(.*?)\\}/', $path, $matches);

        if (isset($matches[1]) && $matches[1] !== '') {
            throw new UrlGenerationException($route);
        }

        $path = $this->replacePathSegments($path);

        // Once we have ensured that there are no missing parameters in the URI we will encode
        // the URI and prepare it for returning to the developer.
        return \strtr(\rawurlencode($path), self::$dontEncode);
    }

Prepare route patch with all parameters and encode the path.

@param \Viserio\Component\Contract\Routing\Route $route
@param array                                     $parameters

@return string

Prepare route patch with all parameters and encode the path .


protected function isSchemeRequired(RouteContract $route): bool
    {
        $requiredSchemes = false;
        $requestScheme   = $this->request->getUri()->getScheme();

        if ($route->isHttpOnly()) {
            $requiredSchemes = $requestScheme !== 'http';
        } elseif ($route->isHttpsOnly()) {
            $requiredSchemes = $requestScheme !== 'https';
        }

        return $requiredSchemes;
    }

protected function isSchemeRequired ( RouteContract $ route ) : bool { $ requiredSchemes = false ; $ requestScheme = $ this -> request -> getUri ( ) -> getScheme ( ) ; if ( $ route -> isHttpOnly ( ) ) { $ requiredSchemes = $ requestScheme !== 'http' ; } elseif ( $ route -> isHttpsOnly ( ) ) { $ requiredSchemes = $ requestScheme !== 'https' ; } return $ requiredSchemes ; }

Check if a scheme is required.

@param \Viserio\Component\Contract\Routing\Route $route

@return bool


protected function addPortAndSchemeToUri(UriInterface $uri, RouteContract $route): UriInterface
    {
        if ($route->isHttpOnly()) {
            $secure = 'http';
            $port   = 80;
        } elseif ($route->isHttpsOnly()) {
            $secure = 'https';
            $port   = 443;
        } else {
            $requestUri = $this->request->getUri();
            $secure     = $requestUri->getScheme();
            $port       = $requestUri->getPort();
        }

        $uri = $uri->withScheme($secure);

        return $uri->withPort($port);
    }

protected function addPortAndSchemeToUri ( UriInterface $ uri , RouteContract $ route ) : UriInterface { if ( $ route -> isHttpOnly ( ) ) { $ secure = 'http' ; $ port = 80 ; } elseif ( $ route -> isHttpsOnly ( ) ) { $ secure = 'https' ; $ port = 443 ; } else { $ requestUri = $ this -> request -> getUri ( ) ; $ secure = $ requestUri -> getScheme ( ) ; $ port = $ requestUri -> getPort ( ) ; } $ uri = $ uri -> withScheme ( $ secure ) ; return $ uri -> withPort ( $ port ) ; }

Add the port and scheme to the uri if necessary.

@param \Psr\Http\Message\UriInterface            $uri
@param \Viserio\Component\Contract\Routing\Route $route

@return \Psr\Http\Message\UriInterface

Add the port and scheme to the uri if necessary .


protected function replaceRouteParameters(string $path, array &$parameters): string
    {
        $path = $this->replaceNamedParameters($path, $parameters);

        $path = \preg_replace_callback('/\{.*?\}/', static function ($match) use (&$parameters) {
            if (\count($parameters) === 0 && ! (\substr($match[0], -\strlen('?}')) === '?}')) {
                return $match[0];
            }

            return \array_shift($parameters);
        }, $path);

        return \trim(\preg_replace('/\{.*?\?\}/', '', $path), '/');
    }

protected function replaceRouteParameters ( string $ path , array & $ parameters ) : string { $ path = $ this -> replaceNamedParameters ( $ path , $ parameters ) ; $ path = \ preg_replace_callback ( '/\{.*?\}/' , static function ( $ match ) use ( & $ parameters ) { if ( \ count ( $ parameters ) === 0 && ! ( \ substr ( $ match [ 0 ] , - \ strlen ( '?}' ) ) === '?}' ) ) { return $ match [ 0 ] ; } return \ array_shift ( $ parameters ) ; } , $ path ) ; return \ trim ( \ preg_replace ( '/\{.*?\?\}/' , '' , $ path ) , '/' ) ; }

Replace all of the wildcard parameters for a route path.

@param string $path
@param array  $parameters

@return string

Replace all of the wildcard parameters for a route path .


protected function replaceNamedParameters(string $path, array &$parameters): string
    {
        return \preg_replace_callback('/\{(.*?)\??\}/', static function ($m) use (&$parameters) {
            if (isset($parameters[$m[1]]) && $parameters[$m[1]] !== '') {
                $parameter = $parameters[$m[1]];

                unset($parameters[$m[1]]);

                return $parameter;
            }

            return $m[0];
        }, $path);
    }

protected function replaceNamedParameters ( string $ path , array & $ parameters ) : string { return \ preg_replace_callback ( '/\{(.*?)\??\}/' , static function ( $ m ) use ( & $ parameters ) { if ( isset ( $ parameters [ $ m [ 1 ] ] ) && $ parameters [ $ m [ 1 ] ] !== '' ) { $ parameter = $ parameters [ $ m [ 1 ] ] ; unset ( $ parameters [ $ m [ 1 ] ] ) ; return $ parameter ; } return $ m [ 0 ] ; } , $ path ) ; }

Replace all of the named parameters in the path.

@param string $path
@param array  $parameters

@return string

Replace all of the named parameters in the path .


protected function addQueryString(string $uri, array $parameters): string
    {
        // If the URI has a fragment we will move it to the end of this URI since it will
        // need to come after any query string that may be added to the URL else it is
        // not going to be available. We will remove it then append it back on here.
        if (null !== ($fragment = \parse_url($uri, \PHP_URL_FRAGMENT))) {
            $uri = \preg_replace('/#.*/', '', $uri);
        }

        $uri .= $this->getRouteQueryString($parameters);

        if (null === $fragment) {
            return $uri;
        }

        return $uri . '#' . \strtr(\rawurlencode($fragment), ['%2F' => '/', '%3F' => '?']);
    }

Add a query string to the URI.

@param string $uri
@param array  $parameters

@return string


protected function getRouteQueryString(array $parameters): string
    {
        // First we will get all of the string parameters that are remaining after we
        // have replaced the route wildcards. We'll then build a query string from
        // these string parameters then use it as a starting point for the rest.
        if (\count($parameters) === 0 || \in_array(null, $parameters, true)) {
            return '';
        }

        $query = \http_build_query(
            $keyed = $this->getStringParameters($parameters),
            '',
            '&',
            \PHP_QUERY_RFC3986
        );

        // Lastly, if there are still parameters remaining, we will fetch the numeric
        // parameters that are in the array and add them to the query string or we
        // will make the initial query string if it wasn't started with strings.
        if (\count($keyed) < \count($parameters)) {
            $query .= '&' . \implode(
                '&',
                $this->getNumericParameters($parameters)
            );
        }

        // "/" and "?" can be left decoded for better user experience, see
        // http://tools.ietf.org/html/rfc3986#section-3.4
        return '?' . \trim(\strtr($query, ['%2F' => '/']), '&');
    }

Get the query string for a given route.

@param array $parameters

@return string

Get the query string for a given route .


protected function parseWhere($name, ?string $expression): array
    {
        if (\is_string($name)) {
            return [$name => $expression];
        }

        $arr = [];

        foreach ($name as $paramName) {
            $arr[$paramName] = $expression;
        }

        return $arr;
    }

protected function parseWhere ( $ name , ? string $ expression ) : array { if ( \ is_string ( $ name ) ) { return [ $ name => $ expression ] ; } $ arr = [ ] ; foreach ( $ name as $ paramName ) { $ arr [ $ paramName ] = $ expression ; } return $ arr ; }

Parse arguments to the where method into an array.

@param array|string $name
@param null|string  $expression

@return array

Parse arguments to the where method into an array .


protected function getControllerMiddleware(): array
    {
        if (! $this->isControllerAction()) {
            return [];
        }

        $controller = $this->getController();

        if (\method_exists($controller, 'gatherMiddleware')) {
            return $controller->gatherMiddleware();
        }

        return [];
    }

protected function getControllerMiddleware ( ) : array { if ( ! $ this -> isControllerAction ( ) ) { return [ ] ; } $ controller = $ this -> getController ( ) ; if ( \ method_exists ( $ controller , 'gatherMiddleware' ) ) { return $ controller -> gatherMiddleware ( ) ; } return [ ] ; }

Get the bound route controller middleware.

@return array

Get the bound route controller middleware .


protected function getControllerDisabledMiddleware(): array
    {
        if (! $this->isControllerAction()) {
            return [];
        }

        $controller = $this->getController();

        if (\method_exists($controller, 'gatherDisabledMiddleware')) {
            return $controller->gatherDisabledMiddleware();
        }

        return [];
    }

protected function getControllerDisabledMiddleware ( ) : array { if ( ! $ this -> isControllerAction ( ) ) { return [ ] ; } $ controller = $ this -> getController ( ) ; if ( \ method_exists ( $ controller , 'gatherDisabledMiddleware' ) ) { return $ controller -> gatherDisabledMiddleware ( ) ; } return [ ] ; }

Get the bound route controller disabled middleware.

@return array

Get the bound route controller disabled middleware .


public function add($cookie): self
    {
        if ($cookie instanceof Cookie || $cookie instanceof SetCookie) {
            $clone                              = clone $this;
            $clone->cookies[$cookie->getName()] = $cookie;

            return $clone;
        }

        throw new InvalidArgumentException(\sprintf(
            'The object [%s] must be an instance of [%s] or [%s].',
            \get_class($cookie),
            Cookie::class,
            SetCookie::class
        ));
    }

Add a request cookie to the stack.

@param \Viserio\Component\Contract\Cookie\Cookie|\Viserio\Component\Cookie\Cookie $cookie

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

@return $this


protected static function splitCookiePair(string $string): array
    {
        $pairParts = \explode('=', $string, 2);

        if (\count($pairParts) === 1) {
            $pairParts[1] = '';
        }

        return \array_map(static function ($part) {
            if ($part === null) {
                return '';
            }

            return \urldecode($part);
        }, $pairParts);
    }

protected static function splitCookiePair ( string $ string ) : array { $ pairParts = \ explode ( '=' , $ string , 2 ) ; if ( \ count ( $ pairParts ) === 1 ) { $ pairParts [ 1 ] = '' ; } return \ array_map ( static function ( $ part ) { if ( $ part === null ) { return '' ; } return \ urldecode ( $ part ) ; } , $ pairParts ) ; }

Split a string to array.

@param string $string

@return array


private function injectContentType(string $contentType, array $headers): array
    {
        $hasContentType = \array_reduce(\array_keys($headers), static function ($carry, $item) {
            return $carry ?: (\strtolower($item) === 'content-type');
        }, false);

        if (! $hasContentType) {
            $headers['Content-Type'] = [$contentType];
        }

        return $headers;
    }

private function injectContentType ( string $ contentType , array $ headers ) : array { $ hasContentType = \ array_reduce ( \ array_keys ( $ headers ) , static function ( $ carry , $ item ) { return $ carry ? : ( \ strtolower ( $ item ) === 'content-type' ) ; } , false ) ; if ( ! $ hasContentType ) { $ headers [ 'Content-Type' ] = [ $ contentType ] ; } return $ headers ; }

Inject the provided Content-Type, if none is already present.

@param string $contentType
@param array  $headers

@return array Headers with injected Content-Type

Inject the provided Content - Type if none is already present .


public static function words(string $value, int $words = 100, string $end = '...'): string
    {
        \preg_match('/^\s*+(?:\S++\s*+){1,' . $words . '}/u', $value, $matches);

        if (! isset($matches[0]) || \mb_strlen($value) === \mb_strlen($matches[0])) {
            return $value;
        }

        return \rtrim($matches[0]) . $end;
    }

public static function words ( string $ value , int $ words = 100 , string $ end = '...' ) : string { \ preg_match ( '/^\s*+(?:\S++\s*+){1,' . $ words . '}/u' , $ value , $ matches ) ; if ( ! isset ( $ matches [ 0 ] ) || \ mb_strlen ( $ value ) === \ mb_strlen ( $ matches [ 0 ] ) ) { return $ value ; } return \ rtrim ( $ matches [ 0 ] ) . $ end ; }

Limit the number of words in a string.

@param string $value
@param int    $words
@param string $end

@return string


public static function random(int $length = 64, string $characters = CharacterType::PRINTABLE_ASCII): string
    {
        $str = '';
        $l   = self::length($characters) - 1;

        for ($i = 0; $i < $length; $i++) {
            $r = \random_int(0, $l);
            $str .= $characters[$r];
        }

        return $str;
    }

public static function random ( int $ length = 64 , string $ characters = CharacterType :: PRINTABLE_ASCII ) : string { $ str = '' ; $ l = self :: length ( $ characters ) - 1 ; for ( $ i = 0 ; $ i < $ length ; $ i ++ ) { $ r = \ random_int ( 0 , $ l ) ; $ str .= $ characters [ $ r ] ; } return $ str ; }

Generate a random string of a given length and character set.

@param int    $length     How many characters do you want?
@param string $characters Which characters to choose from

@return string

Generate a random string of a given length and character set .


public static function replaceFirst(string $search, string $replace, string $subject): string
    {
        if ($search === '') {
            return $subject;
        }

        $position = \mb_strpos($subject, $search);

        return self::replaceByPosition($subject, $replace, $position, $search);
    }

public static function replaceFirst ( string $ search , string $ replace , string $ subject ) : string { if ( $ search === '' ) { return $ subject ; } $ position = \ mb_strpos ( $ subject , $ search ) ; return self :: replaceByPosition ( $ subject , $ replace , $ position , $ search ) ; }

Replace the first occurrence of a given value in the string.

@param string $search
@param string $replace
@param string $subject

@return string

Replace the first occurrence of a given value in the string .


public static function replaceLast(string $search, string $replace, string $subject): string
    {
        $position = \mb_strrpos($subject, $search);

        return self::replaceByPosition($subject, $replace, $position, $search);
    }

public static function replaceLast ( string $ search , string $ replace , string $ subject ) : string { $ position = \ mb_strrpos ( $ subject , $ search ) ; return self :: replaceByPosition ( $ subject , $ replace , $ position , $ search ) ; }

Replace the last occurrence of a given value in the string.

@param string $search
@param string $replace
@param string $subject

@return string

Replace the last occurrence of a given value in the string .


private static function replaceByPosition(string $subject, string $replace, $position, string $search): string
    {
        if ($position !== false) {
            return \substr_replace($subject, $replace, $position, \mb_strlen($search));
        }

        return $subject;
    }

private static function replaceByPosition ( string $ subject , string $ replace , $ position , string $ search ) : string { if ( $ position !== false ) { return \ substr_replace ( $ subject , $ replace , $ position , \ mb_strlen ( $ search ) ) ; } return $ subject ; }

Helper function for replaceLast and replaceFirst.

@param string   $subject
@param string   $replace
@param bool|int $position
@param string   $search

@return string

Helper function for replaceLast and replaceFirst .


public function getVerbosity($level = null): int
    {
        if ($level === null) {
            return $this->verbosity;
        }

        if (isset($this->verbosityMap[$level])) {
            return $this->verbosityMap[$level];
        }

        return (int) $level;
    }

public function getVerbosity ( $ level = null ) : int { if ( $ level === null ) { return $ this -> verbosity ; } if ( isset ( $ this -> verbosityMap [ $ level ] ) ) { return $ this -> verbosityMap [ $ level ] ; } return ( int ) $ level ; }

Get the verbosity level in terms of Symfony's OutputInterface level.

@param null|int|string $level

@return int

Get the verbosity level in terms of Symfony s OutputInterface level .


public function run(InputInterface $input, OutputInterface $output): int
    {
        $this->input  = $input;
        $this->output = new SymfonyStyle(
            $input,
            $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output
        );

        return parent::run($input, $output);
    }

public function run ( InputInterface $ input , OutputInterface $ output ) : int { $ this -> input = $ input ; $ this -> output = new SymfonyStyle ( $ input , $ output instanceof ConsoleOutputInterface ? $ output -> getErrorOutput ( ) : $ output ) ; return parent :: run ( $ input , $ output ) ; }

Run the console command.

@param \Symfony\Component\Console\Input\InputInterface   $input
@param \Symfony\Component\Console\Output\OutputInterface $output

@return int


public function call(string $command, array $arguments = []): int
    {
        return $this->getApplication()->call($command, $arguments, $this->getOutput());
    }

public function call ( string $ command , array $ arguments = [ ] ) : int { return $ this -> getApplication ( ) -> call ( $ command , $ arguments , $ this -> getOutput ( ) ) ; }

Call another console command.

@param string $command
@param array  $arguments

@return int


public function callSilent(string $command, array $arguments = []): int
    {
        return $this->getApplication()->call($command, $arguments, new NullOutput());
    }

public function callSilent ( string $ command , array $ arguments = [ ] ) : int { return $ this -> getApplication ( ) -> call ( $ command , $ arguments , new NullOutput ( ) ) ; }

Call another console command silently.

@param string $command
@param array  $arguments

@return int


public function argument(?string $key = null)
    {
        if ($key === null) {
            return $this->input->getArguments();
        }

        return $this->input->getArgument($key);
    }

public function argument ( ? string $ key = null ) { if ( $ key === null ) { return $ this -> input -> getArguments ( ) ; } return $ this -> input -> getArgument ( $ key ) ; }

Get the value of a command argument.

@param null|string $key

@return null|array|string


public function option(?string $key = null)
    {
        if ($key === null) {
            return $this->input->getOptions();
        }

        return $this->input->getOption($key);
    }

public function option ( ? string $ key = null ) { if ( $ key === null ) { return $ this -> input -> getOptions ( ) ; } return $ this -> input -> getOption ( $ key ) ; }

Get the value of a command option.

@param null|string $key

@return null|array|string


public function ask(string $question, ?string $default = null): ?string
    {
        return $this->getOutput()->ask($question, $default);
    }

public function ask ( string $ question , ? string $ default = null ) : ? string { return $ this -> getOutput ( ) -> ask ( $ question , $ default ) ; }

Prompt the user for input.

@param string      $question
@param null|string $default

@return null|string


public function anticipate(string $question, array $choices, string $default = null): ?string
    {
        return $this->askWithCompletion($question, $choices, $default);
    }

public function anticipate ( string $ question , array $ choices , string $ default = null ) : ? string { return $ this -> askWithCompletion ( $ question , $ choices , $ default ) ; }

Prompt the user for input with auto completion.

@param string $question
@param array  $choices
@param string $default

@return null|string

Prompt the user for input with auto completion .


public function choice(
        string $question,
        array $choices,
        ?string $default = null,
        $attempts        = null,
        bool $multiple   = false
    ): ?string {
        $question = new ChoiceQuestion($question, $choices, $default);

        $question->setMaxAttempts($attempts)->setMultiselect($multiple);

        return $this->getOutput()->askQuestion($question);
    }

public function choice ( string $ question , array $ choices , ? string $ default = null , $ attempts = null , bool $ multiple = false ) : ? string { $ question = new ChoiceQuestion ( $ question , $ choices , $ default ) ; $ question -> setMaxAttempts ( $ attempts ) -> setMultiselect ( $ multiple ) ; return $ this -> getOutput ( ) -> askQuestion ( $ question ) ; }

Give the user a single choice from an array of answers.

@param string      $question
@param array       $choices
@param null|string $default
@param mixed       $attempts
@param bool        $multiple

@return null|string

Give the user a single choice from an array of answers .


public function table(array $headers, $rows, string $style = 'default', array $columnStyles = []): void
    {
        $table = new Table($this->output);

        if ($rows instanceof Arrayable) {
            $rows = $rows->toArray();
        }

        $table->setHeaders($headers)->setRows($rows)->setStyle($style);

        foreach ($columnStyles as $columnIndex => $columnStyle) {
            $table->setColumnStyle($columnIndex, $columnStyle);
        }

        $table->render();
    }

public function table ( array $ headers , $ rows , string $ style = 'default' , array $ columnStyles = [ ] ) : void { $ table = new Table ( $ this -> output ) ; if ( $ rows instanceof Arrayable ) { $ rows = $ rows -> toArray ( ) ; } $ table -> setHeaders ( $ headers ) -> setRows ( $ rows ) -> setStyle ( $ style ) ; foreach ( $ columnStyles as $ columnIndex => $ columnStyle ) { $ table -> setColumnStyle ( $ columnIndex , $ columnStyle ) ; } $ table -> render ( ) ; }

Format input to textual table.

@param array                                               $headers
@param array|\Viserio\Component\Contract\Support\Arrayable $rows
@param string                                              $style
@param array                                               $columnStyles

@return void


public function line(string $string, ?string $style = null, $verbosityLevel = null): void
    {
        $styledString = $style ? "<${style}>${string}</${style}>" : $string;
        $this->getOutput()->writeln($styledString, $this->getVerbosity($verbosityLevel));
    }

public function line ( string $ string , ? string $ style = null , $ verbosityLevel = null ) : void { $ styledString = $ style ? "<${style}>${string}</${style}>" : $ string ; $ this -> getOutput ( ) -> writeln ( $ styledString , $ this -> getVerbosity ( $ verbosityLevel ) ) ; }

Write a string as standard output.

@param string          $string
@param null|string     $style          The output style of the string
@param null|int|string $verbosityLevel

@return void


public function info(string $string, $verbosityLevel = null): void
    {
        $this->line($string, 'info', $verbosityLevel);
    }

public function info ( string $ string , $ verbosityLevel = null ) : void { $ this -> line ( $ string , 'info' , $ verbosityLevel ) ; }

Write a string as information output.

@param string          $string
@param null|int|string $verbosityLevel

@return void


public function comment(string $string, $verbosityLevel = null): void
    {
        $this->line($string, 'comment', $verbosityLevel);
    }

public function comment ( string $ string , $ verbosityLevel = null ) : void { $ this -> line ( $ string , 'comment' , $ verbosityLevel ) ; }

Write a string as comment output.

@param string          $string
@param null|int|string $verbosityLevel

@return void