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

        $manager = new TranslationManager($container->get(MessageFormatterContract::class));

        if ($container->has(LoaderContract::class)) {
            $manager->setLoader($container->get(LoaderContract::class));
        }

        if (isset($options['locale'])) {
            $manager->setLocale($options['locale']);
        }

        if (isset($options['directories'])) {
            $manager->setDirectories($options['directories']);
        }

        if (isset($options['files'])) {
            foreach ((array) $options['files'] as $import) {
                $manager->import($import);
            }
        }

        if ($container->has(PsrLoggerInterface::class)) {
            $manager->setLogger($container->get(PsrLoggerInterface::class));
        }

        return $manager;
    }

public static function createTranslationManager ( ContainerInterface $ container ) : TranslationManagerContract { $ options = self :: resolveOptions ( $ container -> get ( 'config' ) ) ; $ manager = new TranslationManager ( $ container -> get ( MessageFormatterContract :: class ) ) ; if ( $ container -> has ( LoaderContract :: class ) ) { $ manager -> setLoader ( $ container -> get ( LoaderContract :: class ) ) ; } if ( isset ( $ options [ 'locale' ] ) ) { $ manager -> setLocale ( $ options [ 'locale' ] ) ; } if ( isset ( $ options [ 'directories' ] ) ) { $ manager -> setDirectories ( $ options [ 'directories' ] ) ; } if ( isset ( $ options [ 'files' ] ) ) { foreach ( ( array ) $ options [ 'files' ] as $ import ) { $ manager -> import ( $ import ) ; } } if ( $ container -> has ( PsrLoggerInterface :: class ) ) { $ manager -> setLogger ( $ container -> get ( PsrLoggerInterface :: class ) ) ; } return $ manager ; }

Create a new TranslationManager instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Contract\Translation\TranslationManager

Create a new TranslationManager instance .


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

        $scheduler = new Schedule($options['path'], $options['console']);

        if ($container->has(CacheItemPoolInterface::class)) {
            $scheduler->setCacheItemPool($container->get(CacheItemPoolInterface::class));
        }

        $scheduler->setContainer($container);

        return $scheduler;
    }

public static function createSchedule ( ContainerInterface $ container ) : Schedule { $ options = self :: resolveOptions ( $ container -> get ( 'config' ) ) ; $ scheduler = new Schedule ( $ options [ 'path' ] , $ options [ 'console' ] ) ; if ( $ container -> has ( CacheItemPoolInterface :: class ) ) { $ scheduler -> setCacheItemPool ( $ container -> get ( CacheItemPoolInterface :: class ) ) ; } $ scheduler -> setContainer ( $ container ) ; return $ scheduler ; }

Create a new Schedule instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Cron\Schedule


private function getComputedData(string $index)
    {
        if (\count($this->computed) === 0) {
            $this->computed = $this->generateComputeData($this->getProfile());
        }

        return $this->computed[$index];
    }

private function getComputedData ( string $ index ) { if ( \ count ( $ this -> computed ) === 0 ) { $ this -> computed = $ this -> generateComputeData ( $ this -> getProfile ( ) ) ; } return $ this -> computed [ $ index ] ; }

Get computed data.

@param string $index

@return mixed


protected function createSwiftMailer(Swift_Transport $transport): Swift_Mailer
    {
        if (isset($this->resolvedOptions['domain'])) {
            Swift_DependencyContainer::getInstance()
                ->register('mime.idgenerator.idright')
                ->asValue($this->resolvedOptions['domain']);
        }

        return new Swift_Mailer($transport);
    }

protected function createSwiftMailer ( Swift_Transport $ transport ) : Swift_Mailer { if ( isset ( $ this -> resolvedOptions [ 'domain' ] ) ) { Swift_DependencyContainer :: getInstance ( ) -> register ( 'mime.idgenerator.idright' ) -> asValue ( $ this -> resolvedOptions [ 'domain' ] ) ; } return new Swift_Mailer ( $ transport ) ; }

Create a new SwiftMailer instance.

@param \Swift_Transport $transport

@return \Swift_Mailer


private function createMailer(Swift_Transport $transport, array $config): MailerContract
    {
        $swiftMailer = $this->createSwiftMailer($transport);

        if ($this->queueManager !== null) {
            $mailer = new QueueMailer($swiftMailer, $this->queueManager, $config);
        } else {
            $mailer = new Mailer($swiftMailer, $config);
        }

        if ($this->container !== null) {
            $mailer->setContainer($this->container);
        }

        if ($this->viewFactory !== null) {
            $mailer->setViewFactory($this->viewFactory);
        }

        if ($this->eventManager !== null) {
            $mailer->setEventManager($this->eventManager);
        }

        // Next we will set all of the global addresses on this mailer, which allows
        // for easy unification of all "from" addresses as well as easy debugging
        // of sent messages since they get be sent into a single email address.
        foreach (['from', 'reply_to', 'to'] as $type) {
            $this->setGlobalAddress($mailer, $type);
        }

        return $mailer;
    }

Create a mailer or queue mailer instance.

@param \Swift_Transport $transport
@param array            $config

@return \Viserio\Component\Contract\Mail\Mailer|\Viserio\Component\Contract\Mail\QueueMailer

Create a mailer or queue mailer instance .


private function setGlobalAddress(MailerContract $mailer, string $type): void
    {
        if (! isset($this->resolvedOptions[$type])) {
            return;
        }

        $address = $this->resolvedOptions[$type];

        if (\is_array($address) && isset($address['address'])) {
            $mailer->{'always' . Str::studly($type)}($address['address'], $address['name']);
        }
    }

private function setGlobalAddress ( MailerContract $ mailer , string $ type ) : void { if ( ! isset ( $ this -> resolvedOptions [ $ type ] ) ) { return ; } $ address = $ this -> resolvedOptions [ $ type ] ; if ( \ is_array ( $ address ) && isset ( $ address [ 'address' ] ) ) { $ mailer -> { 'always' . Str :: studly ( $ type ) } ( $ address [ 'address' ] , $ address [ 'name' ] ) ; } }

Set a global address on the mailer by type.

@param \Viserio\Component\Contract\Mail\Mailer $mailer
@param string                                  $type

@return void

Set a global address on the mailer by type .


protected function createTooltipGroup(array $data): string
    {
        $tooltip = '
';

        foreach ($data as $strong => $infos) {
            $tooltip .= '
';

            if (\is_array($infos)) {
                $tooltip .= '' . $strong . '';

                foreach ($infos as $info) {
                    $class = isset($info['class']) ? ' class="' . $info['class'] . '"' : '';

                    $tooltip .= '' . $info['value'] . '';
                }
            } elseif (\is_int($strong) && \is_string($infos)) {
                $tooltip .= $infos;
            } else {
                $tooltip .= '' . $strong . '' . $infos . '';
            }

            $tooltip .= '
';
        }

        $tooltip .= '
';

        return $tooltip;
    }

Creates a tooltip group from array.

array[]
['key']       string          Defines the name of <b> html element.
['value']     array|string    Defines the content to be shown in the <span> html element.
['class'] string          Adds a class to the <span> html element.
['value'] string          Adds the content.

@param array $data (See above)

@return string


protected function createTabs(array $data): string
    {
        $html = '
';

        foreach ($data as $key => $value) {
            $id = \uniqid($key . '-', true);

            $html .= '
';
            $html .= '<input type="radio" name="tabgroup" id="tab-' . $id . '">';
            $html .= '' . $value['name'] . '';
            $html .= '
';
            $html .= $value['content'];
            $html .= '

';
        }

        $html .= '
';

        return $html;
    }

Creates a tab slider.

array[]         array     Defines witch tabs a shown.
['name']    string    Name of the tab
['content'] string    Tab content.

@param array $data (See above)

@return string


