private function getFileReflector(\ReflectionClass $reflectionClass)
    {
        if (!($fileName = $reflectionClass->getFileName()) || 'hh' === pathinfo($fileName, PATHINFO_EXTENSION)) {
            return;
        }

        if (isset(self::$fileReflectors[$fileName])) {
            return self::$fileReflectors[$fileName];
        }

        self::$fileReflectors[$fileName] = new FileReflector($fileName);
        self::$fileReflectors[$fileName]->process();

        return self::$fileReflectors[$fileName];
    }

private function getFileReflector ( \ ReflectionClass $ reflectionClass ) { if ( ! ( $ fileName = $ reflectionClass -> getFileName ( ) ) || 'hh' === pathinfo ( $ fileName , PATHINFO_EXTENSION ) ) { return ; } if ( isset ( self :: $ fileReflectors [ $ fileName ] ) ) { return self :: $ fileReflectors [ $ fileName ] ; } self :: $ fileReflectors [ $ fileName ] = new FileReflector ( $ fileName ) ; self :: $ fileReflectors [ $ fileName ] -> process ( ) ; return self :: $ fileReflectors [ $ fileName ] ; }

Gets the FileReflector associated with the class.

@param \ReflectionClass $reflectionClass

@return FileReflector|null

Gets the FileReflector associated with the class .


private function getDocBlock($class, $property)
    {
        $propertyHash = sprintf('%s::%s', $class, $property);

        if (isset(self::$docBlocks[$propertyHash])) {
            return self::$docBlocks[$propertyHash];
        }

        $ucFirstProperty = ucfirst($property);

        switch (true) {
            case $docBlock = $this->getDocBlockFromProperty($class, $property):
                $data = array($docBlock, self::PROPERTY, null);
                break;

            case list($docBlock) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR):
                $data = array($docBlock, self::ACCESSOR, null);
                break;

            case list($docBlock, $prefix) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR):
                $data = array($docBlock, self::MUTATOR, $prefix);
                break;

            default:
                $data = array(null, null);
        }

        return self::$docBlocks[$propertyHash] = $data;
    }

private function getDocBlock ( $ class , $ property ) { $ propertyHash = sprintf ( '%s::%s' , $ class , $ property ) ; if ( isset ( self :: $ docBlocks [ $ propertyHash ] ) ) { return self :: $ docBlocks [ $ propertyHash ] ; } $ ucFirstProperty = ucfirst ( $ property ) ; switch ( true ) { case $ docBlock = $ this -> getDocBlockFromProperty ( $ class , $ property ) : $ data = array ( $ docBlock , self :: PROPERTY , null ) ; break ; case list ( $ docBlock ) = $ this -> getDocBlockFromMethod ( $ class , $ ucFirstProperty , self :: ACCESSOR ) : $ data = array ( $ docBlock , self :: ACCESSOR , null ) ; break ; case list ( $ docBlock , $ prefix ) = $ this -> getDocBlockFromMethod ( $ class , $ ucFirstProperty , self :: MUTATOR ) : $ data = array ( $ docBlock , self :: MUTATOR , $ prefix ) ; break ; default : $ data = array ( null , null ) ; } return self :: $ docBlocks [ $ propertyHash ] = $ data ; }

Gets the DocBlock for this property.

@param string $class
@param string $property

@return array


private function getDocBlockFromProperty($class, $property)
    {
        // Use a ReflectionProperty instead of $class to get the parent class if applicable
        try {
            $reflectionProperty = new \ReflectionProperty($class, $property);
        } catch (\ReflectionException $reflectionException) {
            return;
        }

        $reflectionCLass = $reflectionProperty->getDeclaringClass();

        $fileReflector = $this->getFileReflector($reflectionCLass);
        if (!$fileReflector) {
            return;
        }

        foreach ($fileReflector->getClasses() as $classReflector) {
            $className = $this->getClassName($classReflector);

            if ($className === $reflectionCLass->name) {
                foreach ($classReflector->getProperties() as $propertyReflector) {
                    // strip the $ prefix
                    $propertyName = substr($propertyReflector->getName(), 1);

                    if ($propertyName === $property) {
                        return $propertyReflector->getDocBlock();
                    }
                }
            }
        }
    }

Gets the DocBlock from a property.

@param string $class
@param string $property

@return DocBlock|null


private function getDocBlockFromMethod($class, $ucFirstProperty, $type)
    {
        $prefixes = $type === self::ACCESSOR ? ReflectionExtractor::$accessorPrefixes : ReflectionExtractor::$mutatorPrefixes;

        foreach ($prefixes as $prefix) {
            $methodName = $prefix.$ucFirstProperty;

            try {
                $reflectionMethod = new \ReflectionMethod($class, $methodName);

                if (
                    (self::ACCESSOR === $type && 0 === $reflectionMethod->getNumberOfRequiredParameters()) ||
                    (self::MUTATOR === $type && $reflectionMethod->getNumberOfParameters() >= 1)
                ) {
                    break;
                }
            } catch (\ReflectionException $reflectionException) {
                // Try the next prefix if the method doesn't exist
            }
        }

        if (!isset($reflectionMethod)) {
            return;
        }

        $reflectionClass = $reflectionMethod->getDeclaringClass();
        $fileReflector = $this->getFileReflector($reflectionClass);

        if (!$fileReflector) {
            return;
        }

        foreach ($fileReflector->getClasses() as $classReflector) {
            $className = $this->getClassName($classReflector);

            if ($className === $reflectionClass->name) {
                if ($methodReflector = $classReflector->getMethod($methodName)) {
                    return array($methodReflector->getDocBlock(), $prefix);
                }
            }
        }
    }

Gets DocBlock from accessor or mutator method.

@param string $class
@param string $ucFirstProperty
@param int    $type

@return DocBlock|null

Gets DocBlock from accessor or mutator method .


private function getPhpTypeAndClass($docType)
    {
        if (in_array($docType, Type::$builtinTypes)) {
            return array($docType, null);
        }

        return array('object', substr($docType, 1));
    }

private function getPhpTypeAndClass ( $ docType ) { if ( in_array ( $ docType , Type :: $ builtinTypes ) ) { return array ( $ docType , null ) ; } return array ( 'object' , substr ( $ docType , 1 ) ) ; }

Gets an array containing the PHP type and the class.

@param string $docType

@return array

Gets an array containing the PHP type and the class .


public function login($username, $password)
    {
        if (empty($username) || empty($password)) {
            throw new LoginException("Incorrect username or password.");
        }

        $this->initClient(true);

        $login = $this->client->post(self::URL_LOGIN, [
            'form_params' => [
                '_token'   => $this->getToken(),
                'username' => $username,
                'password' => $password
            ],
            'on_stats' => function (TransferStats $stats) use (&$url) {
                $url = $stats->getEffectiveUri();
            }
        ]);

        if ($url == self::URL_HOME . self::URL_LOGIN) {
            throw new LoginException("Incorrect username or password.");
        }

        $this->username = $username;
    }

public
function
login
(
$
username
,
$
password
)
{
if
(
empty
(
$
username
)
||
empty
(
$
password
)
)
{
throw
new
LoginException
(
"Incorrect username or password."
)
;
}
$
this
->
initClient
(
true
)
;
$
login
=
$
this
->
client
->
post
(
self
::
URL_LOGIN
,
[
'form_params'
=>
[
'_token'
=>
$
this
->
getToken
(
)
,
'username'
=>
$
username
,
'password'
=>
$
password
]
,
'on_stats'
=>
function
(
TransferStats
$
stats
)
use
(
&
$
url
)
{
$
url
=
$
stats
->
getEffectiveUri
(
)
;
}
]
)
;
if
(
$
url
==
self
::
URL_HOME
.
self
::
URL_LOGIN
)
{
throw
new
LoginException
(
"Incorrect username or password."
)
;
}
$
this
->
username
=
$
username
;
}

Login to Wallhaven.

@param string $username Username.
@param string $password Password.

@throws LoginException


private function initClient($withCookies = false)
    {

        if ($withCookies) {
            $jar = new CookieJar();
            $this->client = new Client(
                [
                    'base_uri' => self::URL_HOME,
                    'cookies'  => $jar
                ]);
        } else {
            $this->client = new Client(['base_uri' => self::URL_HOME]);
        }
    }

private function initClient ( $ withCookies = false ) { if ( $ withCookies ) { $ jar = new CookieJar ( ) ; $ this -> client = new Client ( [ 'base_uri' => self :: URL_HOME , 'cookies' => $ jar ] ) ; } else { $ this -> client = new Client ( [ 'base_uri' => self :: URL_HOME ] ) ; } }

Initialize HTTP client.

@param bool $withCookies Whether cookies should be enabled.


private function getToken()
    {
        $body = $this->client->get('/')->getBody()->getContents();

        $dom = new Dom();
        $dom->load($body);

        $token = $dom->find('input[name="_token"]')[0]->value;

        if (empty($token)) {
            throw new LoginException("Cannot find login token on Wallhaven's homepage.");
        }

        return $token;
    }

Get token for login.

@return string Token.
@throws WallhavenException Thrown if no token is found.


public function search(
        $query,
        $categories = Category::ALL,
        $purity = Purity::SFW,
        $sorting = Sorting::RELEVANCE,
        $order = Order::DESC,
        $resolutions = [],
        $ratios = [],
        $page = 1
    ) {
        $result = $this->client->get(self::URL_SEARCH, [
            'query'   => [
                'q'           => $query,
                'categories'  => self::getBinary($categories),
                'purity'      => self::getBinary($purity),
                'sorting'     => $sorting,
                'order'       => $order,
                'resolutions' => implode(',', $resolutions),
                'ratios'      => implode(',', $ratios),
                'page'        => $page
            ],
            'headers' => [
                'X-Requested-With' => 'XMLHttpRequest'
            ]
        ]);

        $body = $result->getBody()->getContents();
        $dom = new Dom();
        $dom->load($body);

        $figures = $dom->find('figure.thumb');

        $wallpapers = new WallpaperList();

        foreach ($figures as $figure) {
            $id = preg_split('#' . self::URL_HOME . self::URL_WALLPAPER . '/#',
                $figure->find('a.preview')->getAttribute('href'))[1];

            $classText = $figure->getAttribute('class');
            preg_match("/thumb thumb-(sfw|sketchy|nsfw) thumb-(general|anime|people)/", $classText, $classMatches);

            $purity = constant('Wallhaven\Purity::' . strtoupper($classMatches[1]));
            $category = constant('Wallhaven\Category::' . strtoupper($classMatches[2]));
            $resolution = str_replace(' ', '', trim($figure->find('span.wall-res')->text));
            $favorites = (int)$figure->find('.wall-favs')->text;

            $w = new Wallpaper($id, $this->client);

            $w->setProperties([
                'purity'     => $purity,
                'category'   => $category,
                'resolution' => $resolution,
                'favorites'  => $favorites
            ]);

            $wallpapers[] = $w;
        }

        return $wallpapers;
    }

Search for wallpapers.

@param string   $query       What to search for. Searching for specific tags can be done with #tagname, e.g.
<samp>#cars</samp>
@param int      $categories  Categories to include. This is a bit field, e.g.: <samp>Category::GENERAL |
Category::PEOPLE</samp>
@param int      $purity      Purity of wallpapers. This is a bit field, e.g.: <samp>Purity::SFW |
Purity::NSFW</samp>
@param string   $sorting     Sorting, e.g. <samp>Sorting::RELEVANCE</samp>
@param string   $order       Order of results. Can be <samp>Order::ASC</samp> or <samp>Order::DESC</samp>
@param string[] $resolutions Array of resolutions in the format of WxH, e.g.: <samp>['1920x1080',
'1280x720']</samp>
@param string[] $ratios      Array of ratios in the format of WxH, e.g.: <samp>['16x9', '4x3']</samp>
@param int      $page        The id of the page to fetch. This is not a total number of pages to
fetch.