protected function createTable(array $data, array $settings = []): string
    {
        $options = \array_merge([
            'name'       => null,
            'headers'    => ['Key', 'Value'],
            'vardumper'  => true,
            'empty_text' => 'Empty',
        ], $settings);

        $html = $options['name'] !== null ? '
' . $options['name'] . '
' : '';

        if (\count($data) !== 0) {
            $html .= '

';

            foreach ((array) $options['headers'] as $header) {
                $html .= '' . $header . '	';
            }

            $html .= '

';

            foreach ($data as $key => $values) {
                if (\is_string($key)) {
                    $html .= '
';
                    $html .= '' . $key . '	';
                    $html .= \sprintf('%s	', ($options['vardumper'] ? $this->cloneVar($values) : $values));
                    $html .= '
';
                } else {
                    $html .= '
';

                    if (\is_array($values)) {
                        foreach ($values as $k => $value) {
                            $html .= \sprintf('%s	', ($options['vardumper'] ? $this->cloneVar($value) : $value));
                        }
                    } else {
                        $html .= \sprintf('%s	', ($options['vardumper'] ? $this->cloneVar($values) : $values));
                    }

                    $html .= '
';
                }
            }

            $html .= '

';
        } else {
            $html .= \sprintf('
%s
', $options['empty_text']);
        }

        return $html;
    }

protected
function
createTable
(
array
$
data
,
array
$
settings
=
[
]
)
:
string
{
$
options
=
\
array_merge
(
[
'name'
=>
,
'headers'
=>
[
'Key'
,
'Value'
]
,
'vardumper'
=>
true
,
'empty_text'
=>
'Empty'
,
]
,
$
settings
)
;
$
html
=
$
options
[
'name'
]
!==
'
'
.
$
options
[
'name'
]
.
'
'
:
''
;
if
(
\
count
(
$
data
)
!==
0
)
{
$
html
.=
'

'
;
foreach
(
(
array
)
$
options
[
'headers'
]
as
$
header
)
{
$
html
.=
''
.
$
header
.
'	'
;
}
$
html
.=
'

'
;
foreach
(
$
data
as
$
key
=>
$
values
)
{
if
(
\
is_string
(
$
key
)
)
{
$
html
.=
'
'
;
$
html
.=
''
.
$
key
.
'	'
;
$
html
.=
\
sprintf
(
'%s	'
,
(
$
options
[
'vardumper'
]
$
this
->
cloneVar
(
$
values
)
:
$
values
)
)
;
$
html
.=
'
'
;
}
else
{
$
html
.=
'
'
;
if
(
\
is_array
(
$
values
)
)
{
foreach
(
$
values
as
$
k
=>
$
value
)
{
$
html
.=
\
sprintf
(
'%s	'
,
(
$
options
[
'vardumper'
]
$
this
->
cloneVar
(
$
value
)
:
$
value
)
)
;
}
}
else
{
$
html
.=
\
sprintf
(
'%s	'
,
(
$
options
[
'vardumper'
]
$
this
->
cloneVar
(
$
values
)
:
$
values
)
)
;
}
$
html
.=
'
'
;
}
}
$
html
.=
'

'
;
}
else
{
$
html
.=
\
sprintf
(
'
%s
'
,
$
options
[
'empty_text'
]
)
;
}
return
$
html
;
}

Creates a table.

@param array $data
@param array $settings

@return string


protected function createDropdownMenuContent(array $data): string
    {
        $selects  = $content  = [];
        $selected = false;

        foreach ($data as $key => $value) {
            $id = 'content-' . $key . '-' . \uniqid('', true);

            $selected = $selected === false ? $selected = 'selected' : '';

            $selects[$key] = '<option value="' . $id . '"' . $selected . '>' . $key . '</option>';
            $content[$key] = '
' . $value . '
';
        }

        $html = '<select class="content-selector" name="' . $this->getName() . '">';

        foreach ($selects as $key => $value) {
            $html .= $value;
        }

        $html .= '</select>';

        foreach ($content as $key => $value) {
            $html .= $value;
        }

        return $html;
    }

Create a dropdown menu content.

@param array $data

@return string


protected function createMetrics(array $data, ?string $name = null): string
    {
        $html = $name !== null ? '
' . $name . '
' : '';
        $html .= '
';

        foreach ($data as $key => $value) {
            $html .= '
';
            $html .= '' . $value . '' . $key . '';
            $html .= '
';
        }

        $html .= '
';

        return $html;
    }

protected
function
createMetrics
(
array
$
data
,
string
$
name
=
)
:
string
{
$
html
=
$
name
!==
'
'
.
$
name
.
'
'
:
''
;
$
html
.=
'
'
;
foreach
(
$
data
as
$
key
=>
$
value
)
{
$
html
.=
'
'
;
$
html
.=
''
.
$
value
.
''
.
$
key
.
''
;
$
html
.=
'
'
;
}
$
html
.=
'
'
;
return
$
html
;
}

Create a metrics.

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

@return string


protected function cloneVar($var): ?string
    {
        $cloneVar = self::getCloner()->cloneVar($this->decorateVar($var), Caster::EXCLUDE_VERBOSE);
        $dumper   = self::getDumper();

        $dumper->dump(
            $cloneVar,
            self::$htmlDumperOutput
        );

        $output = self::$htmlDumperOutput->getOutput();
        self::$htmlDumperOutput->reset();

        return $output;
    }

protected function cloneVar ( $ var ) : ? string { $ cloneVar = self :: getCloner ( ) -> cloneVar ( $ this -> decorateVar ( $ var ) , Caster :: EXCLUDE_VERBOSE ) ; $ dumper = self :: getDumper ( ) ; $ dumper -> dump ( $ cloneVar , self :: $ htmlDumperOutput ) ; $ output = self :: $ htmlDumperOutput -> getOutput ( ) ; self :: $ htmlDumperOutput -> reset ( ) ; return $ output ; }

Converts the variable into a serializable Data instance.

@param mixed $var

@return null|string

Converts the variable into a serializable Data instance .


private static function getCloner(): AbstractCloner
    {
        if (self::$cloner === null) {
            self::$cloner = new VarCloner();
            self::$cloner->setMaxItems(250);
            self::$cloner->addCasters([
                Stub::class => static function (Stub $v, array $a, Stub $s, $isNested) {
                    return $isNested ? $a : StubCaster::castStub($v, $a, $s, true);
                },
            ]);
        }

        return self::$cloner;
    }

private static function getCloner ( ) : AbstractCloner { if ( self :: $ cloner === null ) { self :: $ cloner = new VarCloner ( ) ; self :: $ cloner -> setMaxItems ( 250 ) ; self :: $ cloner -> addCasters ( [ Stub :: class => static function ( Stub $ v , array $ a , Stub $ s , $ isNested ) { return $ isNested ? $ a : StubCaster :: castStub ( $ v , $ a , $ s , true ) ; } , ] ) ; } return self :: $ cloner ; }

Get the cloner used for dumping variables.

@return \Symfony\Component\VarDumper\Cloner\AbstractCloner

Get the cloner used for dumping variables .


private static function getDumper(): HtmlDumper
    {
        if (self::$htmlDumper === null) {
            self::$htmlDumperOutput = new HtmlDumperOutput();

            // re-use the same var-dumper instance, so it won't re-render the global styles/scripts on each dump.
            self::$htmlDumper = new HtmlDumper(self::$htmlDumperOutput);
        }

        return self::$htmlDumper;
    }

Get a HtmlDumper instance.

@return \Viserio\Component\Support\Debug\HtmlDumper


public function append(string $code): void
    {
        $indent = \str_repeat(' ', 4 * $this->indent);

        $this->code .= $indent . \str_replace(\PHP_EOL, \PHP_EOL . $indent, $code);
    }

public
function
append
(
string
$
code
)
:
void
{
$
indent
=
\
str_repeat
(
' '
,
4
*
$
this
->
indent
)
;
$
this
->
code
.=
$
indent
.
\
str_replace
(
\
PHP_EOL
,
\
PHP_EOL
.
$
indent
,
$
code
)
;
}

Appends the supplied code to the builder.

@param string $code

Appends the supplied code to the builder .


public function appendLine(string $code = ''): void
    {
        $this->append($code);
        $this->code .= \PHP_EOL;
    }

public function appendLine ( string $ code = '' ) : void { $ this -> append ( $ code ) ; $ this -> code .= \ PHP_EOL ; }

Appends the supplied code and a new line to the builder.

@param string $code

Appends the supplied code and a new line to the builder .


protected function addExtensions(Environment $twig, array $config): Environment
    {
        if (isset($config['extensions']) && \is_array($config['extensions'])) {
            foreach ($config['extensions'] as $extension) {
                if ($this->container !== null && \is_string($extension) && $this->container->has($extension)) {
                    $twig->addExtension($this->container->get($extension));
                } elseif (\is_object($extension) && $extension instanceof ExtensionInterface) {
                    $twig->addExtension($extension);
                } else {
                    throw new RuntimeException(\sprintf(
                        'Twig extension [%s] is not a object.',
                        $extension
                    ));
                }
            }
        }

        return $twig;
    }

protected
function
addExtensions
(
Environment
$
twig
,
array
$
config
)
:
Environment
{
if
(
isset
(
$
config
[
'extensions'
]
)
&&
\
is_array
(
$
config
[
'extensions'
]
)
)
{
foreach
(
$
config
[
'extensions'
]
as
$
extension
)
{
if
(
$
this
->
container
!==
&&
\
is_string
(
$
extension
)
&&
$
this
->
container
->
has
(
$
extension
)
)
{
$
twig
->
addExtension
(
$
this
->
container
->
get
(
$
extension
)
)
;
}
elseif
(
\
is_object
(
$
extension
)
&&
$
extension
instanceof
ExtensionInterface
)
{
$
twig
->
addExtension
(
$
extension
)
;
}
else
{
throw
new
RuntimeException
(
\
sprintf
(
'Twig extension [%s] is not a object.'
,
$
extension
)
)
;
}
}
}
return
$
twig
;
}

Add extensions to twig environment.

@param \Twig\Environment $twig
@param array             $config

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

@return \Twig\Environment


protected function doSortMiddleware(array $priorityMap, array $middleware): array
    {
        $lastIndex = $lastPriorityIndex = 0;

        foreach ($middleware as $index => $mware) {
            if (\in_array($mware, $priorityMap, true)) {
                $priorityIndex = \array_search($mware, $priorityMap, true);

                // This middleware is in the priority map. If we have encountered another middleware
                // that was also in the priority map and was at a lower priority than the current
                // middleware, we will move this middleware to be above the previous encounter.
                if (isset($lastPriorityIndex) && $priorityIndex < $lastPriorityIndex) {
                    return $this->doSortMiddleware(
                        $priorityMap,
                        \array_values(
                            $this->moveMiddleware($middleware, $index, $lastIndex)
                        )
                    );
                }

                // This middleware is in the priority map; but, this is the first middleware we have
                // encountered from the map thus far. We'll save its current index plus its index
                // from the priority map so we can compare against them on the next iterations.
                $lastIndex         = $index;
                $lastPriorityIndex = $priorityIndex;
            }
        }

        return \array_values(\array_unique($middleware, \SORT_REGULAR));
    }

Sort the middleware by the given priority map.

Each call to this method makes one discrete middleware movement if necessary.

@param array $priorityMap
@param array $middleware

@return array

Sort the middleware by the given priority map .


protected function moveMiddleware(array $middleware, int $from, int $to): array
    {
        \array_splice($middleware, $to, 0, $middleware[$from]);

        unset($middleware[$from + 1]);

        return $middleware;
    }

protected function moveMiddleware ( array $ middleware , int $ from , int $ to ) : array { \ array_splice ( $ middleware , $ to , 0 , $ middleware [ $ from ] ) ; unset ( $ middleware [ $ from + 1 ] ) ; return $ middleware ; }

Splice a middleware into a new position and remove the old entry.

@param array $middleware
@param int   $from
@param int   $to

@return array

Splice a middleware into a new position and remove the old entry .


protected function createAggregateDriver(array $config): LoggerInterface
    {
        $handlers = [];

        foreach ((array) $config['channels'] as $channel) {
            foreach ($this->getDriver($channel)->getHandlers() as $handler) {
                $handlers[] = $handler;
            }
        }

        return new Monolog($this->parseChannel($config), $handlers);
    }

protected function createAggregateDriver ( array $ config ) : LoggerInterface { $ handlers = [ ] ; foreach ( ( array ) $ config [ 'channels' ] as $ channel ) { foreach ( $ this -> getDriver ( $ channel ) -> getHandlers ( ) as $ handler ) { $ handlers [ ] = $ handler ; } } return new Monolog ( $ this -> parseChannel ( $ config ) , $ handlers ) ; }

Create a aggregate log driver instance.

@param array $config

@return \Psr\Log\LoggerInterface

Create a aggregate log driver instance .


protected function createEmergencyDriver(): LoggerInterface
    {
        $handler = new StreamHandler(
            $this->getFilePath(),
            self::parseLevel('debug'),
            $config['bubble'] ?? true,
            $config['permission'] ?? null,
            $config['locking'] ?? false
        );
        $handler->setFormatter($this->getConfiguredLineFormatter());

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

protected function createEmergencyDriver ( ) : LoggerInterface { $ handler = new StreamHandler ( $ this -> getFilePath ( ) , self :: parseLevel ( 'debug' ) , $ config [ 'bubble' ] ?? true , $ config [ 'permission' ] ?? null , $ config [ 'locking' ] ?? false ) ; $ handler -> setFormatter ( $ this -> getConfiguredLineFormatter ( ) ) ; return new Monolog ( $ this -> resolvedOptions [ 'name' ] , [ $ handler ] ) ; }

Create an emergency log handler to avoid white screens of death.

@throws \Exception
@throws \InvalidArgumentException

@return \Psr\Log\LoggerInterface

Create an emergency log handler to avoid white screens of death .


protected function createSingleDriver(array $config): LoggerInterface
    {
        $handler = new StreamHandler(
            $this->getFilePath(),
            self::parseLevel($config['level'] ?? 'debug'),
            $config['bubble'] ?? true,
            $config['permission'] ?? null,
            $config['locking'] ?? false
        );
        $handler->setFormatter($this->getConfiguredLineFormatter());

        return new Monolog($this->parseChannel($config), [$handler]);
    }

protected function createSingleDriver ( array $ config ) : LoggerInterface { $ handler = new StreamHandler ( $ this -> getFilePath ( ) , self :: parseLevel ( $ config [ 'level' ] ?? 'debug' ) , $ config [ 'bubble' ] ?? true , $ config [ 'permission' ] ?? null , $ config [ 'locking' ] ?? false ) ; $ handler -> setFormatter ( $ this -> getConfiguredLineFormatter ( ) ) ; return new Monolog ( $ this -> parseChannel ( $ config ) , [ $ handler ] ) ; }

Create an instance of the single file log driver.

@param array $config

@throws \Exception
@throws \InvalidArgumentException

@return \Psr\Log\LoggerInterface

Create an instance of the single file log driver .


protected function createDailyDriver(array $config): LoggerInterface
    {
        $handler = new RotatingFileHandler(
            $this->getFilePath(),
            $config['days'] ?? 7,
            self::parseLevel($config['level'] ?? 'debug'),
            $config['bubble'] ?? true,
            $config['permission'] ?? null,
            $config['locking'] ?? false
        );
        $handler->setFormatter($this->getConfiguredLineFormatter());

        return new Monolog($this->parseChannel($config), [$handler]);
    }

protected function createDailyDriver ( array $ config ) : LoggerInterface { $ handler = new RotatingFileHandler ( $ this -> getFilePath ( ) , $ config [ 'days' ] ?? 7 , self :: parseLevel ( $ config [ 'level' ] ?? 'debug' ) , $ config [ 'bubble' ] ?? true , $ config [ 'permission' ] ?? null , $ config [ 'locking' ] ?? false ) ; $ handler -> setFormatter ( $ this -> getConfiguredLineFormatter ( ) ) ; return new Monolog ( $ this -> parseChannel ( $ config ) , [ $ handler ] ) ; }

Create an instance of the daily file log driver.

@param array $config

@throws \InvalidArgumentException

@return \Psr\Log\LoggerInterface

Create an instance of the daily file log driver .


protected function createSyslogDriver(array $config): LoggerInterface
    {
        $handler = new SyslogHandler(
            $config['name'],
            $config['facility'] ?? \LOG_USER,
            self::parseLevel($config['level'] ?? 'debug')
        );
        $handler->setFormatter($this->getConfiguredLineFormatter());

        return new Monolog($this->parseChannel($config), [$handler]);
    }

protected function createSyslogDriver ( array $ config ) : LoggerInterface { $ handler = new SyslogHandler ( $ config [ 'name' ] , $ config [ 'facility' ] ?? \ LOG_USER , self :: parseLevel ( $ config [ 'level' ] ?? 'debug' ) ) ; $ handler -> setFormatter ( $ this -> getConfiguredLineFormatter ( ) ) ; return new Monolog ( $ this -> parseChannel ( $ config ) , [ $ handler ] ) ; }

Create an instance of the syslog log driver.

@param array $config

@throws \InvalidArgumentException

@return \Psr\Log\LoggerInterface

Create an instance of the syslog log driver .


protected function createErrorlogDriver(array $config): LoggerInterface
    {
        $handler = new ErrorLogHandler(
            $config['type'] ?? ErrorLogHandler::OPERATING_SYSTEM,
            self::parseLevel($config['level'] ?? 'debug')
        );
        $handler->setFormatter($this->getConfiguredLineFormatter());

        return new Monolog($this->parseChannel($config), [$handler]);
    }

protected function createErrorlogDriver ( array $ config ) : LoggerInterface { $ handler = new ErrorLogHandler ( $ config [ 'type' ] ?? ErrorLogHandler :: OPERATING_SYSTEM , self :: parseLevel ( $ config [ 'level' ] ?? 'debug' ) ) ; $ handler -> setFormatter ( $ this -> getConfiguredLineFormatter ( ) ) ; return new Monolog ( $ this -> parseChannel ( $ config ) , [ $ handler ] ) ; }

Create an instance of the "error log" log driver.

@param array $config

@throws \InvalidArgumentException

@return \Psr\Log\LoggerInterface

Create an instance of the error log log driver .


protected function createSlackDriver(array $config): LoggerInterface
    {
        $handler = new SlackWebhookHandler(
            $config['url'],
            $config['channel'] ?? null,
            $config['username'] ?? $this->resolvedOptions['name'],
            $config['attachment'] ?? true,
            $config['emoji'] ?? ':boom:',
            $config['short'] ?? false,
            $config['context'] ?? true,
            self::parseLevel($config['level'] ?? 'debug'),
            $config['bubble'] ?? true,
            $config['exclude_fields'] ?? []
        );
        $handler->setFormatter($this->getConfiguredLineFormatter());

        return new Monolog($this->parseChannel($config), [$handler]);
    }

protected function createSlackDriver ( array $ config ) : LoggerInterface { $ handler = new SlackWebhookHandler ( $ config [ 'url' ] , $ config [ 'channel' ] ?? null , $ config [ 'username' ] ?? $ this -> resolvedOptions [ 'name' ] , $ config [ 'attachment' ] ?? true , $ config [ 'emoji' ] ?? ':boom:' , $ config [ 'short' ] ?? false , $ config [ 'context' ] ?? true , self :: parseLevel ( $ config [ 'level' ] ?? 'debug' ) , $ config [ 'bubble' ] ?? true , $ config [ 'exclude_fields' ] ?? [ ] ) ; $ handler -> setFormatter ( $ this -> getConfiguredLineFormatter ( ) ) ; return new Monolog ( $ this -> parseChannel ( $ config ) , [ $ handler ] ) ; }

Create an instance of the Slack log driver.

@param array $config

@throws \InvalidArgumentException

@return \Psr\Log\LoggerInterface

Create an instance of the Slack log driver .


protected function createCustomDriver(array $config): LoggerInterface
    {
        $via            = $config['via'];
        $config['name'] = $config['original_name'];

        unset($config['original_name']);

        if (\is_callable($via)) {
            return $via($config);
        }

        if ($this->container !== null && $this->container->has($via)) {
            return $this->container->get($via);
        }

        throw new RuntimeException(\sprintf(
            'Given custom logger [%s] could not be resolved.',
            $config['name']
        ));
    }

Create a custom log driver instance.

@param array $config

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

@return \Psr\Log\LoggerInterface


protected function createMonologDriver(array $config): LoggerInterface
    {
        if ($this->container === null) {
            throw new RuntimeException('No container instance was found.');
        }

        $config['name'] = $config['original_name'];

        unset($config['original_name']);

        if ($this->container->has($config['handler'])) {
            $handler = $this->container->get($config['handler']);

            if (! \is_a($handler, HandlerInterface::class, true)) {
                throw new InvalidArgumentException(\sprintf('[%s] must be an instance of [%s]', $config['handler'], HandlerInterface::class));
            }
        } else {
            throw new InvalidArgumentException(\sprintf('Handler [%s] is not managed by the container.', $config['handler']));
        }

        if (! isset($config['formatter'])) {
            $handler->setFormatter($this->getConfiguredLineFormatter());
        } elseif ($config['formatter'] !== 'default') {
            $handler->setFormatter($this->container->get($config['formatter']));
        }

        $monolog = new Monolog($this->parseChannel($config));

        $monolog->pushHandler($handler);

        return $monolog;
    }

Create an instance of any handler available in Monolog.

@param array $config

@throws \InvalidArgumentException

@return \Psr\Log\LoggerInterface

Create an instance of any handler available in Monolog .


protected function pushProcessorsToMonolog(array $config, Monolog $driver): Monolog
    {
        $processors = $this->processors;

        if (isset($config['processors'])) {
            $processors = \array_merge($processors, $config['processors']);
        }

        foreach ($processors as $processor) {
            $driver->pushProcessor($processor);
        }

        return $driver;
    }

protected function pushProcessorsToMonolog ( array $ config , Monolog $ driver ) : Monolog { $ processors = $ this -> processors ; if ( isset ( $ config [ 'processors' ] ) ) { $ processors = \ array_merge ( $ processors , $ config [ 'processors' ] ) ; } foreach ( $ processors as $ processor ) { $ driver -> pushProcessor ( $ processor ) ; } return $ driver ; }

Push given processors to monolog.

@param array           $config
@param \Monolog\Logger $driver

@return \Monolog\Logger


public function createFromArray(
        array $server,
        array $headers = [],
        array $cookie  = [],
        array $get     = [],
        array $post    = [],
        array $files   = [],
        $body          = null
    ): ServerRequestInterface {
        if (isset($server['SERVER_ADDR'])) {
            $server['SERVER_ADDR'] = \str_replace('Server IP: ', '', $server['SERVER_ADDR']);
        }

        $serverRequest = new ServerRequest(
            Uri::createFromServer($server),
            $this->getMethodFromServer($server),
            $headers,
            $body,
            $this->marshalProtocolVersion($server),
            $server
        );

        return $serverRequest
            ->withCookieParams($cookie)
            ->withQueryParams($get)
            ->withParsedBody($post)
            ->withUploadedFiles(Util::normalizeFiles($files));
    }

public
function
createFromArray
(
array
$
server
,
array
$
headers
=
[
]
,
array
$
cookie
=
[
]
,
array
$
get
=
[
]
,
array
$
post
=
[
]
,
array
$
files
=
[
]
,
$
body
=
)
:
ServerRequestInterface
{
if
(
isset
(
$
server
[
'SERVER_ADDR'
]
)
)
{
$
server
[
'SERVER_ADDR'
]
=
\
str_replace
(
'Server IP: '
,
''
,
$
server
[
'SERVER_ADDR'
]
)
;
}
$
serverRequest
=
new
ServerRequest
(
Uri
::
createFromServer
(
$
server
)
,
$
this
->
getMethodFromServer
(
$
server
)
,
$
headers
,
$
body
,
$
this
->
marshalProtocolVersion
(
$
server
)
,
$
server
)
;
return
$
serverRequest
->
withCookieParams
(
$
cookie
)
->
withQueryParams
(
$
get
)
->
withParsedBody
(
$
post
)
->
withUploadedFiles
(
Util
::
normalizeFiles
(
$
files
)
)
;
}

Create a new server request from a set of arrays.

@param array                                                         $server  typically $_SERVER or similar structure
@param array                                                         $headers typically the output of getallheaders() or similar structure
@param array                                                         $cookie  typically $_COOKIE or similar structure
@param array                                                         $get     typically $_GET or similar structure
@param array                                                         $post    typically $_POST or similar structure
@param array                                                         $files   typically $_FILES or similar structure
@param null|\Psr\Http\Message\ServerRequestInterface|resource|string $body    Typically stdIn

@throws \InvalidArgumentException if no valid method or URI can be determined

@return \Psr\Http\Message\ServerRequestInterface

Create a new server request from a set of arrays .


public static function singular(string $value): string
    {
        $singular = Inflector::singularize($value);

        return static::matchCase($singular, $value);
    }

public static function singular ( string $ value ) : string { $ singular = Inflector :: singularize ( $ value ) ; return static :: matchCase ( $ singular , $ value ) ; }

Get the singular form of an English word.

@param string $value

@return string

Get the singular form of an English word .


protected static function matchCase(string $value, string $comparison): string
    {
        $functions = ['mb_strtolower', 'mb_strtoupper', 'ucfirst', 'ucwords'];

        foreach ($functions as $function) {
            if ($function($comparison) === $comparison) {
                return $function($value);
            }
        }

        return $value;
    }

protected static function matchCase ( string $ value , string $ comparison ) : string { $ functions = [ 'mb_strtolower' , 'mb_strtoupper' , 'ucfirst' , 'ucwords' ] ; foreach ( $ functions as $ function ) { if ( $ function ( $ comparison ) === $ comparison ) { return $ function ( $ value ) ; } } return $ value ; }

Attempt to match the case on two strings.

@param string $value
@param string $comparison

@return string

Attempt to match the case on two strings .


public function connect(): AdapterInterface
    {
        return new Local(
            $this->resolvedOptions['path'],
            $this->resolvedOptions['write_flags'],
            $this->resolvedOptions['link_handling'],
            $this->resolvedOptions['permissions']
        );
    }

public function connect ( ) : AdapterInterface { return new Local ( $ this -> resolvedOptions [ 'path' ] , $ this -> resolvedOptions [ 'write_flags' ] , $ this -> resolvedOptions [ 'link_handling' ] , $ this -> resolvedOptions [ 'permissions' ] ) ; }

Establish a connection.

@throws \Viserio\Component\Contract\OptionsResolver\Exception\InvalidArgumentException On wrong configuration

@return \League\Flysystem\Adapter\Local


public static function createCerebro(ContainerInterface $container): Application
    {
        $console = new Application();
        $console->setContainer($container);

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

        return $console;
    }

public static function createCerebro ( ContainerInterface $ container ) : Application { $ console = new Application ( ) ; $ console -> setContainer ( $ container ) ; if ( $ container -> has ( EventManagerContract :: class ) ) { $ console -> setEventManager ( $ container -> get ( EventManagerContract :: class ) ) ; } return $ console ; }

Create a new console application instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Console\Application

Create a new console application instance .


public static function merge(array $new, array $old): array
    {
        if (isset($new['domain'])) {
            unset($old['domain']);
        }

        $new = \array_merge(static::formatAs($new, $old), [
            'namespace' => static::formatNamespace($new, $old),
            'prefix'    => static::formatGroupPrefix($new, $old),
            'where'     => static::formatWhere($new, $old),
            'suffix'    => static::formatGroupSuffix($new, $old),
        ]);

        foreach (['namespace', 'prefix', 'suffix', 'where', 'as'] as $name) {
            if (isset($old[$name])) {
                unset($old[$name]);
            }
        }

        return \array_merge_recursive($old, $new);
    }

public static function merge ( array $ new , array $ old ) : array { if ( isset ( $ new [ 'domain' ] ) ) { unset ( $ old [ 'domain' ] ) ; } $ new = \ array_merge ( static :: formatAs ( $ new , $ old ) , [ 'namespace' => static :: formatNamespace ( $ new , $ old ) , 'prefix' => static :: formatGroupPrefix ( $ new , $ old ) , 'where' => static :: formatWhere ( $ new , $ old ) , 'suffix' => static :: formatGroupSuffix ( $ new , $ old ) , ] ) ; foreach ( [ 'namespace' , 'prefix' , 'suffix' , 'where' , 'as' ] as $ name ) { if ( isset ( $ old [ $ name ] ) ) { unset ( $ old [ $ name ] ) ; } } return \ array_merge_recursive ( $ old , $ new ) ; }

Merge route groups into a new array.

@param array $new
@param array $old

@return array


protected static function formatGroupSuffix(array $new, array $old): ?string
    {
        $oldSuffix = $old['suffix'] ?? null;

        if (isset($new['suffix'])) {
            return \trim($new['suffix']) . \trim($oldSuffix);
        }

        return $oldSuffix;
    }

protected static function formatGroupSuffix ( array $ new , array $ old ) : ? string { $ oldSuffix = $ old [ 'suffix' ] ?? null ; if ( isset ( $ new [ 'suffix' ] ) ) { return \ trim ( $ new [ 'suffix' ] ) . \ trim ( $ oldSuffix ) ; } return $ oldSuffix ; }

Format the suffix for the new group attributes.

@param array $new
@param array $old

@return null|string

Format the suffix for the new group attributes .


protected static function checkForSpecificEnvironmentFile(KernelContract $kernel, ?string $env): void
    {
        if ($kernel->isRunningInConsole() && ($input = new ArgvInput())->hasParameterOption(['--env', '-e'])) {
            if (static::setEnvironmentFilePath(
                $kernel,
                $kernel->getEnvironmentFile() . '.' . $input->getParameterOption(['--env', '-e'])
            )) {
                return;
            }
        }

        if ($env === null) {
            return;
        }

        static::setEnvironmentFilePath($kernel, $kernel->getEnvironmentFile() . '.' . $env);
    }

protected static function checkForSpecificEnvironmentFile ( KernelContract $ kernel , ? string $ env ) : void { if ( $ kernel -> isRunningInConsole ( ) && ( $ input = new ArgvInput ( ) ) -> hasParameterOption ( [ '--env' , '-e' ] ) ) { if ( static :: setEnvironmentFilePath ( $ kernel , $ kernel -> getEnvironmentFile ( ) . '.' . $ input -> getParameterOption ( [ '--env' , '-e' ] ) ) ) { return ; } } if ( $ env === null ) { return ; } static :: setEnvironmentFilePath ( $ kernel , $ kernel -> getEnvironmentFile ( ) . '.' . $ env ) ; }

Detect if a custom environment file matching the APP_ENV exists.

@param \Viserio\Component\Contract\Foundation\Kernel $kernel
@param null|string                                   $env

@return void

Detect if a custom environment file matching the APP_ENV exists .


protected static function setEnvironmentFilePath(KernelContract $kernel, string $file): bool
    {
        if (\file_exists($kernel->getEnvironmentPath() . \DIRECTORY_SEPARATOR . $file)) {
            $kernel->loadEnvironmentFrom($file);

            return true;
        }

        return false;
    }

protected static function setEnvironmentFilePath ( KernelContract $ kernel , string $ file ) : bool { if ( \ file_exists ( $ kernel -> getEnvironmentPath ( ) . \ DIRECTORY_SEPARATOR . $ file ) ) { $ kernel -> loadEnvironmentFrom ( $ file ) ; return true ; } return false ; }

Load a custom environment file.

@param \Viserio\Component\Contract\Foundation\Kernel $kernel
@param string                                        $file

@return bool


public function getTransport(string $transport, array $config): Swift_Transport
    {
        // If the given transport has not been created before, we will create the instances
        // here and cache it so we can return it next time very quickly. If there is
        // already a transport created by this name, we'll just return that instance.
        if (! isset($this->transports[$transport])) {
            $this->transports[$transport] = $this->createTransport($transport, $config);
        }

        return $this->transports[$transport];
    }

Get a transport instance.

@param string $transport
@param array  $config

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

@return \Swift_Transport


public function createTransport(string $transport, array $config): Swift_Transport
    {
        $method = 'create' . Str::studly($transport) . 'Transport';

        $config['name'] = $transport;

        return $this->create($config, $method);
    }

public function createTransport ( string $ transport , array $ config ) : Swift_Transport { $ method = 'create' . Str :: studly ( $ transport ) . 'Transport' ; $ config [ 'name' ] = $ transport ; return $ this -> create ( $ config , $ method ) ; }

Make a new transport instance.

@param string $transport
@param array  $config

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

@return \Swift_Transport


public function hasTransport(string $transport): bool
    {
        $method = 'create' . Str::studly($transport) . 'Transport';

        return \method_exists($this, $method) || isset($this->extensions[$transport]);
    }

public function hasTransport ( string $ transport ) : bool { $ method = 'create' . Str :: studly ( $ transport ) . 'Transport' ; return \ method_exists ( $ this , $ method ) || isset ( $ this -> extensions [ $ transport ] ) ; }

Check if the given transport is supported.

@param string $transport

@return bool

Check if the given transport is supported .


protected function createSmtpTransport(array $config): Swift_SmtpTransport
    {
        // The Swift SMTP transport instance will allow us to use any SMTP backend
        // for delivering mail such as Amazon SES, Sendgrid or a custom server
        // a developer has available.
        $transport = new Swift_SmtpTransport(
            $config['host'],
            $config['port']
        );

        if (isset($config['encryption'])) {
            $transport->setEncryption($config['encryption']);
        }

        // Once we have the transport we will check for the presence of a username
        // and password.
        if (isset($config['username'], $config['password'])) {
            $transport->setUsername($config['username']);
            $transport->setPassword($config['password']);
        }

        if (isset($config['stream'])) {
            $transport->setStreamOptions($config['stream']);
        }

        return $transport;
    }

Create an instance of the SMTP Swift Transport driver.

@param array $config

@return \Swift_SmtpTransport

Create an instance of the SMTP Swift Transport driver .


protected function createMailgunTransport(array $config): MailgunTransport
    {
        return new MailgunTransport(
            $this->getHttpClient($config),
            $config['secret'],
            $config['domain'],
            $config['base_url'] ?? null
        );
    }

protected function createMailgunTransport ( array $ config ) : MailgunTransport { return new MailgunTransport ( $ this -> getHttpClient ( $ config ) , $ config [ 'secret' ] , $ config [ 'domain' ] , $ config [ 'base_url' ] ?? null ) ; }

Create an instance of the Mailgun Swift Transport driver.

@param array $config

@return \Viserio\Component\Mail\Transport\MailgunTransport

Create an instance of the Mailgun Swift Transport driver .


protected function createSparkPostTransport(array $config): SparkPostTransport
    {
        return new SparkPostTransport(
            $this->getHttpClient($config),
            $config['secret'],
            $config['options'] ?? [],
            $config['endpoint'] ?? null
        );
    }

protected function createSparkPostTransport ( array $ config ) : SparkPostTransport { return new SparkPostTransport ( $ this -> getHttpClient ( $ config ) , $ config [ 'secret' ] , $ config [ 'options' ] ?? [ ] , $ config [ 'endpoint' ] ?? null ) ; }

Create an instance of the SparkPost Swift Transport driver.

@param array $config

@return \Viserio\Component\Mail\Transport\SparkPostTransport

Create an instance of the SparkPost Swift Transport driver .


protected function createSesTransport(array $config): SesTransport
    {
        $config += [
            'version' => 'latest',
            'service' => 'email',
        ];

        if (isset($config['key'], $config['secret'])) {
            $config['credentials'] = \array_intersect_key($config, \array_flip(['key', 'secret', 'token']));
        }

        return new SesTransport(new SesClient($config));
    }

protected function createSesTransport ( array $ config ) : SesTransport { $ config += [ 'version' => 'latest' , 'service' => 'email' , ] ; if ( isset ( $ config [ 'key' ] , $ config [ 'secret' ] ) ) { $ config [ 'credentials' ] = \ array_intersect_key ( $ config , \ array_flip ( [ 'key' , 'secret' , 'token' ] ) ) ; } return new SesTransport ( new SesClient ( $ config ) ) ; }

Create an instance of the Amazon SES Swift Transport driver.

@param array $config

@throws \InvalidArgumentException

@return \Viserio\Component\Mail\Transport\SesTransport

Create an instance of the Amazon SES Swift Transport driver .


public static function createRepository(ContainerInterface $container): RepositoryContract
    {
        $config = new Repository();

        if ($container->has(LoaderContract::class)) {
            $config->setLoader($container->get(LoaderContract::class));
        }

        $config->addParameterProcessor(new EnvParameterProcessor());

        return $config;
    }

public static function createRepository ( ContainerInterface $ container ) : RepositoryContract { $ config = new Repository ( ) ; if ( $ container -> has ( LoaderContract :: class ) ) { $ config -> setLoader ( $ container -> get ( LoaderContract :: class ) ) ; } $ config -> addParameterProcessor ( new EnvParameterProcessor ( ) ) ; return $ config ; }

Create a new Repository instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Contract\Config\Repository


public function update(array $matchers, $contents): RouteTreeNode
    {
        if ($this->matchers === $matchers && $this->contents === $contents) {
            return $this;
        }

        $clone           = clone $this;
        $clone->matchers = $matchers;
        $clone->contents = $contents;

        return $clone;
    }

public function update ( array $ matchers , $ contents ) : RouteTreeNode { if ( $ this -> matchers === $ matchers && $ this -> contents === $ contents ) { return $ this ; } $ clone = clone $ this ; $ clone -> matchers = $ matchers ; $ clone -> contents = $ contents ; return $ clone ; }

Update RouteTreeNode class.

@param array                                                                                $matchers
@param \Viserio\Component\Routing\TreeGenerator\ChildrenNodeCollection|\Viserio\Component\Routing\TreeGenerator\MatchedRouteDataMap $contents

@throws \RuntimeException

@return \Viserio\Component\Routing\TreeGenerator\RouteTreeNode


public function registerEvents(EventManagerContract $eventManager): void
    {
        // Before a command is executed, the handler gets activated and the console output
        // is set in order to know where to write the logs.
        $eventManager->attach(
            ConsoleEvents::COMMAND,
            function (ConsoleCommandEvent $event): void {
                $output = $event->getOutput();

                if ($output instanceof ConsoleOutputInterface) {
                    $output = $output->getErrorOutput();
                }

                $this->setOutput($output);
            },
            255
        );

        // After a command has been executed, it disables the output.
        $eventManager->attach(
            ConsoleEvents::TERMINATE,
            function (): void {
                $this->close();
            },
            -255
        );
    }

Register needed events to event manager.

@param \Viserio\Component\Contract\Events\EventManager $eventManager

@return void

Register needed events to event manager .


public static function extendTwigEnvironment(
        ContainerInterface $container,
        ?TwigEnvironment $twig = null
    ): ?TwigEnvironment {
        if ($twig !== null) {
            if ($container->has(Lexer::class)) {
                $twig->setLexer($container->get(Lexer::class));
            }

            if ($twig->isDebug() && \class_exists(VarCloner::class)) {
                $twig->addExtension(new DumpExtension());
            }

            self::registerViserioTwigExtension($twig, $container);
        }

        return $twig;
    }

public static function extendTwigEnvironment ( ContainerInterface $ container , ? TwigEnvironment $ twig = null ) : ? TwigEnvironment { if ( $ twig !== null ) { if ( $ container -> has ( Lexer :: class ) ) { $ twig -> setLexer ( $ container -> get ( Lexer :: class ) ) ; } if ( $ twig -> isDebug ( ) && \ class_exists ( VarCloner :: class ) ) { $ twig -> addExtension ( new DumpExtension ( ) ) ; } self :: registerViserioTwigExtension ( $ twig , $ container ) ; } return $ twig ; }

Extend the twig environment.

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

@return null|\Twig\Environment


protected static function registerViserioTwigExtension(TwigEnvironment $twig, ContainerInterface $container): void
    {
        if ($container->has(TranslationManagerContract::class)) {
            $twig->addExtension(new TranslatorExtension($container->get(TranslationManagerContract::class)));
        }

        if (\class_exists(Str::class)) {
            $twig->addExtension(new StrExtension());
        }

        if ($container->has(StoreContract::class)) {
            $twig->addExtension(new SessionExtension($container->get(StoreContract::class)));
        }

        if ($container->has(RepositoryContract::class)) {
            $twig->addExtension(new ConfigExtension($container->get(RepositoryContract::class)));
        }
    }

protected static function registerViserioTwigExtension ( TwigEnvironment $ twig , ContainerInterface $ container ) : void { if ( $ container -> has ( TranslationManagerContract :: class ) ) { $ twig -> addExtension ( new TranslatorExtension ( $ container -> get ( TranslationManagerContract :: class ) ) ) ; } if ( \ class_exists ( Str :: class ) ) { $ twig -> addExtension ( new StrExtension ( ) ) ; } if ( $ container -> has ( StoreContract :: class ) ) { $ twig -> addExtension ( new SessionExtension ( $ container -> get ( StoreContract :: class ) ) ) ; } if ( $ container -> has ( RepositoryContract :: class ) ) { $ twig -> addExtension ( new ConfigExtension ( $ container -> get ( RepositoryContract :: class ) ) ) ; } }

Register viserio twig extension.

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

@return void


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

        foreach ($this->httpMethodRouteMap as $item) {
            foreach ($item[0] as $method) {
                $allowedHttpMethods[] = $method;
            }
        }

        return \array_values($allowedHttpMethods);
    }

public function allowedHttpMethods ( ) : array { $ allowedHttpMethods = [ ] ; foreach ( $ this -> httpMethodRouteMap as $ item ) { foreach ( $ item [ 0 ] as $ method ) { $ allowedHttpMethods [ ] = $ method ; } } return \ array_values ( $ allowedHttpMethods ) ; }

Get all allowed http methods.

@return array


public function addRoute(RouteContract $route, array $parameterIndexNameMap): void
    {
        $this->httpMethodRouteMap[] = [$route->getMethods(), [$parameterIndexNameMap, $route->getIdentifier()]];
    }

public function addRoute ( RouteContract $ route , array $ parameterIndexNameMap ) : void { $ this -> httpMethodRouteMap [ ] = [ $ route -> getMethods ( ) , [ $ parameterIndexNameMap , $ route -> getIdentifier ( ) ] ] ; }

Adds the supplied route to the matched route data map.

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

Adds the supplied route to the matched route data map .


private function isPipe(): bool
    {
        if ($this->isPipe === null) {
            $this->isPipe = false;

            if (isset($this->stream)) {
                $mode         = \fstat($this->stream)['mode'];
                $this->isPipe = ($mode & self::FSTAT_MODE_S_IFIFO) !== 0;
            }
        }

        return $this->isPipe;
    }

private function isPipe ( ) : bool { if ( $ this -> isPipe === null ) { $ this -> isPipe = false ; if ( isset ( $ this -> stream ) ) { $ mode = \ fstat ( $ this -> stream ) [ 'mode' ] ; $ this -> isPipe = ( $ mode & self :: FSTAT_MODE_S_IFIFO ) !== 0 ; } } return $ this -> isPipe ; }

Returns whether or not the stream is a pipe.

@return bool

Returns whether or not the stream is a pipe .


public function addMimeType(string $mimeType, string $extension): void
    {
        self::$supportedMimeTypes[$mimeType] = $extension;
    }

public function addMimeType ( string $ mimeType , string $ extension ) : void { self :: $ supportedMimeTypes [ $ mimeType ] = $ extension ; }

Add a new mime type with extension.

@param string $mimeType
@param string $extension

@return void


public function addParser(ParserContract $parser, string $extension): void
    {
        self::$supportedParsers[$extension] = $parser;
    }

public function addParser ( ParserContract $ parser , string $ extension ) : void { self :: $ supportedParsers [ $ extension ] = $ parser ; }

Add a new parser.

@param \Viserio\Component\Contract\Parser\Parser $parser
@param string                                    $extension

@return void


public function parse(string $payload): array
    {
        if ($payload === '') {
            return [];
        }

        $format = $this->getFormat($payload);

        if ($format !== 'php' && \is_file($payload)) {
            $payload = \file_get_contents($payload);

            if ($payload === false) {
                throw new RuntimeException(\sprintf('A error occurred during reading [%s]', $payload));
            }
        }

        return $this->getParser($format)->parse($payload);
    }

public
function
parse
(
string
$
payload
)
:
array
{
if
(
$
payload
===
''
)
{
return
[
]
;
}
$
format
=
$
this
->
getFormat
(
$
payload
)
;
if
(
$
format
!==
'php'
&&
\
is_file
(
$
payload
)
)
{
$
payload
=
\
file_get_contents
(
$
payload
)
;
if
(
$
payload
===
false
)
{
throw
new
RuntimeException
(
\
sprintf
(
'A error occurred during reading [%s]'
,
$
payload
)
)
;
}
}
return
$
this
->
getParser
(
$
format
)
->
parse
(
$
payload
)
;
}

Parse given file path or content string.

@param string $payload

@throws \Viserio\Component\Contract\Parser\Exception\ParseException
@throws \RuntimeException                                           if an error occurred during reading

@return array

Parse given file path or content string .


public function getParser(string $type): ParserContract
    {
        if (isset(self::$supportedParsers[$type])) {
            return new self::$supportedParsers[$type]();
        }

        if (isset(self::$supportedMimeTypes[$type])) {
            $class = self::$supportedParsers[self::$supportedMimeTypes[$type]];

            if (\is_object($class) && $class instanceof ParserContract) {
                return $class;
            }

            return new $class();
        }

        throw new NotSupportedException(\sprintf('Given extension or mime type [%s] is not supported.', $type));
    }

Get supported parser on extension or mime type.

@param string $type

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

@return \Viserio\Component\Contract\Parser\Parser

Get supported parser on extension or mime type .


protected function getFormat(string $payload): string
    {
        $format = '';

        if (\is_file($file = $payload)) {
            $format = \pathinfo($file, \PATHINFO_EXTENSION);
        } elseif (\is_string($payload)) {
            // try if content is json
            \json_decode($payload);

            if (\json_last_error() === \JSON_ERROR_NONE) {
                return 'json';
            }

            $format = (new finfo(\FILEINFO_MIME_TYPE))->buffer($payload);
        }

        return self::$supportedMimeTypes[$format] ?? $format;
    }

protected
function
getFormat
(
string
$
payload
)
:
string
{
$
format
=
''
;
if
(
\
is_file
(
$
file
=
$
payload
)
)
{
$
format
=
\
pathinfo
(
$
file
,
\
PATHINFO_EXTENSION
)
;
}
elseif
(
\
is_string
(
$
payload
)
)
{
// try if content is json
\
json_decode
(
$
payload
)
;
if
(
\
json_last_error
(
)
===
\
JSON_ERROR_NONE
)
{
return
'json'
;
}
$
format
=
(
new
finfo
(
\
FILEINFO_MIME_TYPE
)
)
->
buffer
(
$
payload
)
;
}
return
self
::
$
supportedMimeTypes
[
$
format
]
??
$
format
;
}

Auto detect the payload data type using finfo and pathinfo.

@param string $payload

@return string Tries to return the short format code (xml, json, ...) else the mime type

Auto detect the payload data type using finfo and pathinfo .


public function classSetUp(): void
    {
        $this->config   = $this->getTestConfig();
        $this->configId = $this->isId ? 'orm_default' : null;
    }

public function classSetUp ( ) : void { $ this -> config = $ this -> getTestConfig ( ) ; $ this -> configId = $ this -> isId ? 'orm_default' : null ; }


public function getRequestDuration(): float
    {
        if ($this->requestEndTime !== null) {
            return $this->requestEndTime - $this->requestStartTime;
        }

        return \microtime(true) - $this->requestStartTime;
    }

public function getRequestDuration ( ) : float { if ( $ this -> requestEndTime !== null ) { return $ this -> requestEndTime - $ this -> requestStartTime ; } return \ microtime ( true ) - $ this -> requestStartTime ; }

Returns the duration of a request.

@return float


public function stopMeasure(string $name, array $params = []): void
    {
        $end = \microtime(true);

        if (! $this->hasStartedMeasure($name)) {
            throw new RuntimeException(\sprintf(
                'Failed stopping measure [%s] because it hasn\'t been started.',
                $name
            ));
        }

        $this->addMeasure(
            $this->startedMeasures[$name]['label'],
            $this->startedMeasures[$name]['start'],
            $end,
            $params,
            $this->startedMeasures[$name]['collector']
        );

        unset($this->startedMeasures[$name]);
    }

Stops a measure.

@param string $name
@param array  $params

@throws \RuntimeException

@return void


public function addMeasure(
        string $label,
        float $start,
        float $end,
        array $params      = [],
        ?string $collector = null
    ): void {
        $this->measures[] = [
            'label'          => $label,
            'start'          => $start,
            'relative_start' => $start - $this->requestStartTime,
            'end'            => $end,
            'relative_end'   => $end - $this->requestEndTime,
            'duration'       => $end - $start,
            'duration_str'   => $this->formatDuration($end - $start),
            'params'         => $params,
            'collector'      => $collector,
        ];
    }

public function addMeasure ( string $ label , float $ start , float $ end , array $ params = [ ] , ? string $ collector = null ) : void { $ this -> measures [ ] = [ 'label' => $ label , 'start' => $ start , 'relative_start' => $ start - $ this -> requestStartTime , 'end' => $ end , 'relative_end' => $ end - $ this -> requestEndTime , 'duration' => $ end - $ start , 'duration_str' => $ this -> formatDuration ( $ end - $ start ) , 'params' => $ params , 'collector' => $ collector , ] ; }

Adds a measure.

@param string      $label
@param float       $start
@param float       $end
@param array       $params
@param null|string $collector

@return void


public static function identify(Throwable $exception): string
    {
        $hash = \spl_object_hash($exception);

        // if we know about the exception, return it's id
        if (isset(self::$identification[$hash])) {
            return self::$identification[$hash];
        }

        // cleanup in preparation for the identification
        if (\count((array) self::$identification) >= 16) {
            \array_shift(self::$identification);
        }

        // generate, store, and return the id
        return self::$identification[$hash] = self::uuid4();
    }

Identify the given exception.

@param \Throwable $exception

@return string


private static function uuid4(): string
    {
        $hash   = \bin2hex(\random_bytes(16));
        $timeHi = \hexdec(\substr($hash, 12, 4)) & 0x0fff;
        $timeHi &= ~0xf000;
        $timeHi |= 4 << 12;

        $clockSeqHi = \hexdec(\substr($hash, 16, 2)) & 0x3f;
        $clockSeqHi &= ~0xc0;
        $clockSeqHi |= 0x80;

        $params = [\substr($hash, 0, 8), \substr($hash, 8, 4), \sprintf('%04x', $timeHi), \sprintf('%02x', $clockSeqHi), \substr($hash, 18, 2), \substr($hash, 20, 12)];

        return \vsprintf('%08s-%04s-%04s-%02s%02s-%012s', $params);
    }

private static function uuid4 ( ) : string { $ hash = \ bin2hex ( \ random_bytes ( 16 ) ) ; $ timeHi = \ hexdec ( \ substr ( $ hash , 12 , 4 ) ) & 0x0fff ; $ timeHi &= ~ 0xf000 ; $ timeHi |= 4 << 12 ; $ clockSeqHi = \ hexdec ( \ substr ( $ hash , 16 , 2 ) ) & 0x3f ; $ clockSeqHi &= ~ 0xc0 ; $ clockSeqHi |= 0x80 ; $ params = [ \ substr ( $ hash , 0 , 8 ) , \ substr ( $ hash , 8 , 4 ) , \ sprintf ( '%04x' , $ timeHi ) , \ sprintf ( '%02x' , $ clockSeqHi ) , \ substr ( $ hash , 18 , 2 ) , \ substr ( $ hash , 20 , 12 ) ] ; return \ vsprintf ( '%08s-%04s-%04s-%02s%02s-%012s' , $ params ) ; }

Generate v4 UUID.

We're generating uuids according to the official v4 spec.

@return string


protected function setHeaders(array $headers): void
    {
        if (\count($headers) === 0) {
            return;
        }

        $this->headerNames = $this->headers = [];

        foreach ($headers as $header => $value) {
            $value      = $this->filterHeaderValue($value);
            $normalized = \strtolower($header);

            if (isset($this->headerNames[$normalized])) {
                $header                 = (string) $this->headerNames[$normalized];
                $this->headers[$header] += $value;
            } else {
                $this->headerNames[$normalized] = $header;
                $this->headers[$header]         = $value;
            }
        }
    }

protected function setHeaders ( array $ headers ) : void { if ( \ count ( $ headers ) === 0 ) { return ; } $ this -> headerNames = $ this -> headers = [ ] ; foreach ( $ headers as $ header => $ value ) { $ value = $ this -> filterHeaderValue ( $ value ) ; $ normalized = \ strtolower ( $ header ) ; if ( isset ( $ this -> headerNames [ $ normalized ] ) ) { $ header = ( string ) $ this -> headerNames [ $ normalized ] ; $ this -> headers [ $ header ] += $ value ; } else { $ this -> headerNames [ $ normalized ] = $ header ; $ this -> headers [ $ header ] = $ value ; } } }

Set validated headers.

@param array $headers

@return void


private function validateProtocolVersion(string $version): void
    {
        if ($version === '') {
            throw new InvalidArgumentException('HTTP protocol version can not be empty.');
        }

        if (! isset(self::$validProtocolVersions[$version])) {
            throw new InvalidArgumentException(
                \sprintf('Invalid HTTP version. Must be one of: [%s].', \implode(', ', \array_keys(self::$validProtocolVersions)))
            );
        }
    }

Validate the HTTP protocol version.

@param string $version

@throws \Viserio\Component\Contract\Http\Exception\InvalidArgumentException on invalid HTTP protocol version

@return void


private function arrayContainsOnlyStrings(array $array): bool
    {
        // Test if a value is a string.
        $filterStringValue = static function (bool $carry, $item) {
            if (! \is_string($item)) {
                return false;
            }

            return $carry;
        };

        return \array_reduce($array, $filterStringValue, true);
    }

private
function
arrayContainsOnlyStrings
(
array
$
array
)
:
bool
{
// Test if a value is a string.
$
filterStringValue
=
static
function
(
bool
$
carry
,
$
item
)
{
if
(
!
\
is_string
(
$
item
)
)
{
return
false
;
}
return
$
carry
;
}
;
return
\
array_reduce
(
$
array
,
$
filterStringValue
,
true
)
;
}

Test that an array contains only strings.

@param array $array

@return bool

Test that an array contains only strings .


private function filterHeaderValue($values): array
    {
        if (! \is_array($values)) {
            $values = [$values];
        }

        if (\count($values) === 0 || ! $this->arrayContainsOnlyStrings($values)) {
            throw new InvalidArgumentException(
                'Invalid header value: must be a string or array of strings and cannot be an empty array.'
            );
        }

        $values = \array_map(static function ($value) {
            // @see http://tools.ietf.org/html/rfc7230#section-3.2
            HeaderSecurity::assertValid($value);

            $value = (string) $value;

            // Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
            //
            // header-field = field-name ":" OWS field-value OWS
            // OWS          = *( SP / HTAB )
            //
            // @see https://tools.ietf.org/html/rfc7230#section-3.2.4
            return \trim($value, " \t");
        }, \array_values($values));

        return \array_map([HeaderSecurity::class, 'filter'], \array_values($values));
    }

Filter array headers.

@param array|string $values

@return array


protected function getRetryTime(): ?int
    {
        $retry = $this->option('retry');

        return \is_numeric($retry) && $retry > 0 ? (int) $retry : null;
    }

protected function getRetryTime ( ) : ? int { $ retry = $ this -> option ( 'retry' ) ; return \ is_numeric ( $ retry ) && $ retry > 0 ? ( int ) $ retry : null ; }

Get the number of seconds the client should wait before retrying their request.

@return null|int

Get the number of seconds the client should wait before retrying their request .


protected function getInvoker(): Invoker
    {
        if ($this->invoker === null) {
            $this->invoker = new Invoker();

            if ($this->container !== null) {
                $this->invoker->setContainer($this->container)
                    ->injectByTypeHint(true)
                    ->injectByParameterName(true);
            }
        }

        return $this->invoker;
    }

protected function getInvoker ( ) : Invoker { if ( $ this -> invoker === null ) { $ this -> invoker = new Invoker ( ) ; if ( $ this -> container !== null ) { $ this -> invoker -> setContainer ( $ this -> container ) -> injectByTypeHint ( true ) -> injectByParameterName ( true ) ; } } return $ this -> invoker ; }

Get configured invoker.

@return \Viserio\Component\Support\Invoker


public static function invalidType(string $name, $provided, array $expected, $configClass): self
    {
        return new self(\sprintf(
            'Invalid configuration value provided for [%s]; Expected [%s], but got [%s], in [%s].',
            $name,
            \count($expected) === 1 ? $expected[0] : \implode('] or [', $expected),
            (\is_object($provided) ? \get_class($provided) : \gettype($provided)),
            $configClass
        ));
    }

When an invalid type is encountered.

@param string $name        name of the value being validated
@param mixed  $provided    the provided value
@param array  $expected    the expected value type
@param string $configClass

@return self


public static function extendCacheItemPool(
        ContainerInterface $container,
        ?CacheItemPoolInterface $cache = null
    ): ?CacheItemPoolInterface {
        if ($cache !== null) {
            if ($cache instanceof PhpCachePoolInterface) {
                return new PhpCacheTraceableCacheDecorator($cache);
            }

            return new TraceableCacheItemDecorator($cache);
        }

        return $cache;
    }

public static function extendCacheItemPool ( ContainerInterface $ container , ? CacheItemPoolInterface $ cache = null ) : ? CacheItemPoolInterface { if ( $ cache !== null ) { if ( $ cache instanceof PhpCachePoolInterface ) { return new PhpCacheTraceableCacheDecorator ( $ cache ) ; } return new TraceableCacheItemDecorator ( $ cache ) ; } return $ cache ; }

Decorate CacheItemPool instances.

@param \Psr\Container\ContainerInterface      $container
@param null|\Psr\Cache\CacheItemPoolInterface $cache

@return null|\Psr\Cache\CacheItemPoolInterface


public static function extendSimpleTraceableCache(
        ContainerInterface $container,
        ?CacheInterface $cache = null
    ): ?CacheInterface {
        if ($cache !== null) {
            if ($cache instanceof PhpCachePoolInterface) {
                return new PhpCacheTraceableCacheDecorator($cache);
            }

            return new SimpleTraceableCacheDecorator($cache);
        }

        return $cache;
    }

public static function extendSimpleTraceableCache ( ContainerInterface $ container , ? CacheInterface $ cache = null ) : ? CacheInterface { if ( $ cache !== null ) { if ( $ cache instanceof PhpCachePoolInterface ) { return new PhpCacheTraceableCacheDecorator ( $ cache ) ; } return new SimpleTraceableCacheDecorator ( $ cache ) ; } return $ cache ; }

Decorate SimpleTraceableCache instances.

@param \Psr\Container\ContainerInterface    $container
@param null|\Psr\SimpleCache\CacheInterface $cache

@return null|\Psr\SimpleCache\CacheInterface

Decorate SimpleTraceableCache instances .


public static function get(string $key, $default = null)
    {
        $value = \getenv($key);

        if ($value === false) {
            return $default instanceof Closure ? $default() : $default;
        }

        if (\preg_match('/base64:|\'base64:|"base64:/', $value) === 1) {
            return \base64_decode(\mb_substr($value, 7), true);
        }

        if (\in_array(
            \mb_strtolower($value),
            [
                'false',
                '(false)',
                'true',
                '(true)',
                'yes',
                '(yes)',
                'no',
                '(no)',
                'on',
                '(on)',
                'off',
                '(off)',
            ],
            true
        )) {
            $value = \str_replace(['(', ')'], '', $value);

            return \filter_var(
                $value,
                \FILTER_VALIDATE_BOOLEAN,
                \FILTER_NULL_ON_FAILURE
            );
        }

        if ($value === 'null' || $value === '(null)') {
            return null;
        }

        if (\is_numeric($value)) {
            return $value + 0;
        }

        if ($value === 'empty' || $value === '(empty)') {
            return '';
        }

        if (\mb_strlen($value) > 1 &&
            \mb_substr($value, 0, \mb_strlen('"')) === '"' &&
            \mb_substr($value, -\mb_strlen('"')) === '"'
        ) {
            return \mb_substr($value, 1, -1);
        }

        return $value;
    }

public static function get ( string $ key , $ default = null ) { $ value = \ getenv ( $ key ) ; if ( $ value === false ) { return $ default instanceof Closure ? $ default ( ) : $ default ; } if ( \ preg_match ( '/base64:|\'base64:|"base64:/' , $ value ) === 1 ) { return \ base64_decode ( \ mb_substr ( $ value , 7 ) , true ) ; } if ( \ in_array ( \ mb_strtolower ( $ value ) , [ 'false' , '(false)' , 'true' , '(true)' , 'yes' , '(yes)' , 'no' , '(no)' , 'on' , '(on)' , 'off' , '(off)' , ] , true ) ) { $ value = \ str_replace ( [ '(' , ')' ] , '' , $ value ) ; return \ filter_var ( $ value , \ FILTER_VALIDATE_BOOLEAN , \ FILTER_NULL_ON_FAILURE ) ; } if ( $ value === 'null' || $ value === '(null)' ) { return null ; } if ( \ is_numeric ( $ value ) ) { return $ value + 0 ; } if ( $ value === 'empty' || $ value === '(empty)' ) { return '' ; } if ( \ mb_strlen ( $ value ) > 1 && \ mb_substr ( $ value , 0 , \ mb_strlen ( '"' ) ) === '"' && \ mb_substr ( $ value , - \ mb_strlen ( '"' ) ) === '"' ) { return \ mb_substr ( $ value , 1 , - 1 ) ; } return $ value ; }

Gets the value of an environment variable. Supports boolean, empty, null and base64 prefix.

@param string $key
@param mixed  $default

@return mixed

Gets the value of an environment variable . Supports boolean empty null and base64 prefix .


protected function parseParameter(string $parameter): string
    {
        \preg_match('/\%' . static::getReferenceKeyword() . '\:(.*)\%/', $parameter, $matches);

        if (\count($matches) !== 0) {
            return $matches[1];
        }

        return $parameter;
    }

protected function parseParameter ( string $ parameter ) : string { \ preg_match ( '/\%' . static :: getReferenceKeyword ( ) . '\:(.*)\%/' , $ parameter , $ matches ) ; if ( \ count ( $ matches ) !== 0 ) { return $ matches [ 1 ] ; } return $ parameter ; }

Get the value without the reference keyword.

@param string $parameter

@return string

Get the value without the reference keyword .


protected function replaceData(string $data, string $parameterKey, string $newValue)
    {
        return \str_replace('%' . static::getReferenceKeyword() . ':' . $parameterKey . '%', $newValue, $data);
    }

protected function replaceData ( string $ data , string $ parameterKey , string $ newValue ) { return \ str_replace ( '%' . static :: getReferenceKeyword ( ) . ':' . $ parameterKey . '%' , $ newValue , $ data ) ; }

Replace parameter key with given value in data string.

@param string $data
@param string $parameterKey
@param string $newValue

@return mixed

Replace parameter key with given value in data string .


public function createTable(): void
    {
        // connect if we are not yet
        $this->getConnection();

        switch ($this->driver) {
            case 'mysql':
                // We use varbinary for the ID column because it prevents unwanted conversions:
                // - character set conversions between server and client
                // - trailing space removal
                // - case-insensitivity
                // - language processing like é == e
                $sql = "CREATE TABLE {$this->table} ({$this->idCol} VARBINARY(128) NOT NULL PRIMARY KEY, {$this->dataCol} BLOB NOT NULL, {$this->lifetimeCol} MEDIUMINT NOT NULL, {$this->timeCol} INTEGER UNSIGNED NOT NULL) COLLATE utf8_bin, ENGINE = InnoDB";

                break;
            case 'sqlite':
                $sql = "CREATE TABLE {$this->table} ({$this->idCol} TEXT NOT NULL PRIMARY KEY, {$this->dataCol} BLOB NOT NULL, {$this->lifetimeCol} INTEGER NOT NULL, {$this->timeCol} INTEGER NOT NULL)";

                break;
            case 'pgsql':
                $sql = "CREATE TABLE {$this->table} ({$this->idCol} VARCHAR(128) NOT NULL PRIMARY KEY, {$this->dataCol} BYTEA NOT NULL, {$this->lifetimeCol} INTEGER NOT NULL, {$this->timeCol} INTEGER NOT NULL)";

                break;
            case 'oci':
                $sql = "CREATE TABLE {$this->table} ({$this->idCol} VARCHAR2(128) NOT NULL PRIMARY KEY, {$this->dataCol} BLOB NOT NULL, {$this->lifetimeCol} INTEGER NOT NULL, {$this->timeCol} INTEGER NOT NULL)";

                break;
            case 'sqlsrv':
                $sql = "CREATE TABLE {$this->table} ({$this->idCol} VARCHAR(128) NOT NULL PRIMARY KEY, {$this->dataCol} VARBINARY(MAX) NOT NULL, {$this->lifetimeCol} INTEGER NOT NULL, {$this->timeCol} INTEGER NOT NULL)";

                break;

            default:
                throw new DomainException(\sprintf(
                    'Creating the session table is currently not implemented for PDO driver [%s].',
                    $this->driver
                ));
        }

        try {
            $this->pdo->exec($sql);
        } catch (PDOException $e) {
            $this->rollback();

            throw $e;
        }
    }

Creates the table to store sessions which can be called once for setup.

Session ID is saved in a column of maximum length 128 because that is enough even
for a 512 bit configured session.hash_function like Whirlpool. Session data is
saved in a BLOB. One could also use a shorter inlined varbinary column
if one was sure the data fits into it.

@throws \PDOException                                                 When the table already exists
@throws \Viserio\Component\Contract\Session\Exception\DomainException When an unsupported PDO driver is used

Creates the table to store sessions which can be called once for setup .


private function getConnection(): PDO
    {
        if ($this->pdo === null) {
            $this->connect($this->dsn);
        }

        return $this->pdo;
    }

private function getConnection ( ) : PDO { if ( $ this -> pdo === null ) { $ this -> connect ( $ this -> dsn ) ; } return $ this -> pdo ; }


private function connect(string $dsn): void
    {
        $this->pdo = new PDO($dsn, $this->username, $this->password, $this->connectionOptions);
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $this->driver = $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
    }

private function connect ( string $ dsn ) : void { $ this -> pdo = new PDO ( $ dsn , $ this -> username , $ this -> password , $ this -> connectionOptions ) ; $ this -> pdo -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION ) ; $ this -> driver = $ this -> pdo -> getAttribute ( PDO :: ATTR_DRIVER_NAME ) ; }