@return WallpaperList Wallpapers.


private function extract(array $extractors, $method, array $arguments)
    {
        foreach ($extractors as $extractor) {
            $value = call_user_func_array(array($extractor, $method), $arguments);
            if (null !== $value) {
                return $value;
            }
        }
    }

private function extract ( array $ extractors , $ method , array $ arguments ) { foreach ( $ extractors as $ extractor ) { $ value = call_user_func_array ( array ( $ extractor , $ method ) , $ arguments ) ; if ( null !== $ value ) { return $ value ; } } }

Iterates over registered extractors and return the first value found.

@param array  $extractors
@param string $method
@param array  $arguments

@return mixed

Iterates over registered extractors and return the first value found .


public function getTags()
    {
        if ($this->cacheEnabled && $this->tags !== null) {
            return $this->tags;
        }

        $dom = $this->getDom();

        $this->tags = [];

        foreach ($dom->find('a.tagname') as $e) {
            $this->tags[] = $e->text;
        }

        return $this->tags;
    }

public function getTags ( ) { if ( $ this -> cacheEnabled && $ this -> tags !== null ) { return $ this -> tags ; } $ dom = $ this -> getDom ( ) ; $ this -> tags = [ ] ; foreach ( $ dom -> find ( 'a.tagname' ) as $ e ) { $ this -> tags [ ] = $ e -> text ; } return $ this -> tags ; }

Get wallpaper tags.

@return string[] Tags.


public function download($directory)
    {
        if (!file_exists($directory)) {
            if (!@mkdir($directory, null, true)) {
                throw new DownloadException("The download directory cannot be created.");
            }
        }

        $url = $this->getImageUrl();

        $this->client->get($url, [
            'save_to' => $directory . '/' . basename($url),
        ]);
    }

Download the wallpaper.

@param string $directory Where to download the wallpaper.

@throws DownloadException Thrown if the download directory cannot be created.


public function getWallpapers()
    {
        $wallpapers = new WallpaperList();

        for ($i = 1; $i <= $this->pages; ++$i) {
            $wallpapers->addAll($this->wallhaven->search(
                $this->keywords,
                $this->categories,
                $this->purity,
                $this->sorting,
                $this->order,
                $this->resolutions,
                $this->ratios,
                $i
            ));
        }

        return $wallpapers;
    }

public function getWallpapers ( ) { $ wallpapers = new WallpaperList ( ) ; for ( $ i = 1 ; $ i <= $ this -> pages ; ++ $ i ) { $ wallpapers -> addAll ( $ this -> wallhaven -> search ( $ this -> keywords , $ this -> categories , $ this -> purity , $ this -> sorting , $ this -> order , $ this -> resolutions , $ this -> ratios , $ i ) ) ; } return $ wallpapers ; }

Execute the search with the specified filters.

@return WallpaperList Wallpapers matching the specified filters.

Execute the search with the specified filters .


public function downloadAll($directory)
    {
        if (!file_exists($directory)) {
            if (!@mkdir($directory, null, true)) {
                throw new DownloadException("The download directory cannot be created.");
            }
        }

        $client = new Client();

        $requests = [];
        foreach ($this->wallpapers as $w) {
            $url = $w->getImageUrl(true);

            $requests[] = $client->createRequest('GET', $url, [
                'save_to' => $directory . '/' . basename($url)
            ]);
        }

        $results = Pool::batch($client, $requests);

        // Retry with PNG
        $retryRequests = [];
        foreach ($results->getFailures() as $e) {
            // Delete failed files
            unlink($directory . '/' . basename($e->getRequest()->getUrl()));

            $urlPng = str_replace('.jpg', '.png', $e->getRequest()->getUrl());
            $statusCode = $e->getResponse()->getStatusCode();

            if ($statusCode == 404) {
                $retryRequests[] = $client->createRequest('GET', $urlPng, [
                    'save_to' => $directory . '/' . basename($urlPng)
                ]);
            }
        }

        Pool::batch($client, $retryRequests);
    }

Download all wallpapers in list.

@param string $directory Where to download wallpapers.

@throws DownloadException Thrown if the download directory cannot be created.


private function extractFromMutator($class, $property)
    {
        list($reflectionMethod, $prefix) = $this->getMutatorMethod($class, $property);
        if (null === $reflectionMethod) {
            return;
        }

        $reflectionParameters = $reflectionMethod->getParameters();
        $reflectionParameter = $reflectionParameters[0];

        $arrayMutator = in_array($prefix, self::$arrayMutatorPrefixes);

        if (method_exists($reflectionParameter, 'getType') && $reflectionType = $reflectionParameter->getType()) {
            $fromReflectionType = $this->extractFromReflectionType($reflectionType);

            if (!$arrayMutator) {
                return array($fromReflectionType);
            }

            $phpType = Type::BUILTIN_TYPE_ARRAY;
            $collectionKeyType = new Type(Type::BUILTIN_TYPE_INT);
            $collectionValueType = $fromReflectionType;
        }

        if ($reflectionParameter->isArray()) {
            $phpType = Type::BUILTIN_TYPE_ARRAY;
            $collection = true;
        }

        if ($arrayMutator) {
            $collection = true;
            $nullable = false;
            $collectionNullable = $reflectionParameter->allowsNull();
        } else {
            $nullable = $reflectionParameter->allowsNull();
            $collectionNullable = false;
        }

        if (!isset($collection)) {
            $collection = false;
        }

        if (method_exists($reflectionParameter, 'isCallable') && $reflectionParameter->isCallable()) {
            $phpType = Type::BUILTIN_TYPE_CALLABLE;
        }

        if ($typeHint = $reflectionParameter->getClass()) {
            if ($collection) {
                $phpType = Type::BUILTIN_TYPE_ARRAY;
                $collectionKeyType = new Type(Type::BUILTIN_TYPE_INT);
                $collectionValueType = new Type(Type::BUILTIN_TYPE_OBJECT, $collectionNullable, $typeHint->name);
            } else {
                $phpType = Type::BUILTIN_TYPE_OBJECT;
                $typeClass = $typeHint->name;
            }
        }

        // Nothing useful extracted
        if (!isset($phpType)) {
            return;
        }

        return array(
            new Type(
                $phpType,
                $nullable,
                isset($typeClass) ? $typeClass : null,
                $collection,
                isset($collectionKeyType) ? $collectionKeyType : null,
                isset($collectionValueType) ? $collectionValueType : null
            ),
        );
    }

private
function
extractFromMutator
(
$
class
,
$
property
)
{
list
(
$
reflectionMethod
,
$
prefix
)
=
$
this
->
getMutatorMethod
(
$
class
,
$
property
)
;
if
(
===
$
reflectionMethod
)
{
return
;
}
$
reflectionParameters
=
$
reflectionMethod
->
getParameters
(
)
;
$
reflectionParameter
=
$
reflectionParameters
[
0
]
;
$
arrayMutator
=
in_array
(
$
prefix
,
self
::
$
arrayMutatorPrefixes
)
;
if
(
method_exists
(
$
reflectionParameter
,
'getType'
)
&&
$
reflectionType
=
$
reflectionParameter
->
getType
(
)
)
{
$
fromReflectionType
=
$
this
->
extractFromReflectionType
(
$
reflectionType
)
;
if
(
!
$
arrayMutator
)
{
return
array
(
$
fromReflectionType
)
;
}
$
phpType
=
Type
::
BUILTIN_TYPE_ARRAY
;
$
collectionKeyType
=
new
Type
(
Type
::
BUILTIN_TYPE_INT
)
;
$
collectionValueType
=
$
fromReflectionType
;
}
if
(
$
reflectionParameter
->
isArray
(
)
)
{
$
phpType
=
Type
::
BUILTIN_TYPE_ARRAY
;
$
collection
=
true
;
}
if
(
$
arrayMutator
)
{
$
collection
=
true
;
$
nullable
=
false
;
$
collectionNullable
=
$
reflectionParameter
->
allowsNull
(
)
;
}
else
{
$
nullable
=
$
reflectionParameter
->
allowsNull
(
)
;
$
collectionNullable
=
false
;
}
if
(
!
isset
(
$
collection
)
)
{
$
collection
=
false
;
}
if
(
method_exists
(
$
reflectionParameter
,
'isCallable'
)
&&
$
reflectionParameter
->
isCallable
(
)
)
{
$
phpType
=
Type
::
BUILTIN_TYPE_CALLABLE
;
}
if
(
$
typeHint
=
$
reflectionParameter
->
getClass
(
)
)
{
if
(
$
collection
)
{
$
phpType
=
Type
::
BUILTIN_TYPE_ARRAY
;
$
collectionKeyType
=
new
Type
(
Type
::
BUILTIN_TYPE_INT
)
;
$
collectionValueType
=
new
Type
(
Type
::
BUILTIN_TYPE_OBJECT
,
$
collectionNullable
,
$
typeHint
->
name
)
;
}
else
{
$
phpType
=
Type
::
BUILTIN_TYPE_OBJECT
;
$
typeClass
=
$
typeHint
->
name
;
}
}
// Nothing useful extracted
if
(
!
isset
(
$
phpType
)
)
{
return
;
}
return
array
(
new
Type
(
$
phpType
,
$
nullable
,
isset
(
$
typeClass
)
$
typeClass
:
,
$
collection
,
isset
(
$
collectionKeyType
)
$
collectionKeyType
:
,
isset
(
$
collectionValueType
)
$
collectionValueType
:
)
,
)
;
}

Tries to extract type information from mutators.

@param string $class
@param string $property

@return Type[]|null

Tries to extract type information from mutators .


private function extractFromAccessor($class, $property)
    {
        list($reflectionMethod, $prefix) = $this->getAccessorMethod($class, $property);
        if (null === $reflectionMethod) {
            return;
        }

        if (method_exists($reflectionMethod, 'getReturnType') && $reflectionType = $reflectionMethod->getReturnType()) {
            return array($this->extractFromReflectionType($reflectionType));
        }

        if (in_array($prefix, array('is', 'can'))) {
            return array(new Type(Type::BUILTIN_TYPE_BOOL));
        }
    }

private function extractFromAccessor ( $ class , $ property ) { list ( $ reflectionMethod , $ prefix ) = $ this -> getAccessorMethod ( $ class , $ property ) ; if ( null === $ reflectionMethod ) { return ; } if ( method_exists ( $ reflectionMethod , 'getReturnType' ) && $ reflectionType = $ reflectionMethod -> getReturnType ( ) ) { return array ( $ this -> extractFromReflectionType ( $ reflectionType ) ) ; } if ( in_array ( $ prefix , array ( 'is' , 'can' ) ) ) { return array ( new Type ( Type :: BUILTIN_TYPE_BOOL ) ) ; } }

Tries to extract type information from accessors.

@param string $class
@param string $property

@return Type[]|null

Tries to extract type information from accessors .


private function extractFromReflectionType(\ReflectionType $reflectionType)
    {
        $phpTypeOrClass = (string) $reflectionType;
        $nullable = $reflectionType->allowsNull();

        if ($reflectionType->isBuiltin()) {
            if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) {
                $type = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true);
            } else {
                $type = new Type($phpTypeOrClass, $nullable);
            }
        } else {
            $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $phpTypeOrClass);
        }

        return $type;
    }

private function extractFromReflectionType ( \ ReflectionType $ reflectionType ) { $ phpTypeOrClass = ( string ) $ reflectionType ; $ nullable = $ reflectionType -> allowsNull ( ) ; if ( $ reflectionType -> isBuiltin ( ) ) { if ( Type :: BUILTIN_TYPE_ARRAY === $ phpTypeOrClass ) { $ type = new Type ( Type :: BUILTIN_TYPE_ARRAY , $ nullable , null , true ) ; } else { $ type = new Type ( $ phpTypeOrClass , $ nullable ) ; } } else { $ type = new Type ( Type :: BUILTIN_TYPE_OBJECT , $ nullable , $ phpTypeOrClass ) ; } return $ type ; }

Extracts data from the PHP 7 reflection type.

@param \ReflectionType $reflectionType

@return Type

Extracts data from the PHP 7 reflection type .


private function isPublicProperty($class, $property)
    {
        try {
            $reflectionProperty = new \ReflectionProperty($class, $property);

            return $reflectionProperty->isPublic();
        } catch (\ReflectionException $reflectionExcetion) {
            // Return false if the property doesn't exist
        }

        return false;
    }

Does the class have the given public property?

@param string $class
@param string $property

@return bool


private function getAccessorMethod($class, $property)
    {
        $ucProperty = ucfirst($property);

        foreach (self::$accessorPrefixes as $prefix) {
            try {
                $reflectionMethod = new \ReflectionMethod($class, $prefix.$ucProperty);

                if (0 === $reflectionMethod->getNumberOfRequiredParameters()) {
                    return array($reflectionMethod, $prefix);
                }
            } catch (\ReflectionException $reflectionException) {
                // Return null if the property doesn't exist
            }
        }

        return;
    }

Gets the accessor method.

Returns an array with a the instance of \ReflectionMethod as first key
and the prefix of the method as second or null if not found.

@param string $class
@param string $property

@return array|null


private function getMutatorMethod($class, $property)
    {
        $ucProperty = ucfirst($property);

        foreach (self::$mutatorPrefixes as $prefix) {
            try {
                $reflectionMethod = new \ReflectionMethod($class, $prefix.$ucProperty);

                // Parameter can be optional to allow things like: method(array $foo = null)
                if ($reflectionMethod->getNumberOfParameters() >= 1) {
                    return array($reflectionMethod, $prefix);
                }
            } catch (\ReflectionException $reflectionException) {
                // Try the next prefix if the method doesn't exist
            }
        }
    }

Gets the mutator method.

Returns an array with a the instance of \ReflectionMethod as first key
and the prefix of the method as second or null if not found.

@param string $class
@param string $property

@return array


private function getPropertyName($methodName)
    {
        $pattern = implode('|', array_merge(self::$accessorPrefixes, self::$mutatorPrefixes));

        if (preg_match('/^('.$pattern.')(.+)$/i', $methodName, $matches)) {
            return $matches[2];
        }
    }

private function getPropertyName ( $ methodName ) { $ pattern = implode ( '|' , array_merge ( self :: $ accessorPrefixes , self :: $ mutatorPrefixes ) ) ; if ( preg_match ( '/^(' . $ pattern . ')(.+)$/i' , $ methodName , $ matches ) ) { return $ matches [ 2 ] ; } }

Extracts a property name from a method name.

@param string $methodName

@return string

Extracts a property name from a method name .


public function load(ServiceContainer $container)
    {
        // Create & store Laravel wrapper

        $container->setShared(
            'laravel',
            function (ServiceContainer $c) {
                $config = $c->getParam('laravel_extension');

                $laravel = new Laravel(
                    isset($config['testing_environment']) ? $config['testing_environment'] : null,
                    isset($config['app_classname']) ? $config['app_classname'] : null
                );

                return $laravel;
            }
        );

        // Bootstrap maintainer to bind Laravel wrapper to specs

        $container->setShared(
            'runner.maintainers.laravel',
            function (ServiceContainer $c) {
                return new LaravelMaintainer(
                    $c->get('laravel')
                );
            }
        );

        // Bootstrap maintainer to bind app Presenter to specs, so it
        // can be passed to custom matchers

        $container->setShared(
            'runner.maintainers.presenter',
            function (ServiceContainer $c) {
                return new PresenterMaintainer(
                    $c->get('formatter.presenter')
                );
            }
        );

        // Bootstrap listener to setup Laravel application for specs

        $container->setShared(
            'event_dispatcher.listeners.laravel',
            function (ServiceContainer $c) {
                return new LaravelListener($c->get('laravel'));
            }
        );
    }

Setup the Laravel extension.

@param  \PhpSpec\ServiceContainer $container
@return void


protected function createApplication()
    {
        putenv('APP_ENV=' . $this->getEnv());

        if (!is_a($this->appClassName, App::class, true)) {
            throw new Exception("Instance of Pixelindustries\\PhpspecTestbench\\App expected, got {$this->appClassName}.");
        }

        return (new $this->appClassName)->createApplication();
    }

Creates a Laravel application.

@return \Illuminate\Foundation\Application


public function setValue($name, $value, $section = 0, $key = null)
    {
        if (!preg_match('/^[^\\[\\]]*$/', $name)) {
            throw new IniInvalidArgumentException("Invalid value name $name");
        }

        if (is_array($value)) {
            if ($key !== null) {
                throw new IniInvalidArgumentException('You cannot indicate a key for an array value');
            }
            $this->_setArrayValue($name, $value, $section);
        } else {
            $this->_setValue($name, $value, $section, $key);
        }
    }

modify an option in the ini file. If the option doesn't exist,
it is created.

@param string $name    the name of the option to modify
@param string $value   the new value
@param string $section the section where to set the item. 0 is the global section
@param int    $key     for option which is an item of array, the key in the array. '' to just add a value in the array

modify an option in the ini file . If the option doesn t exist it is created .


public function setValues($values, $section = 0)
    {
        foreach ($values as $name => $val) {
            $this->setValue($name, $val, $section);
        }
    }

public function setValues ( $ values , $ section = 0 ) { foreach ( $ values as $ name => $ val ) { $ this -> setValue ( $ name , $ val , $ section ) ; } }

modify several options in the ini file.

@param array  $value   associated array with key=>value
@param string $section the section where to set the item. 0 is the global section

modify several options in the ini file .


public function removeSection($section = 0, $removePreviousComment = true)
    {
        if ($section === 0 || !isset($this->content[$section])) {
            return;
        }

        if ($removePreviousComment) {
            // retrieve the previous section
            $previousSection = -1;
            foreach ($this->content as $s => $c) {
                if ($s === $section) {
                    break;
                } else {
                    $previousSection = $s;
                }
            }

            if ($previousSection != -1) {
                //retrieve the last comment
                $s = $this->content[$previousSection];
                end($s);
                $tok = current($s);
                while ($tok !== false) {
                    if ($tok[0] != self::TK_WS && $tok[0] != self::TK_COMMENT) {
                        break;
                    }
                    if ($tok[0] == self::TK_COMMENT && strpos($tok[1], '<?') === false) {
                        $this->content[$previousSection][key($s)] = array(self::TK_WS, '--');
                    }
                    $tok = prev($s);
                }
            }
        }

        unset($this->content[$section]);
        $this->modified = true;
    }

public
function
removeSection
(
$
section
=
0
,
$
removePreviousComment
=
true
)
{
if
(
$
section
===
0
||
!
isset
(
$
this
->
content
[
$
section
]
)
)
{
return
;
}
if
(
$
removePreviousComment
)
{
// retrieve the previous section
$
previousSection
=
1
;
foreach
(
$
this
->
content
as
$
s
=>
$
c
)
{
if
(
$
s
===
$
section
)
{
break
;
}
else
{
$
previousSection
=
$
s
;
}
}
if
(
$
previousSection
!=
1
)
{
//retrieve the last comment
$
s
=
$
this
->
content
[
$
previousSection
]
;
end
(
$
s
)
;
$
tok
=
current
(
$
s
)
;
while
(
$
tok
!==
false
)
{
if
(
$
tok
[
0
]
!=
self
::
TK_WS
&&
$
tok
[
0
]
!=
self
::
TK_COMMENT
)
{
break
;
}
if
(
$
tok
[
0
]
==
self
::
TK_COMMENT
&&
strpos
(
$
tok
[
1
]
,
'<?'
)
===
false
)
{
$
this
->
content
[
$
previousSection
]
[
key
(
$
s
)
]
=
array
(
self
::
TK_WS
,
'--'
)
;
}
$
tok
=
prev
(
$
s
)
;
}
}
}
unset
(
$
this
->
content
[
$
section
]
)
;
$
this
->
modified
=
true
;
}

remove a section from the ini file.

@param string $section the section where to remove the value, or the section to remove

@since 2.5.0


public function mergeSection($sectionSource, $sectionTarget)
    {
        if (!isset($this->content[$sectionTarget])) {
            return $this->renameSection($sectionSource, $sectionTarget);
        }

        if (!isset($this->content[$sectionSource])) {
            return false;
        }
        $this->mergeValues($this->content[$sectionSource], $sectionTarget);
        if ($sectionSource == '0') {
            $this->content[$sectionSource] = array();
        } else {
            unset($this->content[$sectionSource]);
        }
        $this->modified = true;

        return true;
    }

public function mergeSection ( $ sectionSource , $ sectionTarget ) { if ( ! isset ( $ this -> content [ $ sectionTarget ] ) ) { return $ this -> renameSection ( $ sectionSource , $ sectionTarget ) ; } if ( ! isset ( $ this -> content [ $ sectionSource ] ) ) { return false ; } $ this -> mergeValues ( $ this -> content [ $ sectionSource ] , $ sectionTarget ) ; if ( $ sectionSource == '0' ) { $ this -> content [ $ sectionSource ] = array ( ) ; } else { unset ( $ this -> content [ $ sectionSource ] ) ; } $ this -> modified = true ; return true ; }

move values of a section into an other section and remove the section.

@return bool true if the merge is a success

move values of a section into an other section and remove the section .


public function renameValue($name, $newName, $section = 0)
    {
        if (!isset($this->content[$section])) {
            return false;
        }
        foreach ($this->content[$section] as $k => $item) {
            if ($item[0] != self::TK_VALUE && $item[0] != self::TK_ARR_VALUE) {
                continue;
            }
            if ($item[1] != $name) {
                continue;
            }
            $this->content[$section][$k][1] = $newName;
            $this->modified = true;
            if ($item[0] == self::TK_VALUE) {
                break;
            }
        }

        return true;
    }

public function renameValue ( $ name , $ newName , $ section = 0 ) { if ( ! isset ( $ this -> content [ $ section ] ) ) { return false ; } foreach ( $ this -> content [ $ section ] as $ k => $ item ) { if ( $ item [ 0 ] != self :: TK_VALUE && $ item [ 0 ] != self :: TK_ARR_VALUE ) { continue ; } if ( $ item [ 1 ] != $ name ) { continue ; } $ this -> content [ $ section ] [ $ k ] [ 1 ] = $ newName ; $ this -> modified = true ; if ( $ item [ 0 ] == self :: TK_VALUE ) { break ; } } return true ; }