Lazy-connects to the database.

@param string $dsn DSN string

@return void


protected static function getFiles(string $path, $extensions = 'php'): array
    {
        if (! \file_exists($path)) {
            return [];
        }

        $files = [];
        $dir   = new DirectoryIterator($path);

        foreach ($dir as $fileinfo) {
            if (! $fileinfo->isDot()) {
                $extension = \pathinfo($fileinfo->getRealPath(), \PATHINFO_EXTENSION);

                if (\in_array($extension, (array) $extensions, true)) {
                    $filePath = $fileinfo->getRealPath();
                    $key      = \basename($filePath, '.' . $extension);

                    if (\in_array($key, static::$bypassFiles, true)) {
                        continue;
                    }

                    $files[$key] = $filePath;
                }
            }
        }

        \ksort($files, \SORT_NATURAL);

        return $files;
    }

protected static function getFiles ( string $ path , $ extensions = 'php' ) : array { if ( ! \ file_exists ( $ path ) ) { return [ ] ; } $ files = [ ] ; $ dir = new DirectoryIterator ( $ path ) ; foreach ( $ dir as $ fileinfo ) { if ( ! $ fileinfo -> isDot ( ) ) { $ extension = \ pathinfo ( $ fileinfo -> getRealPath ( ) , \ PATHINFO_EXTENSION ) ; if ( \ in_array ( $ extension , ( array ) $ extensions , true ) ) { $ filePath = $ fileinfo -> getRealPath ( ) ; $ key = \ basename ( $ filePath , '.' . $ extension ) ; if ( \ in_array ( $ key , static :: $ bypassFiles , true ) ) { continue ; } $ files [ $ key ] = $ filePath ; } } } \ ksort ( $ files , \ SORT_NATURAL ) ; return $ files ; }