public function renameSection($oldName, $newName)
    {
        if (!isset($this->content[$oldName])) {
            return false;
        }

        if (isset($this->content[$newName])) {
            return $this->mergeSection($oldName, $newName);
        }

        $newcontent = array();
        foreach ($this->content as $section => $values) {
            if ((string) $oldName == (string) $section) {
                if ($section == '0') {
                    $newcontent[0] = array();
                }
                if ($values[0][0] == self::TK_SECTION) {
                    $values[0][1] = '['.$newName.']';
                } else {
                    array_unshift($values, array(self::TK_SECTION, '['.$newName.']'));
                }
                $newcontent[$newName] = $values;
            } else {
                $newcontent [$section] = $values;
            }
        }
        $this->content = $newcontent;
        $this->modified = true;

        return true;
    }

public function renameSection ( $ oldName , $ newName ) { if ( ! isset ( $ this -> content [ $ oldName ] ) ) { return false ; } if ( isset ( $ this -> content [ $ newName ] ) ) { return $ this -> mergeSection ( $ oldName , $ newName ) ; } $ newcontent = array ( ) ; foreach ( $ this -> content as $ section => $ values ) { if ( ( string ) $ oldName == ( string ) $ section ) { if ( $ section == '0' ) { $ newcontent [ 0 ] = array ( ) ; } if ( $ values [ 0 ] [ 0 ] == self :: TK_SECTION ) { $ values [ 0 ] [ 1 ] = '[' . $ newName . ']' ; } else { array_unshift ( $ values , array ( self :: TK_SECTION , '[' . $ newName . ']' ) ) ; } $ newcontent [ $ newName ] = $ values ; } else { $ newcontent [ $ section ] = $ values ; } } $ this -> content = $ newcontent ; $ this -> modified = true ; return true ; }


public static function read($filename, $asObject = false)
    {
        if (file_exists($filename)) {
            if ($asObject) {
                return (object) parse_ini_file($filename, true, INI_SCANNER_TYPED);
            } else {
                return parse_ini_file($filename, true, INI_SCANNER_TYPED);
            }
        } else {
            return false;
        }
    }

public static function read ( $ filename , $ asObject = false ) { if ( file_exists ( $ filename ) ) { if ( $ asObject ) { return ( object ) parse_ini_file ( $ filename , true , INI_SCANNER_TYPED ) ; } else { return parse_ini_file ( $ filename , true , INI_SCANNER_TYPED ) ; } } else { return false ; } }

read an ini file.

@param string $filename the path and the name of the file to read
@param bool   $asObject true if the content should be returned as an object

@return object|false the content of the file or false if file does not exists


public static function readAndMergeObject($filename, $content, $flags = 0,
                                              $ignoredSection = array())
    {
        if (!file_exists($filename)) {
            return false;
        }

        $newContent = @parse_ini_file($filename, true, INI_SCANNER_TYPED);
        if ($newContent === false) {
            return false;
        }

        return self::mergeIniObjectContents($content, $newContent, $flags, $ignoredSection);
    }

public static function readAndMergeObject ( $ filename , $ content , $ flags = 0 , $ ignoredSection = array ( ) ) { if ( ! file_exists ( $ filename ) ) { return false ; } $ newContent = @ parse_ini_file ( $ filename , true , INI_SCANNER_TYPED ) ; if ( $ newContent === false ) { return false ; } return self :: mergeIniObjectContents ( $ content , $ newContent , $ flags , $ ignoredSection ) ; }

read an ini file and merge its parameters to the given object.
Useful to merge to config files.
Parameters whose name starts with a '_' are not merged.

@param string $filename the path and the name of the file to read
@param object $content
@param int    $flags    a combination of constants NOT_MERGE_*, NORMAL_MERGE_*
@param array  $ignoredSection list of sections or top level parameters that
should not be merged

@return object|false the content of the file or false if error during parsing the file

@since 2.0

read an ini file and merge its parameters to the given object . Useful to merge to config files . Parameters whose name starts with a _ are not merged .


public static function mergeIniObjectContents(
        $baseContent,
        $contentToImport,
        $flags = 0,
        $ignoredSection = array()
    )
    {
        $contentToImport = (array) $contentToImport;

        foreach ($contentToImport as $k => $v) {
            if (!isset($baseContent->$k)) {
                $baseContent->$k = $v;
                continue;
            }

            if (($flags & self::NOT_MERGE_PROTECTED_DIRECTIVE) && $k[0] == '_') {
                continue;
            }

            if (in_array($k, $ignoredSection)) {
                continue;
            }

            if (is_array($v)) {
                // this is a section or a array value
                if (!is_array($baseContent->$k)) {
                    $baseContent->$k = $v;
                } else {
                    if ($flags & self::NORMAL_MERGE_ARRAY_VALUES_WITH_INTEGER_KEYS) {
                        if (self::hasOnlyIntegerKeys($v) && self::hasOnlyIntegerKeys($baseContent->$k)) {
                            $baseContent->$k = array_merge($baseContent->$k, $v);
                            continue;
                        }
                        $newbase = $baseContent->$k;
                    } else {
                        // first, in the case of an array value, clean the $base value, by removing all values with numerical keys
                        // as it does not make sens to merge two simple arrays here.
                        $newbase = array();
                        foreach ($baseContent->$k as $k2 => $v2) {
                            if (is_string($k2)) {
                                $newbase[$k2] = $v2;
                            }
                        }
                    }
                    $baseContent->$k = self::mergeSectionContent($newbase, $v, $flags);
                }
            } else {
                $baseContent->$k = $v;
            }
        }

        return $baseContent;
    }

merge two simple StdClass object.

@param object $baseContent     the object which receives new properties
@param object $contentToImport the object providing new properties
@param int    $flags           a combination of constants NOT_MERGE_*, NORMAL_MERGE_*
@param array  $ignoredSection  list of sections or top level parameters that
should not be merged

@return object $baseContent


private static function _iniValue($key, $value)
    {
        if (is_array($value)) {
            $res = '';
            foreach ($value as $v) {
                $res .= self::_iniValue($key.'[]', $v);
            }

            return $res;
        } elseif ($value == ''
                  || is_numeric($value)
                  || (is_string($value) &&
                      preg_match("/^[\w\\-\\.]*$/", $value) &&
                      strpos("\n", $value) === false)
        ) {
            return $key.'='.$value."\n";
        } elseif ($value === false) {
            return $key."=off\n";
        } elseif ($value === true) {
            return $key."=on\n";
        } else {
            return $key.'="'.$value."\"\n";
        }
    }

private static function _iniValue ( $ key , $ value ) { if ( is_array ( $ value ) ) { $ res = '' ; foreach ( $ value as $ v ) { $ res .= self :: _iniValue ( $ key . '[]' , $ v ) ; } return $ res ; } elseif ( $ value == '' || is_numeric ( $ value ) || ( is_string ( $ value ) && preg_match ( "/^[\w\\-\\.]*$/" , $ value ) && strpos ( "\n" , $ value ) === false ) ) { return $ key . '=' . $ value . "\n" ; } elseif ( $ value === false ) { return $ key . "=off\n" ; } elseif ( $ value === true ) { return $ key . "=on\n" ; } else { return $ key . '="' . $ value . "\"\n" ; } }

format a value to store in a ini file.

@param string $value the value

@return string the formated value


public function setValue($name, $value, $section = 0, $key = null)
    {
        if ($this->lastModifier instanceof IniModifierInterface) {
            $this->lastModifier->setValue($name, $value, $section, $key);
        } else {
            trigger_error('The top ini content is not alterable', E_USER_WARNING);
        }
    }

public
function
setValue
(
$
name
,
$
value
,
$
section
=
0
,
$
key
=
)
{
if
(
$
this
->
lastModifier
instanceof
IniModifierInterface
)
{
$
this
->
lastModifier
->
setValue
(
$
name
,
$
value
,
$
section
,
$
key
)
;
}
else
{
trigger_error
(
'The top ini content is not alterable'
,
E_USER_WARNING
)
;
}
}

modify an option in the latest ini file. If the option doesn't exist,
it is created.

@param string $name    the name of the option to modify
@param string $value   the new value
@param string $section the section where to set the item. 0 is the global section
@param string $key     for option which is an item of array, the key in the array

modify an option in the latest ini file . If the option doesn t exist it is created .


public function setValues($values, $section = 0)
    {
        if ($this->lastModifier instanceof IniModifierInterface) {
            $this->lastModifier->setValues($values, $section);
        } else {
            trigger_error('The top ini content is not alterable', E_USER_WARNING);
        }
    }

public
function
setValues
(
$
values
,
$
section
=
0
)
{
if
(
$
this
->
lastModifier
instanceof
IniModifierInterface
)
{
$
this
->
lastModifier
->
setValues
(
$
values
,
$
section
)
;
}
else
{
trigger_error
(
'The top ini content is not alterable'
,
E_USER_WARNING
)
;
}
}

modify several options in the latest ini file.

@param array  $value   associated array with key=>value
@param string $section the section where to set the item. 0 is the global section

modify several options in the latest ini file .


public function getValues($section = 0)
    {
        $finalValues = array();
        foreach ($this->modifiers as $mod) {
            $values = $mod->getValues($section);
            if (!count($values)) {
                continue;
            }
            if (!count($finalValues)) {
                $finalValues = $values;
                continue;
            }
            foreach ($values as $key => &$value) {
                if (!isset($finalValues[$key])) {
                    $finalValues[$key] = $value;
                    continue;
                }
                if (is_array($value) && is_array($finalValues[$key])) {
                    $finalValues[$key] = array_merge($finalValues[$key], $value);
                } else {
                    $finalValues[$key] = $value;
                }
            }
        }

        return $finalValues;
    }

public function getValues ( $ section = 0 ) { $ finalValues = array ( ) ; foreach ( $ this -> modifiers as $ mod ) { $ values = $ mod -> getValues ( $ section ) ; if ( ! count ( $ values ) ) { continue ; } if ( ! count ( $ finalValues ) ) { $ finalValues = $ values ; continue ; } foreach ( $ values as $ key => & $ value ) { if ( ! isset ( $ finalValues [ $ key ] ) ) { $ finalValues [ $ key ] = $ value ; continue ; } if ( is_array ( $ value ) && is_array ( $ finalValues [ $ key ] ) ) { $ finalValues [ $ key ] = array_merge ( $ finalValues [ $ key ] , $ value ) ; } else { $ finalValues [ $ key ] = $ value ; } } } return $ finalValues ; }

return all values of a section from all ini files.

@param string $section the section from wich we want values. 0 is the global section

@return array the list of values, $key=>$value

return all values of a section from all ini files .


public function removeValue($name, $section = 0, $key = null, $removePreviousComment = true)
    {
        foreach ($this->modifiers as $mod) {
            if ($mod instanceof IniModifierInterface) {
                $mod->removeValue($name, $section, $key, $removePreviousComment);
            }
        }
    }

public function removeValue ( $ name , $ section = 0 , $ key = null , $ removePreviousComment = true ) { foreach ( $ this -> modifiers as $ mod ) { if ( $ mod instanceof IniModifierInterface ) { $ mod -> removeValue ( $ name , $ section , $ key , $ removePreviousComment ) ; } } }

remove an option from all ini file.

It can remove an entire section if you give an empty value as $name, and a $section name.
(deprecated behavior, see removeSection())

@param string $name                  the name of the option to remove, or null to remove an entire section
@param string $section               the section where to remove the value, or the section to remove
@param int    $key                   for option which is an item of array, the key in the array
@param bool   $removePreviousComment if a comment is before the value, if true, it removes also the comment