Get all of the files for the application.

@param string       $path
@param array|string $extensions

@return array

Get all of the files for the application .


protected function renderIntoHtml(): string
    {
        $html = \sprintf('<style>%s</style>', $this->dumpAssetsToString('css'));
        $html .= \sprintf('<script type="text/javascript">%s</script>', $this->dumpAssetsToString('js'));

        return $html;
    }

Render css and js into html elements.

@return string


protected function getModifiedTime(string $type): int
    {
        $files  = $this->getAssets($type);
        $latest = 0;

        foreach ($files as $file) {
            $mtime = (int) \filemtime($file);

            if ($mtime > $latest) {
                $latest = $mtime;
            }
        }

        return $latest;
    }

protected function getModifiedTime ( string $ type ) : int { $ files = $ this -> getAssets ( $ type ) ; $ latest = 0 ; foreach ( $ files as $ file ) { $ mtime = ( int ) \ filemtime ( $ file ) ; if ( $ mtime > $ latest ) { $ latest = $ mtime ; } } return $ latest ; }

Get the last modified time of any assets.

@param string $type 'js' or 'css'

@return int

Get the last modified time of any assets .


public function run()
    {
        if ($this->description) {
            $item = $this->cachePool->getItem($this->getMutexName());
            $item->set($this->getMutexName());
            $item->expiresAfter(1440);

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

        $this->callBeforeCallbacks();

        try {
            $response = $this->getInvoker()->call($this->callback, $this->parameters);
        } finally {
            if ($this->description) {
                $this->cachePool->deleteItem($this->getMutexName());
            }
        }

        $this->callAfterCallbacks();

        return $response;
    }

public function run ( ) { if ( $ this -> description ) { $ item = $ this -> cachePool -> getItem ( $ this -> getMutexName ( ) ) ; $ item -> set ( $ this -> getMutexName ( ) ) ; $ item -> expiresAfter ( 1440 ) ; $ this -> cachePool -> save ( $ item ) ; } $ this -> callBeforeCallbacks ( ) ; try { $ response = $ this -> getInvoker ( ) -> call ( $ this -> callback , $ this -> parameters ) ; } finally { if ( $ this -> description ) { $ this -> cachePool -> deleteItem ( $ this -> getMutexName ( ) ) ; } } $ this -> callAfterCallbacks ( ) ; return $ response ; }


public function withoutOverlapping(): CronContract
    {
        if ($this->description === null) {
            throw new LogicException(
                'A scheduled cron job description is required to prevent overlapping. ' .
                "Use the 'setDescription' method before 'withoutOverlapping'."
            );
        }

        return $this->skip(function () {
            return $this->cachePool->hasItem($this->getMutexName());
        });
    }

Do not allow the cron job to overlap each other.

@throws \Viserio\Component\Contract\Cron\Exception\LogicException

@return \Viserio\Component\Contract\Cron\Cron

Do not allow the cron job to overlap each other .


public static function extendLogManager(ContainerInterface $container, $logManager = null)
    {
        $options = self::resolveOptions($container->get('config'));

        if ($logManager !== null && $options['collector']['logs'] === true) {
            $logManager->pushProcessor(new DebugProcessor());
        }

        return $logManager;
    }

public static function extendLogManager ( ContainerInterface $ container , $ logManager = null ) { $ options = self :: resolveOptions ( $ container -> get ( 'config' ) ) ; if ( $ logManager !== null && $ options [ 'collector' ] [ 'logs' ] === true ) { $ logManager -> pushProcessor ( new DebugProcessor ( ) ) ; } return $ logManager ; }

Extend monolog with a processor.

@param \Psr\Container\ContainerInterface                      $container
@param null|\Monolog\Logger|\Viserio\Component\Log\LogManager $logManager

@return null|\Monolog\Logger|\Viserio\Component\Log\Logger


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

            if ($options['collector']['logs'] === true && $container->has(LogManager::class)) {
                $profiler->addCollector(new LoggerDataCollector($container->get(LogManager::class)->getDriver()));
            }
        }

        return $profiler;
    }