public function removeSection($section = 0, $removePreviousComment = true)
    {
        foreach ($this->modifiers as $mod) {
            if ($mod instanceof IniModifierInterface) {
                $mod->removeSection($section, $removePreviousComment);
            }
        }
    }

public function removeSection ( $ section = 0 , $ removePreviousComment = true ) { foreach ( $ this -> modifiers as $ mod ) { if ( $ mod instanceof IniModifierInterface ) { $ mod -> removeSection ( $ section , $ removePreviousComment ) ; } } }

remove a section from all ini file.
@param int $section
@param bool $removePreviousComment
@since 2.5.0


public function setValue($name, $value, $section = 0, $key = null)
    {
        $this->overrider->setValue($name, $value, $section, $key);
    }

public function setValue ( $ name , $ value , $ section = 0 , $ key = null ) { $ this -> overrider -> setValue ( $ name , $ value , $ section , $ key ) ; }

modify an option in the overrider ini file. If the option doesn't exist,
it is created.

@param string $name    the name of the option to modify
@param string $value   the new value
@param string $section the section where to set the item. 0 is the global section
@param string $key     for option which is an item of array, the key in the array

modify an option in the overrider ini file . If the option doesn t exist it is created .


public function setValueOnMaster($name, $value, $section = 0, $key = null)
    {
        if (!$this->master instanceof IniModifierInterface) {
            throw new IniException('Cannot set value on master which is only an ini reader');
        }
        $this->master->setValue($name, $value, $section, $key);
    }

modify an option in the master ini file. If the option doesn't exist,
it is created.

@param string $name    the name of the option to modify
@param string $value   the new value
@param string $section the section where to set the item. 0 is the global section
@param string $key     for option which is an item of array, the key in the array

modify an option in the master ini file . If the option doesn t exist it is created .


public function setValuesOnMaster($values, $section = 0)
    {
        if (!$this->master instanceof IniModifierInterface) {
            throw new IniException('Cannot set value on master which is only an ini reader');
        }
        $this->master->setValues($values, $section);
    }

modify several options in the master ini file.

@param array  $value   associated array with key=>value
@param string $section the section where to set the item. 0 is the global section

modify several options in the master ini file .


public function getValueOnMaster($name, $section = 0, $key = null)
    {
        return $this->master->getValue($name, $section, $key);
    }

public function getValueOnMaster ( $ name , $ section = 0 , $ key = null ) { return $ this -> master -> getValue ( $ name , $ section , $ key ) ; }

return the value of an option from the master ini file only.
If the option doesn't exist, it returns null.

@param string $name    the name of the option to retrieve
@param string $section the section where the option is. 0 is the global section
@param string $key     for option which is an item of array, the key in the array

@return mixed the value

return the value of an option from the master ini file only . If the option doesn t exist it returns null .


public function getValues($section = 0)
    {
        $masterValues = $this->master->getValues($section);
        $overValues = $this->overrider->getValues($section);

        foreach ($overValues as $key => &$value) {
            if (!isset($masterValues[$key])) {
                $masterValues[$key] = $value;
                continue;
            }
            if (is_array($value) && is_array($masterValues[$key])) {
                $masterValues[$key] = array_merge($masterValues[$key], $value);
            } else {
                $masterValues[$key] = $value;
            }
        }

        return $masterValues;
    }

public function getValues ( $ section = 0 ) { $ masterValues = $ this -> master -> getValues ( $ section ) ; $ overValues = $ this -> overrider -> getValues ( $ section ) ; foreach ( $ overValues as $ key => & $ value ) { if ( ! isset ( $ masterValues [ $ key ] ) ) { $ masterValues [ $ key ] = $ value ; continue ; } if ( is_array ( $ value ) && is_array ( $ masterValues [ $ key ] ) ) { $ masterValues [ $ key ] = array_merge ( $ masterValues [ $ key ] , $ value ) ; } else { $ masterValues [ $ key ] = $ value ; } } return $ masterValues ; }

return all values of a section from the both ini files.

@param string $section the section from wich we want values. 0 is the global section

@return array the list of values, $key=>$value

return all values of a section from the both ini files .


public function removeValue($name, $section = 0, $key = null, $removePreviousComment = true)
    {
        if ($this->master instanceof IniModifierInterface) {
            $this->master->removeValue($name, $section, $key, $removePreviousComment);
        }
        $this->overrider->removeValue($name, $section, $key, $removePreviousComment);
    }

public function removeValue ( $ name , $ section = 0 , $ key = null , $ removePreviousComment = true ) { if ( $ this -> master instanceof IniModifierInterface ) { $ this -> master -> removeValue ( $ name , $ section , $ key , $ removePreviousComment ) ; } $ this -> overrider -> removeValue ( $ name , $ section , $ key , $ removePreviousComment ) ; }

remove an option from the two ini file.

It can remove an entire section if you give an empty value as $name,
and a $section name. (deprecated behavior, see removeSection())

@param string $name                  the name of the option to remove, or null to remove an entire section
@param string $section               the section where to remove the value, or the section to remove
@param int    $key                   for option which is an item of array, the key in the array
@param bool   $removePreviousComment if a comment is before the value, if true, it removes also the comment

remove an option from the two ini file .


public function removeValueOnMaster($name, $section = 0, $key = null, $removePreviousComment = true)
    {
        if (!$this->master instanceof IniModifierInterface) {
            throw new IniException('Cannot remove value on master which is only an ini reader');
        }
        $this->master->removeValue($name, $section, $key, $removePreviousComment);
    }

remove an option from the master ini file only.

It can remove an entire section if you give an empty value as $name,
and a $section name. (deprecated behavior, see removeSection())

@param string $name                  the name of the option to remove, or null to remove an entire section
@param string $section               the section where to remove the value, or the section to remove
@param int    $key                   for option which is an item of array, the key in the array
@param bool   $removePreviousComment if a comment is before the value, if true, it removes also the comment

remove an option from the master ini file only .


public function isSection($name)
    {
        return $this->overrider->isSection($name) || $this->master->isSection($name);
    }

public function isSection ( $ name ) { return $ this -> overrider -> isSection ( $ name ) || $ this -> master -> isSection ( $ name ) ; }

says if there is a section with the given name.

says if there is a section with the given name .


public function getValues($section = 0)
    {
        if (!isset($this->content[$section])) {
            return array();
        }
        $values = array();
        foreach ($this->content[$section] as $k => $item) {
            if ($item[0] != self::TK_VALUE && $item[0] != self::TK_ARR_VALUE) {
                continue;
            }

            $val = $this->convertValue($item[2]);

            if ($item[0] == self::TK_VALUE) {
                $values[$item[1]] = $val;
            } else {
                $values[$item[1]][$item[3]] = $val;
            }
        }

        return $values;
    }

public function getValues ( $ section = 0 ) { if ( ! isset ( $ this -> content [ $ section ] ) ) { return array ( ) ; } $ values = array ( ) ; foreach ( $ this -> content [ $ section ] as $ k => $ item ) { if ( $ item [ 0 ] != self :: TK_VALUE && $ item [ 0 ] != self :: TK_ARR_VALUE ) { continue ; } $ val = $ this -> convertValue ( $ item [ 2 ] ) ; if ( $ item [ 0 ] == self :: TK_VALUE ) { $ values [ $ item [ 1 ] ] = $ val ; } else { $ values [ $ item [ 1 ] ] [ $ item [ 3 ] ] = $ val ; } } return $ values ; }

return all values of a section in the ini file.

@param string $section the section from which we want values. 0 is the global section

@return array the list of values, $key=>$value

return all values of a section in the ini file .


public function createFileLoader($type, ContainerBuilder $container, $path)
    {
        $className = $this->getClassNameByShortType($type);

        return new $className($container, new FileLocator($path));
    }

public function createFileLoader ( $ type , ContainerBuilder $ container , $ path ) { $ className = $ this -> getClassNameByShortType ( $ type ) ; return new $ className ( $ container , new FileLocator ( $ path ) ) ; }

Creates a loader for the service config file

@param  string           $type      The name of the file type, such as xml, yml or php
@param  ContainerBuilder $container
@param  string           $path      The path to the *directory* containing the the file
@return LoaderInterface


protected function getClassNameByShortType($type)
    {
        if (!isset($this->shortTypeToClassMapping[$type])) {
            throw UnknownFormatException::create($type);
        }

        return $this->shortTypeToClassMapping[$type];
    }

protected function getClassNameByShortType ( $ type ) { if ( ! isset ( $ this -> shortTypeToClassMapping [ $ type ] ) ) { throw UnknownFormatException :: create ( $ type ) ; } return $ this -> shortTypeToClassMapping [ $ type ] ; }

Get loader class name based on short name
@param  string                 $type
@return string                 Loader class name
@throws UnknownFormatException


public function make($name, $value, $minutes = null, $path = null, $domain = null, $secure = false, $httponly = true)
    {
        // Calculate a hash for the data and append it to the end of the data string
        $hash = hash_hmac($this->hash_algo, $value, $this->hash_secret);
        $value .= $hash;
        $minutes = $minutes ? $minutes : self::DEFAULT_EXPIRATION_DATE;
        // Set a cookie with the data
        $ttl = $minutes === null ? 0 : time() + ($minutes * 60);
        return setcookie($name, base64_encode($value), $ttl, $path, $domain, $secure, $httponly);
    }

Set cookie.

@param string $name
@param string $value
@param int|null $minutes If null, we set the value to `0` (which means the cookie lives
within this client session), otherwise the timestamp is calculated
as `current time + $minutes * 60`
@param string|null $path
@param string|null $domain
@param bool $secure
@param bool $httponly
@return bool


protected function execute(InputInterface $input, OutputInterface $output)
    {
        $fileToConvert = $this->determineFile($output, $input->getArgument('file'));
        $newFormat = $input->getArgument('format');

        $newConfig = $this
            ->getContainer()
            ->get('tuck_converter.config_format_converter')
            ->convertFile($fileToConvert, $newFormat);

        if ($input->getOption('output')) {
            $output->write($newConfig);
        } else {
            $this->writeToFile($output, $fileToConvert, $newConfig, $newFormat);
        }
    }

Interactively determine the file and convert it

@param  InputInterface  $input
@param  OutputInterface $output
@return void


protected function determineFile(OutputInterface $output, $givenFileName)
    {
        if (is_file($givenFileName)) {
            return new \SplFileInfo($givenFileName);
        }

        return $this->chooseFileInDirectory(
            $output,
            $this->chooseBundle($output)->getPath().'/Resources/config/'
        );
    }

protected function determineFile ( OutputInterface $ output , $ givenFileName ) { if ( is_file ( $ givenFileName ) ) { return new \ SplFileInfo ( $ givenFileName ) ; } return $ this -> chooseFileInDirectory ( $ output , $ this -> chooseBundle ( $ output ) -> getPath ( ) . '/Resources/config/' ) ; }

Choose file from cli input or interactively

@param  OutputInterface $output
@param  string          $givenFileName
@return SplFileInfo


protected function chooseBundle(OutputInterface $output)
    {
        $bundles = $this->getContainer()->get('kernel')->getBundles();

        $selectedBundle = $this->getHelperSet()->get('dialog')->ask(
            $output,
            '<info>Which bundle\'s config would you like to convert? </info>',
            null,
            array_keys($bundles)
        );

        if (!isset($bundles[$selectedBundle])) {
            throw UnknownBundleException::create($selectedBundle);
        }

        return $bundles[$selectedBundle];
    }

Prompt the user to choose the bundle whose config they want to convert

@param  OutputInterface        $output
@return Bundle
@throws UnknownBundleException


protected function writeToFile(OutputInterface $output, SplFileInfo $originalFile, $newConfig, $newFormat)
    {
        $proposedLocation = $originalFile->getPath().'/services.'.$newFormat;
        $location = $this->getHelperSet()->get('dialog')->ask(
            $output,
            "<info>Where should the new config be written?</info> [{$proposedLocation}] ",
            $proposedLocation
        );

        if (file_exists($location)
            && !$this->getHelperSet()->get('dialog')->askConfirmation($output, 'File exists. Overwrite? ')
        ) {
            $output->writeln('Aborting...');

            return;
        }

        file_put_contents($location, $newConfig);
        $output->writeln(
            "Written! Don't forget to update the DependencyInjection/*Extension class in your bundle to use the new ".
            "loader class and delete the old config file."
        );
    }

Write the new config to the same directory as the original file

@param OutputInterface $output
@param SplFileInfo     $originalFile
@param string          $newConfig
@param string          $newFormat    The short file name given, like


public function createDumper($type, ContainerBuilder $container)
    {
        $className = $this->getClassNameByShortType($type);

        return new $className($container);
    }

public function createDumper ( $ type , ContainerBuilder $ container ) { $ className = $ this -> getClassNameByShortType ( $ type ) ; return new $ className ( $ container ) ; }

Creates a dumper for use only by the given container

@param  string           $type
@param  ContainerBuilder $container
@return DumperInterface


public function convertString($content, $oldFormat, $newFormat)
    {
        $tempFile = $this->tempFileFactory->createFile($content, $oldFormat);

        try {
            $output = $this->convertFile($tempFile, $newFormat);
        } catch (\Exception $e) {
            // Cleanup the temp file, even with a failure
            unlink($tempFile->getRealPath());
            throw $e;
        }
        unlink($tempFile->getRealPath());

        return $output;
    }

Convert a config represented as a string to some other format

@param  string $content
@param  string $oldFormat
@param  string $newFormat

@throws \Exception when file conversion fails

@return string


public function read($session_id) {

    // Check for the existance of a cookie with the name of the session id
    // Make sure that the cookie is atleast the size of our hash, otherwise it's invalid
    // Return an empty string if it's invalid.
    if (! $this->storage->has($session_id)) return '';

    try {
      $data = $this->storage->get($session_id);
    } catch (HashMismatchException $ex) {
      $data = '';
    }

    // Return the data, now that it's been verified.
    return $data;
  }

Called by PHP to read session data.
@param string $session_id
@return string serialized session data


protected function getRoutes(): array
    {
        $routes = [];

        foreach ($this->routes as $route) {
            if (($routeInfo = $this->getRouteInformation($route)) !== null) {
                $routes[] = $routeInfo;
            }
        }

        if ($sort = $this->option('sort')) {
            $routes = self::sort($routes, static function ($route) use ($sort) {
                return $route[$sort];
            });
        }

        if ($this->option('reverse')) {
            $routes = \array_reverse($routes);
        }

        return \array_filter($routes);
    }

protected function getRoutes ( ) : array { $ routes = [ ] ; foreach ( $ this -> routes as $ route ) { if ( ( $ routeInfo = $ this -> getRouteInformation ( $ route ) ) !== null ) { $ routes [ ] = $ routeInfo ; } } if ( $ sort = $ this -> option ( 'sort' ) ) { $ routes = self :: sort ( $ routes , static function ( $ route ) use ( $ sort ) { return $ route [ $ sort ] ; } ) ; } if ( $ this -> option ( 'reverse' ) ) { $ routes = \ array_reverse ( $ routes ) ; } return \ array_filter ( $ routes ) ; }

Compile the routes into a displayable format.

@return array

Compile the routes into a displayable format .


protected static function sort(array $array, callable $callback): array
    {
        $results = [];

        foreach ($array as $key => $value) {
            $results[$key] = $callback($value, $key);
        }

        \asort($results, \SORT_REGULAR);

        foreach (\array_keys($results) as $key) {
            $results[$key] = $array[$key];
        }

        return $results;
    }

protected static function sort ( array $ array , callable $ callback ) : array { $ results = [ ] ; foreach ( $ array as $ key => $ value ) { $ results [ $ key ] = $ callback ( $ value , $ key ) ; } \ asort ( $ results , \ SORT_REGULAR ) ; foreach ( \ array_keys ( $ results ) as $ key ) { $ results [ $ key ] = $ array [ $ key ] ; } return $ results ; }

Sort the array using the given callback.

@param array    $array
@param callable $callback

@return array

Sort the array using the given callback .


public function setOffset(int $offset): void
    {
        $current = $this->stream->tell();

        if ($current !== $offset) {
            // If the stream cannot seek to the offset position, then read to it
            if ($this->stream->isSeekable()) {
                $this->stream->seek($offset);
            } elseif ($current > $offset) {
                throw new RuntimeException(\sprintf('Could not seek to stream offset %s', $offset));
            } else {
                $this->stream->read($offset - $current);
            }
        }

        $this->offset = $offset;
    }

Set the offset to start limiting from.

@param int $offset Offset to seek to and begin byte limiting from

@throws \Viserio\Component\Contract\Http\Exception\RuntimeException if the stream cannot be seeked

@return void


protected function gatherData(): array
    {
        $data = \array_merge($this->factory->getShared(), $this->data);

        foreach ($data as $key => $value) {
            if ($value instanceof Renderable) {
                $data[$key] = $value->render();
            } elseif ($value instanceof Closure) {
                $data[$key] = $value();
            }
        }

        return $data;
    }

protected function gatherData ( ) : array { $ data = \ array_merge ( $ this -> factory -> getShared ( ) , $ this -> data ) ; foreach ( $ data as $ key => $ value ) { if ( $ value instanceof Renderable ) { $ data [ $ key ] = $ value -> render ( ) ; } elseif ( $ value instanceof Closure ) { $ data [ $ key ] = $ value ( ) ; } } return $ data ; }

Get the data bound to the view instance.

@return array

Get the data bound to the view instance .


private function putContentToFile(string $file, string $content, string $key): void
    {
        if ($this->hasOption('overwrite') || ! \file_exists($file)) {
            \file_put_contents($file, $content);
        } else {
            if ($this->hasOption('merge')) {
                $confirmed = true;
            } else {
                $confirmed = $this->confirm(\sprintf('Do you really wish to overwrite %s', $key));
            }

            if ($confirmed) {
                \file_put_contents($file, $content);
            }
        }
    }

private
function
putContentToFile
(
string
$
file
,
string
$
content
,
string
$
key
)
:
void
{
if
(
$
this
->
hasOption
(
'overwrite'
)
||
!
\
file_exists
(
$
file
)
)
{
\
file_put_contents
(
$
file
,
$
content
)
;
}
else
{
if
(
$
this
->
hasOption
(
'merge'
)
)
{
$
confirmed
=
true
;
}
else
{
$
confirmed
=
$
this
->
confirm
(
\
sprintf
(
'Do you really wish to overwrite %s'
,
$
key
)
)
;
}
if
(
$
confirmed
)
{
\
file_put_contents
(
$
file
,
$
content
)
;
}
}
}

Put the created content to file.

@param string $file
@param string $content
@param string $key

@return void


private function getConfigReader(): OptionsReader
    {
        $command = $this;

        return new class($command) extends OptionsReader {
            /**
             * A OptionDumpCommand instance.
             *
             * @var \Viserio\Component\OptionsResolver\Command\OptionDumpCommand
             */
            private $command;

            /**
             * @param \Viserio\Component\OptionsResolver\Command\OptionDumpCommand $command
             */
            public function __construct(OptionDumpCommand $command)
            {
                $this->command = $command;
            }

            /**
             * Read the mandatory options and ask for the value.
             *
             * @param string $className
             * @param array  $dimensions
             * @param array  $mandatoryOptions
             *
             * @return array
             */
            protected function readMandatoryOption(string $className, array $dimensions, array $mandatoryOptions): array
            {
                $options = [];

                foreach ($mandatoryOptions as $key => $mandatoryOption) {
                    if (! \is_scalar($mandatoryOption)) {
                        $options[$key] = $this->readMandatoryOption($className, $dimensions, $mandatoryOptions[$key]);

                        continue;
                    }

                    $options[$mandatoryOption] = $this->command->ask(
                        \sprintf(
                            '%s: Please enter the following mandatory value for [%s]',
                            $className,
                            \implode('.', $dimensions) . '.' . $mandatoryOption
                        )
                    );
                }

                return $options;
            }
        };
    }

Get a modified OptionsReader instance.

@return \Viserio\Component\OptionsResolver\Command\OptionsReader


protected function runRoute(RouteContract $route, ServerRequestInterface $request): ResponseInterface
    {
        $pipeline = new Pipeline();

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

        return $pipeline->send($request)
            ->through($this->gatherRouteMiddleware($route))
            ->then(static function ($request) use ($route) {
                return $route->run($request);
            });
    }

protected function runRoute ( RouteContract $ route , ServerRequestInterface $ request ) : ResponseInterface { $ pipeline = new Pipeline ( ) ; if ( $ this -> container !== null ) { $ pipeline -> setContainer ( $ this -> container ) ; } return $ pipeline -> send ( $ request ) -> through ( $ this -> gatherRouteMiddleware ( $ route ) ) -> then ( static function ( $ request ) use ( $ route ) { return $ route -> run ( $ request ) ; } ) ; }

Run the given route within a Stack "onion" instance.

@param \Viserio\Component\Contract\Routing\Route $route
@param \Psr\Http\Message\ServerRequestInterface  $request

@return \Psr\Http\Message\ResponseInterface

Run the given route within a Stack onion instance .


protected function gatherRouteMiddleware(RouteContract $route): array
    {
        $middleware = [];

        self::map($route->gatherMiddleware(), function ($nameOrObject) use (&$middleware, $route): void {
            $bypass = $route->gatherDisabledMiddleware();

            if (\is_object($nameOrObject) && ! isset($bypass[\get_class($nameOrObject)])) {
                $middleware[] = $nameOrObject;
            } else {
                $middleware[] = MiddlewareNameResolver::resolve(
                    $nameOrObject,
                    $this->middleware,
                    $this->middlewareGroups,
                    $bypass
                );
            }
        });

        return (new SortedMiddleware(
            $this->middlewarePriority,
            self::flatten($middleware)
        ))->getAll();
    }

protected function gatherRouteMiddleware ( RouteContract $ route ) : array { $ middleware = [ ] ; self :: map ( $ route -> gatherMiddleware ( ) , function ( $ nameOrObject ) use ( & $ middleware , $ route ) : void { $ bypass = $ route -> gatherDisabledMiddleware ( ) ; if ( \ is_object ( $ nameOrObject ) && ! isset ( $ bypass [ \ get_class ( $ nameOrObject ) ] ) ) { $ middleware [ ] = $ nameOrObject ; } else { $ middleware [ ] = MiddlewareNameResolver :: resolve ( $ nameOrObject , $ this -> middleware , $ this -> middlewareGroups , $ bypass ) ; } } ) ; return ( new SortedMiddleware ( $ this -> middlewarePriority , self :: flatten ( $ middleware ) ) ) -> getAll ( ) ; }

Gather the middleware for the given route.

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

@return array

Gather the middleware for the given route .