public static function extendProfiler ( ContainerInterface $ container , ? ProfilerContract $ profiler = null ) : ? ProfilerContract { if ( $ profiler !== null ) { $ options = self :: resolveOptions ( $ container -> get ( 'config' ) ) ; if ( $ options [ 'collector' ] [ 'logs' ] === true && $ container -> has ( LogManager :: class ) ) { $ profiler -> addCollector ( new LoggerDataCollector ( $ container -> get ( LogManager :: class ) -> getDriver ( ) ) ) ; } } return $ profiler ; }

Extend viserio profiler with a data collector.

@param \Psr\Container\ContainerInterface                  $container
@param null|\Viserio\Component\Contract\Profiler\Profiler $profiler

@return null|\Viserio\Component\Contract\Profiler\Profiler

Extend viserio profiler with a data collector .


public static function importDom(DOMDocument $dom): SimpleXMLElement
    {
        $xml = \simplexml_import_dom($dom);

        if ($xml === false) {
            throw new ParseException(['message' => 'A failure happend on importing a DOMDocument.']);
        }

        return $xml;
    }

A simplexml_import_dom wrapper.

@param \DOMDocument $dom

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

@return \SimpleXMLElement


public static function loadFile(string $file, $schemaOrCallable = null): DOMDocument
    {
        if (! \file_exists($file)) {
            throw new FileNotFoundException(\sprintf('No such file [%s] found.', $file));
        }

        return self::loadString(@\file_get_contents($file), $schemaOrCallable);
    }

public
static
function
loadFile
(
string
$
file
,
$
schemaOrCallable
=
)
:
DOMDocument
{
if
(
!
\
file_exists
(
$
file
)
)
{
throw
new
FileNotFoundException
(
\
sprintf
(
'No such file [%s] found.'
,
$
file
)
)
;
}
return
self
::
loadString
(
@
\
file_get_contents
(
$
file
)
,
$
schemaOrCallable
)
;
}

Loads an XML file.

@param string               $file             An XML file path
@param null|callable|string $schemaOrCallable An XSD schema file path, a callable, or null to disable validation

@throws \Viserio\Component\Contract\Parser\Exception\InvalidArgumentException When loading of XML file returns error
@throws \Viserio\Component\Contract\Parser\Exception\FileNotFoundException

@return \DOMDocument


public static function loadString(string $content, $schemaOrCallable = null): DOMDocument
    {
        if (\trim($content) === '') {
            throw new InvalidArgumentException('Content does not contain valid XML, it is empty.');
        }

        $internalErrors  = \libxml_use_internal_errors(true);
        $disableEntities = \libxml_disable_entity_loader();

        \libxml_clear_errors();

        $dom                  = new DOMDocument();
        $dom->validateOnParse = true;

        if (! $dom->loadXML($content, \LIBXML_NONET | (\defined('LIBXML_COMPACT') ? \LIBXML_COMPACT : 0))) {
            \libxml_disable_entity_loader($disableEntities);

            if ($errors = XliffUtils::validateSchema($dom)) {
                throw new InvalidArgumentException(self::getErrorsAsString($errors));
            }
        }

        $dom->normalizeDocument();

        \libxml_use_internal_errors($internalErrors);
        \libxml_disable_entity_loader($disableEntities);

        foreach ($dom->childNodes as $child) {
            if ($child->nodeType === \XML_DOCUMENT_TYPE_NODE) {
                throw new InvalidArgumentException('Document types are not allowed.');
            }
        }

        if ($schemaOrCallable !== null) {
            self::validateXmlDom($dom, $schemaOrCallable);
        }

        \libxml_clear_errors();
        \libxml_use_internal_errors($internalErrors);

        return $dom;
    }