protected static function flatten(array $array): array
    {
        $flattened = [];

        foreach ($array as $key => $value) {
            if (\is_array($value)) {
                $flattened = \array_merge($flattened, static::flatten($value));
            } else {
                $flattened[] = $value;
            }
        }

        return $flattened;
    }

protected static function flatten ( array $ array ) : array { $ flattened = [ ] ; foreach ( $ array as $ key => $ value ) { if ( \ is_array ( $ value ) ) { $ flattened = \ array_merge ( $ flattened , static :: flatten ( $ value ) ) ; } else { $ flattened [ ] = $ value ; } } return $ flattened ; }

Convert a multi-dimensional array into a single-dimensional array without keys.

@param array $array

@return array

Convert a multi - dimensional array into a single - dimensional array without keys .


protected static function loadConfigurationFiles(KernelContract $kernel, RepositoryContract $config): void
    {
        foreach (static::getFiles($kernel->getConfigPath('packages'), self::CONFIG_EXTS) as $path) {
            $config->import($path);
        }

        foreach (static::getFiles($kernel->getConfigPath(), self::CONFIG_EXTS) as $path) {
            $config->import($path);
        }

        foreach (static::getFiles($kernel->getConfigPath($kernel->getEnvironment()), self::CONFIG_EXTS) as $path) {
            $config->import($path);
        }

        foreach (static::getFiles($kernel->getConfigPath('packages' . \DIRECTORY_SEPARATOR . $kernel->getEnvironment()), self::CONFIG_EXTS) as $path) {
            $config->import($path);
        }
    }

protected static function loadConfigurationFiles ( KernelContract $ kernel , RepositoryContract $ config ) : void { foreach ( static :: getFiles ( $ kernel -> getConfigPath ( 'packages' ) , self :: CONFIG_EXTS ) as $ path ) { $ config -> import ( $ path ) ; } foreach ( static :: getFiles ( $ kernel -> getConfigPath ( ) , self :: CONFIG_EXTS ) as $ path ) { $ config -> import ( $ path ) ; } foreach ( static :: getFiles ( $ kernel -> getConfigPath ( $ kernel -> getEnvironment ( ) ) , self :: CONFIG_EXTS ) as $ path ) { $ config -> import ( $ path ) ; } foreach ( static :: getFiles ( $ kernel -> getConfigPath ( 'packages' . \ DIRECTORY_SEPARATOR . $ kernel -> getEnvironment ( ) ) , self :: CONFIG_EXTS ) as $ path ) { $ config -> import ( $ path ) ; } }

Load the configuration items from all of the files.

@param \Viserio\Component\Contract\Foundation\Kernel $kernel
@param \Viserio\Component\Contract\Config\Repository $config

@return void

Load the configuration items from all of the files .


protected function getSlice(): Closure
    {
        return function ($stack, $stage) {
            return function ($traveler) use ($stack, $stage) {
                // If the $stage is an instance of a Closure, we will just call it directly.
                if ($stage instanceof Closure) {
                    return $stage($traveler, $stack);
                }

                // Otherwise we'll resolve the stages out of the container and call it with
                // the appropriate method and arguments, returning the results back out.
                if ($this->container && ! \is_object($stage) && \is_string($stage)) {
                    return $this->sliceThroughContainer($traveler, $stack, $stage);
                }

                if (\is_array($stage)) {
                    $parameters = [$traveler, $stack];
                    $class      = \array_shift($stage);

                    if (\is_object($class) && (\is_string($class) && \class_exists($class))) {
                        throw new \InvalidArgumentException(\sprintf(
                            'The first entry in the array must be a class, [%s] given.',
                            \is_object($class) ? \get_class($class) : \gettype($class)
                        ));
                    }

                    /** @var \Closure $object */
                    $object = (new ReflectionClass($class))->newInstanceArgs($stage);

                    return $object(...$parameters);
                }

                // If the pipe is already an object we'll just make a callable and pass it to
                // the pipe as-is. There is no need to do any extra parsing and formatting
                // since the object we're given was already a fully instantiated object.
                $parameters = [$traveler, $stack];

                return $stage->{$this->method}(...$parameters);
            };
        };
    }

Get a Closure that represents a slice of the application onion.

@return \Closure

Get a Closure that represents a slice of the application onion .


protected function parseStageString(string $stage): array
    {
        [$name, $parameters] = \array_pad(\explode(':', $stage, 2), 2, []);

        if (\is_string($parameters)) {
            $parameters = \explode(',', $parameters);
        }

        return [$name, $parameters];
    }

protected function parseStageString ( string $ stage ) : array { [ $ name , $ parameters ] = \ array_pad ( \ explode ( ':' , $ stage , 2 ) , 2 , [ ] ) ; if ( \ is_string ( $ parameters ) ) { $ parameters = \ explode ( ',' , $ parameters ) ; } return [ $ name , $ parameters ] ; }

Parse full pipe string to get name and parameters.

@param string $stage

@return array

Parse full pipe string to get name and parameters .


public function call(string $command, array $parameters = [], ?OutputInterface $outputBuffer = null): int
    {
        if (\is_subclass_of($command, SymfonyCommand::class)) {
            /** @var \Symfony\Component\Console\Command\Command $symfonyCommand */
            $symfonyCommand = $command;

            if (($commandName = $symfonyCommand::getDefaultName()) !== null) {
                $command = $commandName;
            }
        }

        if (! $this->has($command)) {
            throw new CommandNotFoundException(\sprintf('The command [%s] does not exist.', $command));
        }

        $this->lastOutput = $outputBuffer ?: new BufferedOutput();

        $this->setCatchExceptions(false);

        \array_unshift($parameters, $command);

        $input = new ArrayInput($parameters);

        if ($input->hasParameterOption(['--no-interaction'], true)) {
            $input->setInteractive(false);
        }

        $result = $this->run($input, $this->lastOutput);

        $this->setCatchExceptions(true);

        return $result;
    }

Run an console command by name.

@param string                                                 $command
@param array                                                  $parameters
@param null|\Symfony\Component\Console\Output\OutputInterface $outputBuffer

@throws \Throwable

@return int


public function defaults(string $commandName, array $argumentDefaults = []): void
    {
        $command           = $this->get($commandName);
        $commandDefinition = $command->getDefinition();

        foreach ($argumentDefaults as $name => $default) {
            $argument = $commandDefinition->getArgument($name);
            $argument->setDefault($default);
        }
    }

public function defaults ( string $ commandName , array $ argumentDefaults = [ ] ) : void { $ command = $ this -> get ( $ commandName ) ; $ commandDefinition = $ command -> getDefinition ( ) ; foreach ( $ argumentDefaults as $ name => $ default ) { $ argument = $ commandDefinition -> getArgument ( $ name ) ; $ argument -> setDefault ( $ default ) ; } }

Define default values for the arguments of the command.

@param string $commandName      name of the command
@param array  $argumentDefaults default argument values

@return void

Define default values for the arguments of the command .


public static function phpBinary(): string
    {
        $finder = (new PhpExecutableFinder())->find(false);

        return \escapeshellarg($finder === false ? '' : $finder);
    }

public static function phpBinary ( ) : string { $ finder = ( new PhpExecutableFinder ( ) ) -> find ( false ) ; return \ escapeshellarg ( $ finder === false ? '' : $ finder ) ; }


public static function cerebroBinary(): string
    {
        $constant = \defined('CEREBRO_BINARY') ? \constant('CEREBRO_BINARY') : null;

        return  $constant !== null ? \escapeshellarg($constant) : 'cerebro';
    }

public static function cerebroBinary ( ) : string { $ constant = \ defined ( 'CEREBRO_BINARY' ) ? \ constant ( 'CEREBRO_BINARY' ) : null ; return $ constant !== null ? \ escapeshellarg ( $ constant ) : 'cerebro' ; }


protected function doRunCommand(SymfonyCommand $command, InputInterface $input, OutputInterface $output): int
    {
        $this->runningCommand = $command;

        foreach ($command->getHelperSet() as $helper) {
            if ($helper instanceof InputAwareInterface) {
                $helper->setInput($input);
            }
        }

        if ($this->eventManager === null) {
            return $command->run($input, $output);
        }

        // bind before the console.command event, so the listeners have access to input options/arguments
        try {
            $command->mergeApplicationDefinition();
            $input->bind($command->getDefinition());
        } catch (ExceptionInterface $exception) {
            // ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
        }

        $event     = new ConsoleCommandEvent($command, $input, $output);
        $exception = null;

        try {
            $this->eventManager->trigger($event);

            if ($event->commandShouldRun()) {
                $exitCode = $command->run($input, $output);
            } else {
                $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
            }
        } catch (Throwable $exception) {
            $this->eventManager->trigger($event = new ConsoleErrorEvent($command, $input, $output, $exception));
            $exception = $event->getError();

            if (($exitCode = $event->getExitCode()) === 0) {
                $exception = null;
            }
        }

        $this->eventManager->trigger($event = new ConsoleTerminateEvent($command, $input, $output, $exitCode));

        if ($exception !== null) {
            throw $exception;
        }

        return $event->getExitCode();
    }

Runs the current command.

If an event dispatcher has been attached to the application,
events are also dispatched during the life-cycle of the command.

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

@throws \Throwable

@return int 0 if everything went fine, or an error code


protected function getDefaultInputDefinition(): InputDefinition
    {
        $definition = parent::getDefaultInputDefinition();
        $definition->addOption($this->getEnvironmentOption());

        return $definition;
    }

protected function getDefaultInputDefinition ( ) : InputDefinition { $ definition = parent :: getDefaultInputDefinition ( ) ; $ definition -> addOption ( $ this -> getEnvironmentOption ( ) ) ; return $ definition ; }

Get the default input definitions for the applications.

This is used to add the --env option to every available command.

@return \Symfony\Component\Console\Input\InputDefinition

Get the default input definitions for the applications .


public function build(array $routes): array
    {
        $rootRouteData = null;
        $nodes         = [];
        $groupedRoutes = [];

        foreach ($routes as $route) {
            $groupedRoutes[\count($route->getSegments())][] = $route;
        }

        if (isset($groupedRoutes[0])) {
            $rootRouteData = new MatchedRouteDataMap();
            $rootRouteData->addRoute($groupedRoutes[0][0], []);

            unset($groupedRoutes[0]);
        }

        foreach ($groupedRoutes as $segmentDepth => $group) {
            $groupNodes = [];

            foreach ($group as $route) {
                $parameterIndexNameMap = [];
                $segments              = $route->getSegments();
                $segmentMatcher        = $this->getMatcher(\array_shift($segments), $parameterIndexNameMap);
                $firstSegmentHash      = $segmentMatcher->getHash();

                if (! isset($groupNodes[$firstSegmentHash])) {
                    $groupNodes[$firstSegmentHash] = new RouteTreeNode(
                        [0 => $segmentMatcher],
                        $segmentDepth === 1 ? new MatchedRouteDataMap() : new ChildrenNodeCollection()
                    );
                }

                $this->addRouteToNode($groupNodes[$firstSegmentHash], $route, $segments, 1, $parameterIndexNameMap);
            }

            $nodes[$segmentDepth] = new ChildrenNodeCollection($groupNodes);
        }

        return [$rootRouteData, $nodes];
    }