Loads an XML string.

@param string               $content          An XML string content
@param null|callable|string $schemaOrCallable An XSD schema file path, a callable, or null to disable validation

@throws \Viserio\Component\Contract\Parser\Exception\InvalidArgumentException When loading of XML file returns error

@return \DOMDocument


public static function phpize($value)
    {
        $value          = (string) $value;
        $lowercaseValue = \mb_strtolower($value);

        switch (true) {
            case 'null' === $lowercaseValue:
                return;
            case \ctype_digit($value):
                return self::transformToNumber($value, 0);
            case isset($value[1]) && '-' === $value[0] && \ctype_digit(\mb_substr($value, 1)):
                return self::transformToNumber($value, 1);
            case 'true' === $lowercaseValue:
                return true;
            case 'false' === $lowercaseValue:
                return false;
            case isset($value[1]) && '0b' === $value[0] . $value[1]:
                return \bindec($value);
            case \is_numeric($value):
                return '0x' === $value[0] . $value[1] ? \hexdec($value) : (float) $value;
            case \preg_match('/^0x[0-9a-f]++$/i', $value):
                return \hexdec($value);
            case \preg_match('/^(-|\+)?\d+(\.\d+)?$/', $value):
                return (float) $value;

            default:
                return $value;
        }
    }

public static function phpize ( $ value ) { $ value = ( string ) $ value ; $ lowercaseValue = \ mb_strtolower ( $ value ) ; switch ( true ) { case 'null' === $ lowercaseValue : return ; case \ ctype_digit ( $ value ) : return self :: transformToNumber ( $ value , 0 ) ; case isset ( $ value [ 1 ] ) && '-' === $ value [ 0 ] && \ ctype_digit ( \ mb_substr ( $ value , 1 ) ) : return self :: transformToNumber ( $ value , 1 ) ; case 'true' === $ lowercaseValue : return true ; case 'false' === $ lowercaseValue : return false ; case isset ( $ value [ 1 ] ) && '0b' === $ value [ 0 ] . $ value [ 1 ] : return \ bindec ( $ value ) ; case \ is_numeric ( $ value ) : return '0x' === $ value [ 0 ] . $ value [ 1 ] ? \ hexdec ( $ value ) : ( float ) $ value ; case \ preg_match ( '/^0x[0-9a-f]++$/i' , $ value ) : return \ hexdec ( $ value ) ; case \ preg_match ( '/^(-|\+)?\d+(\.\d+)?$/' , $ value ) : return ( float ) $ value ; default : return $ value ; } }

Converts an xml value to a PHP type.

@param mixed $value

@return mixed


private static function validateXmlDom(DOMDocument $dom, $schemaOrCallable): void
    {
        $internalErrors = \libxml_use_internal_errors(true);
        \libxml_clear_errors();

        $exception = null;

        if (\is_callable($schemaOrCallable)) {
            try {
                /** @var callable $schemaOrCallable */
                $valid = $schemaOrCallable($dom, $internalErrors);
            } catch (Throwable $exception) {
                $valid = false;
            }
        } elseif (\is_string($schemaOrCallable) && \is_file($schemaOrCallable)) {
            $valid = @$dom->schemaValidateSource(\file_get_contents($schemaOrCallable));
        } else {
            \libxml_use_internal_errors($internalErrors);

            throw new InvalidArgumentException('The schemaOrCallable argument has to be a valid path to XSD file or callable.');
        }

        if (! $valid) {
            $errors = self::getErrorsAsString(self::getXmlErrors($internalErrors));

            if ($errors === '') {
                $errors = 'The XML file is not valid.';
            }

            throw new InvalidArgumentException($errors, 0, $exception);
        }
    }

Validates DOMDocument against a file or callback.

@param \DOMDocument    $dom
@param callable|string $schemaOrCallable

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

@return void

Validates DOMDocument against a file or callback .


Convert a string from its PO representation.

@param string $value

@return string

Convert a string from its PO representation .


private static function isHeader(array $entry): bool
    {
        $headerKeys = [
            'Project-Id-Version' => false,
            'PO-Revision-Date'   => false,
            'MIME-Version'       => false,
        ];

        $keys        = \array_keys($headerKeys);
        $headerItems = 0;
        $headers     = \array_map('trim', $entry['msgstr']);

        foreach ($headers as $header) {
            \preg_match_all('/(.*):\s/', $header, $matches, \PREG_SET_ORDER);

            if (isset($matches[0]) && \in_array($matches[0][1], $keys, true)) {
                $headerItems++;

                unset($headerKeys[$matches[0][1]]);

                $keys = \array_keys($headerKeys);
            }
        }

        return $headerItems !== 0;
    }

private static function isHeader ( array $ entry ) : bool { $ headerKeys = [ 'Project-Id-Version' => false , 'PO-Revision-Date' => false , 'MIME-Version' => false , ] ; $ keys = \ array_keys ( $ headerKeys ) ; $ headerItems = 0 ; $ headers = \ array_map ( 'trim' , $ entry [ 'msgstr' ] ) ; foreach ( $ headers as $ header ) { \ preg_match_all ( '/(.*):\s/' , $ header , $ matches , \ PREG_SET_ORDER ) ; if ( isset ( $ matches [ 0 ] ) && \ in_array ( $ matches [ 0 ] [ 1 ] , $ keys , true ) ) { $ headerItems ++ ; unset ( $ headerKeys [ $ matches [ 0 ] [ 1 ] ] ) ; $ keys = \ array_keys ( $ headerKeys ) ; } } return $ headerItems !== 0 ; }

Checks if entry is a header.

@param array $entry

@return bool


private static function addReferences(string $data, array $entry): array
    {
        foreach (\preg_split('/#:\s+/', \trim($data)) as $value) {
            if (\count(\preg_split('/\s+/', $value)) >= 2) {
                if (\preg_match_all('/([.\/a-zA-Z]+)(:(\d*))/', ' ' . $value, $matches, \PREG_SET_ORDER, 1)) {
                    $key    = '';
                    $values = [];

                    foreach ($matches as $match) {
                        $filename = $match[1];
                        $line     = $match[3] ?? null;

                        $key .= \sprintf('{%s}:{%s} ', $filename, $line);
                        $values[] = [$filename, $line];
                    }

                    $entry['references'][\trim($key)] = $values;
                }
            } else {
                if (\preg_match('/^(.+)(:(\d*))?$/U', $value, $matches)) {
                    $filename = $matches[1];
                    $line     = $matches[3] ?? null;
                    $key      = \sprintf('{%s}:{%s}', $filename, $line);

                    $entry['references'][$key] = [$filename, $line];
                }
            }
        }

        return $entry;
    }

private
static
function
addReferences
(
string
$
data
,
array
$
entry
)
:
array
{
foreach
(
\
preg_split
(
'/#:\s+/'
,
\
trim
(
$
data
)
)
as
$
value
)
{
if
(
\
count
(
\
preg_split
(
'/\s+/'
,
$
value
)
)
>=
2
)
{
if
(
\
preg_match_all
(
'/([.\/a-zA-Z]+)(:(\d*))/'
,
' '
.
$
value
,
$
matches
,
\
PREG_SET_ORDER
,
1
)
)
{
$
key
=
''
;
$
values
=
[
]
;
foreach
(
$
matches
as
$
match
)
{
$
filename
=
$
match
[
1
]
;
$
line
=
$
match
[
3
]
??
;
$
key
.=
\
sprintf
(
'{%s}:{%s} '
,
$
filename
,
$
line
)
;
$
values
[
]
=
[
$
filename
,
$
line
]
;
}
$
entry
[
'references'
]
[
\
trim
(
$
key
)
]
=
$
values
;
}
}
else
{
if
(
\
preg_match
(
'/^(.+)(:(\d*))?$/U'
,
$
value
,
$
matches
)
)
{
$
filename
=
$
matches
[
1
]
;
$
line
=
$
matches
[
3
]
??
;
$
key
=
\
sprintf
(
'{%s}:{%s}'
,
$
filename
,
$
line
)
;
$
entry
[
'references'
]
[
$
key
]
=
[
$
filename
,
$
line
]
;
}
}
}
return
$
entry
;
}

Export reference infos.

@param string $data
@param array  $entry

@return array


private static function processObsoleteEntry(
        ?string $lastPreviousKey,
        ?string $tmpKey,
        string $str,
        array $entry
    ): array {
        $entry['obsolete'] = true;

        switch ($tmpKey) {
            case 'msgid':
                $entry['msgid'][] = self::convertString($str);
                $lastPreviousKey  = $tmpKey;

                break;
            case 'msgstr':
                $entry['msgstr'][] = self::convertString($str);

                $lastPreviousKey = $tmpKey;

                break;

            default:
                break;
        }

        return [$entry, $lastPreviousKey];
    }

private static function processObsoleteEntry ( ? string $ lastPreviousKey , ? string $ tmpKey , string $ str , array $ entry ) : array { $ entry [ 'obsolete' ] = true ; switch ( $ tmpKey ) { case 'msgid' : $ entry [ 'msgid' ] [ ] = self :: convertString ( $ str ) ; $ lastPreviousKey = $ tmpKey ; break ; case 'msgstr' : $ entry [ 'msgstr' ] [ ] = self :: convertString ( $ str ) ; $ lastPreviousKey = $ tmpKey ; break ; default : break ; } return [ $ entry , $ lastPreviousKey ] ; }

Export obsolete entries.

@param null|string $lastPreviousKey
@param null|string $tmpKey
@param string      $str
@param array       $entry

@return array


private static function processPreviousEntry(
        ?string $lastPreviousKey,
        ?string $tmpKey,
        string $str,
        array $entry,
        string $key
    ): array {
        switch ($tmpKey) {
            case 'msgid':
            case 'msgid_plural':
            case 'msgstr':
                $entry[$key][$tmpKey][] = self::convertString($str);
                $lastPreviousKey        = $tmpKey;

                break;

            default:
                $entry[$key][$tmpKey] = self::convertString($str);

                break;
        }

        return [$entry, $lastPreviousKey];
    }

private static function processPreviousEntry ( ? string $ lastPreviousKey , ? string $ tmpKey , string $ str , array $ entry , string $ key ) : array { switch ( $ tmpKey ) { case 'msgid' : case 'msgid_plural' : case 'msgstr' : $ entry [ $ key ] [ $ tmpKey ] [ ] = self :: convertString ( $ str ) ; $ lastPreviousKey = $ tmpKey ; break ; default : $ entry [ $ key ] [ $ tmpKey ] = self :: convertString ( $ str ) ; break ; } return [ $ entry , $ lastPreviousKey ] ; }

Export previous entries.

@param null|string $lastPreviousKey
@param null|string $tmpKey
@param string      $str
@param array       $entry
@param string      $key

@return array