public function build ( array $ routes ) : array { $ rootRouteData = null ; $ nodes = [ ] ; $ groupedRoutes = [ ] ; foreach ( $ routes as $ route ) { $ groupedRoutes [ \ count ( $ route -> getSegments ( ) ) ] [ ] = $ route ; } if ( isset ( $ groupedRoutes [ 0 ] ) ) { $ rootRouteData = new MatchedRouteDataMap ( ) ; $ rootRouteData -> addRoute ( $ groupedRoutes [ 0 ] [ 0 ] , [ ] ) ; unset ( $ groupedRoutes [ 0 ] ) ; } foreach ( $ groupedRoutes as $ segmentDepth => $ group ) { $ groupNodes = [ ] ; foreach ( $ group as $ route ) { $ parameterIndexNameMap = [ ] ; $ segments = $ route -> getSegments ( ) ; $ segmentMatcher = $ this -> getMatcher ( \ array_shift ( $ segments ) , $ parameterIndexNameMap ) ; $ firstSegmentHash = $ segmentMatcher -> getHash ( ) ; if ( ! isset ( $ groupNodes [ $ firstSegmentHash ] ) ) { $ groupNodes [ $ firstSegmentHash ] = new RouteTreeNode ( [ 0 => $ segmentMatcher ] , $ segmentDepth === 1 ? new MatchedRouteDataMap ( ) : new ChildrenNodeCollection ( ) ) ; } $ this -> addRouteToNode ( $ groupNodes [ $ firstSegmentHash ] , $ route , $ segments , 1 , $ parameterIndexNameMap ) ; } $ nodes [ $ segmentDepth ] = new ChildrenNodeCollection ( $ groupNodes ) ; } return [ $ rootRouteData , $ nodes ] ; }

Creates a route tree from the supplied routes.

@param \Viserio\Component\Contract\Routing\Route[] $routes

@return array

Creates a route tree from the supplied routes .


private function addRouteToNode(
        RouteTreeNode $node,
        RouteContract $route,
        array $segments,
        int $segmentDepth,
        array $parameterIndexNameMap
    ): void {
        if (\count($segments) === 0) {
            $node->getContents()->addRoute($route, $parameterIndexNameMap);

            return;
        }

        $childSegmentMatcher = $this->getMatcher(\array_shift($segments), $parameterIndexNameMap);

        if ($node->getContents()->hasChildFor($childSegmentMatcher)) {
            $child = $node->getContents()->getChild($childSegmentMatcher);
        } else {
            $child = new RouteTreeNode(
                [$segmentDepth => $childSegmentMatcher],
                \count($segments) === 0 ? new MatchedRouteDataMap() : new ChildrenNodeCollection()
            );
            $node->getContents()->addChild($child);
        }

        $this->addRouteToNode($child, $route, $segments, $segmentDepth + 1, $parameterIndexNameMap);
    }

private function addRouteToNode ( RouteTreeNode $ node , RouteContract $ route , array $ segments , int $ segmentDepth , array $ parameterIndexNameMap ) : void { if ( \ count ( $ segments ) === 0 ) { $ node -> getContents ( ) -> addRoute ( $ route , $ parameterIndexNameMap ) ; return ; } $ childSegmentMatcher = $ this -> getMatcher ( \ array_shift ( $ segments ) , $ parameterIndexNameMap ) ; if ( $ node -> getContents ( ) -> hasChildFor ( $ childSegmentMatcher ) ) { $ child = $ node -> getContents ( ) -> getChild ( $ childSegmentMatcher ) ; } else { $ child = new RouteTreeNode ( [ $ segmentDepth => $ childSegmentMatcher ] , \ count ( $ segments ) === 0 ? new MatchedRouteDataMap ( ) : new ChildrenNodeCollection ( ) ) ; $ node -> getContents ( ) -> addChild ( $ child ) ; } $ this -> addRouteToNode ( $ child , $ route , $ segments , $ segmentDepth + 1 , $ parameterIndexNameMap ) ; }

Adds a route to the node tree.

@param \Viserio\Component\Routing\TreeGenerator\RouteTreeNode $node
@param \Viserio\Component\Contract\Routing\Route              $route
@param array                                                  $segments
@param int                                                    $segmentDepth
@param array                                                  $parameterIndexNameMap

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

@return void


private function getMatcher($firstSegment, array &$parameterIndexNameMap): SegmentMatcherContract
    {
        if ($firstSegment instanceof ParameterMatcher) {
            return $firstSegment->getMatcher($parameterIndexNameMap);
        }

        return $firstSegment;
    }

private function getMatcher ( $ firstSegment , array & $ parameterIndexNameMap ) : SegmentMatcherContract { if ( $ firstSegment instanceof ParameterMatcher ) { return $ firstSegment -> getMatcher ( $ parameterIndexNameMap ) ; } return $ firstSegment ; }

Get the right Matcher.

@param \Viserio\Component\Contract\Routing\SegmentMatcher|\Viserio\Component\Routing\Matcher\ParameterMatcher $firstSegment
@param array                                                                                $parameterIndexNameMap

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


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

        if ($container->has(CacheManagerContract::class)) {
            $manager->setCacheManager($container->get(CacheManagerContract::class));
        }

        return $manager;
    }

public static function createFilesystemManager ( ContainerInterface $ container ) : FilesystemManager { $ manager = new FilesystemManager ( $ container -> get ( 'config' ) ) ; if ( $ container -> has ( CacheManagerContract :: class ) ) { $ manager -> setCacheManager ( $ container -> get ( CacheManagerContract :: class ) ) ; } return $ manager ; }

Create a new FilesystemManager instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Filesystem\FilesystemManager

Create a new FilesystemManager instance .


public static function createCachedFactory(ContainerInterface $container): CachedFactory
    {
        $cache = null;

        if ($container->has(CacheManagerContract::class)) {
            $cache = $container->get(CacheManagerContract::class);
        }

        return new CachedFactory(
            $container->get(FilesystemManager::class),
            $cache
        );
    }

public static function createCachedFactory ( ContainerInterface $ container ) : CachedFactory { $ cache = null ; if ( $ container -> has ( CacheManagerContract :: class ) ) { $ cache = $ container -> get ( CacheManagerContract :: class ) ; } return new CachedFactory ( $ container -> get ( FilesystemManager :: class ) , $ cache ) ; }

Create a new CachedFactory instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Component\Filesystem\Cache\CachedFactory


public function getAccumulatedStatementsDuration(): int
    {
        return \array_reduce($this->executedStatements, static function ($v, $s) {
            return $v + $s->getDuration();
        });
    }

public function getAccumulatedStatementsDuration ( ) : int { return \ array_reduce ( $ this -> executedStatements , static function ( $ v , $ s ) { return $ v + $ s -> getDuration ( ) ; } ) ; }

Returns the accumulated execution time of statements.

@return int

Returns the accumulated execution time of statements .


public function getMemoryUsage(): int
    {
        return \array_reduce($this->executedStatements, static function ($v, $s) {
            return $v + $s->getMemoryUsage();
        });
    }

public function getMemoryUsage ( ) : int { return \ array_reduce ( $ this -> executedStatements , static function ( $ v , $ s ) { return $ v + $ s -> getMemoryUsage ( ) ; } ) ; }

Returns the peak memory usage while performing statements.

@return int

Returns the peak memory usage while performing statements .


protected function profileCall(string $method, string $sql, array $args)
    {
        $trace = new TracedStatement($sql);
        $trace->start();

        $ex     = null;
        $result = null;

        try {
            $result = $this->pdo->{$method}(...$args);
        } catch (PDOException $e) {
            $ex = $e;
        }

        if ($this->pdo->getAttribute(PDO::ATTR_ERRMODE) !== PDO::ERRMODE_EXCEPTION && $result === false) {
            $error = $this->pdo->errorInfo();
            $ex    = new PDOException($error[2], $error[0]);
        }

        $trace->end($ex);

        $this->addExecutedStatement($trace);

        if ($this->pdo->getAttribute(PDO::ATTR_ERRMODE) === PDO::ERRMODE_EXCEPTION && $ex !== null) {
            throw $ex;
        }

        return $result;
    }

protected function profileCall ( string $ method , string $ sql , array $ args ) { $ trace = new TracedStatement ( $ sql ) ; $ trace -> start ( ) ; $ ex = null ; $ result = null ; try { $ result = $ this -> pdo -> { $ method } ( ... $ args ) ; } catch ( PDOException $ e ) { $ ex = $ e ; } if ( $ this -> pdo -> getAttribute ( PDO :: ATTR_ERRMODE ) !== PDO :: ERRMODE_EXCEPTION && $ result === false ) { $ error = $ this -> pdo -> errorInfo ( ) ; $ ex = new PDOException ( $ error [ 2 ] , $ error [ 0 ] ) ; } $ trace -> end ( $ ex ) ; $ this -> addExecutedStatement ( $ trace ) ; if ( $ this -> pdo -> getAttribute ( PDO :: ATTR_ERRMODE ) === PDO :: ERRMODE_EXCEPTION && $ ex !== null ) { throw $ ex ; } return $ result ; }

Profiles a call to a PDO method.

@param string $method
@param string $sql
@param array  $args

@return mixed


public function resolve(string $alias): ?string
    {
        // Check wether the alias matches the pattern
        if (\preg_match($this->regex, $alias, $matches) !== 1) {
            return null;
        }

        // Get the translation
        $translation = $this->translation;

        if (\mb_strpos($translation, '$') === false) {
            $class = $translation;
        } else {
            // Make sure namespace seperators are escaped
            $translation = \str_replace('\\', '\\\\', $translation);
            // Resolve the replacement
            $class = \preg_replace($this->regex, $translation, $alias);
        }

        // Check wether the class exists
        if ($class && $this->exists($class, true)) {
            return $class;
        }

        return null;
    }

Resolves an alias.

@param string $alias

@return null|string


public function matches(string $pattern, string $translation = null): bool
    {
        return $this->pattern === $pattern && (! $translation || $translation === $this->translation);
    }

public function matches ( string $ pattern , string $ translation = null ) : bool { return $ this -> pattern === $ pattern && ( ! $ translation || $ translation === $ this -> translation ) ; }

Checks whether the resolver matches a given pattern and optional translation.

@param string      $pattern
@param null|string $translation

@return bool

Checks whether the resolver matches a given pattern and optional translation .


public static function createTwigEngine(ContainerInterface $container): TwigEngine
    {
        $engine = new TwigEngine($container->get(TwigEnvironment::class), $container->get('config'));
        $engine->setContainer($container);

        return $engine;
    }

public static function createTwigEngine ( ContainerInterface $ container ) : TwigEngine { $ engine = new TwigEngine ( $ container -> get ( TwigEnvironment :: class ) , $ container -> get ( 'config' ) ) ; $ engine -> setContainer ( $ container ) ; return $ engine ; }

Create a new twig engine instance.

@param \Psr\Container\ContainerInterface $container

@return \Viserio\Provider\Twig\Engine\TwigEngine


public static function extendViewFactory(
        ContainerInterface $container,
        ?FactoryContract $view = null
    ): ?FactoryContract {
        if ($view !== null) {
            // @var FactoryContract $view
            $view->addExtension('twig', 'twig');
        }

        return $view;
    }

public
static
function
extendViewFactory
(
ContainerInterface
$
container
,
FactoryContract
$
view
=
)
:
FactoryContract
{
if
(
$
view
!==
)
{
// @var FactoryContract $view
$
view
->
addExtension
(
'twig'
,
'twig'
)
;
}
return
$
view
;
}

Extend ViewFactory.

@param \Psr\Container\ContainerInterface             $container
@param null|\Viserio\Component\Contract\View\Factory $view

@return null|\Viserio\Component\Contract\View\Factory