public function get($id, $remove = false)
    {
        $self = $this;
        /** @var File $file */
        $file = null;
        $getPromise = $this->getArchiveFilePath($id, true)->then(
            function($filePath) use (&$file) {
                $file = \Reaction::$app->fs->file($filePath);
                return $file->exists()->then(
                    function() use (&$file) {
                        return $file->open('r');
                    }
                );
            }
        )->then(
            function($stream = null) use (&$file) {
                return $file->getContents();
            }
        )->then(
            function($dataStr) use ($self, &$file, $remove) {
                try {
                    $data = $self->getHandler()->unserializeData($dataStr);
                } catch (\InvalidArgumentException $exception) {
                    $data = null;
                }
                $data = is_array($data) ? $data : null;
                if ($remove) {
                    $callback = function() use ($data) { return $data; };
                    return $file->remove()->then($callback, $callback);
                }
                return $data;
            },
            function() use ($id) {
                $message = sprintf('Failed to restore session "%s"', $id);
                throw new SessionException($message);
            }
        );
        return resolve($getPromise);
    }

public
function
get
(
$
id
,
$
remove
=
false
)
{
$
self
=
$
this
;
/** @var File $file */
$
file
=
;
$
getPromise
=
$
this
->
getArchiveFilePath
(
$
id
,
true
)
->
then
(
function
(
$
filePath
)
use
(
&
$
file
)
{
$
file
=
\
Reaction
::
$
app
->
fs
->
file
(
$
filePath
)
;
return
$
file
->
exists
(
)
->
then
(
function
(
)
use
(
&
$
file
)
{
return
$
file
->
open
(
'r'
)
;
}
)
;
}
)
->
then
(
function
(
$
stream
=
)
use
(
&
$
file
)
{
return
$
file
->
getContents
(
)
;
}
)
->
then
(
function
(
$
dataStr
)
use
(
$
self
,
&
$
file
,
$
remove
)
{
try
{
$
data
=
$
self
->
getHandler
(
)
->
unserializeData
(
$
dataStr
)
;
}
catch
(
\
InvalidArgumentException
$
exception
)
{
$
data
=
;
}
$
data
=
is_array
(
$
data
)
$
data
:
;
if
(
$
remove
)
{
$
callback
=
function
(
)
use
(
$
data
)
{
return
$
data
;
}
;
return
$
file
->
remove
(
)
->
then
(
$
callback
,
$
callback
)
;
}
return
$
data
;
}
,
function
(
)
use
(
$
id
)
{
$
message
=
sprintf
(
'Failed to restore session "%s"'
,
$
id
)
;
throw
new
SessionException
(
$
message
)
;
}
)
;
return
resolve
(
$
getPromise
)
;
}

Get data from archive
@param string $id Session id
@param bool   $remove Flag to remove data
@return ExtendedPromiseInterface with data array


public function remove($id)
    {
        return $this->getArchiveFilePath($id, true)->then(
            function($filePath) {
                $file = \Reaction::$app->fs->file($filePath);
                return $file->remove();
            }
        );
    }

public function remove ( $ id ) { return $ this -> getArchiveFilePath ( $ id , true ) -> then ( function ( $ filePath ) { $ file = \ Reaction :: $ app -> fs -> file ( $ filePath ) ; return $ file -> remove ( ) ; } ) ; }

Remove from archive
@param string $id Session id
@return ExtendedPromiseInterface which resolved when process complete


protected function getArchivePath() {
        if (!isset($this->_archivePath)) {
            $this->_archivePath = \Reaction::$app->getAlias($this->archivePath);
            $path = \Reaction::$app->getAlias($this->archivePath);
            $self = $this;
            $fs = \Reaction::$app->fs;
            $dirAsFile = $fs->file($path);
            $pathPromise = $dirAsFile->exists()->then(
                null,
                function() use ($path) {
                    return FileHelperAsc::createDir($path, 0777, true);
                }
            )->then(
                function() use (&$self, $path) {
                    $self->_archivePath = $path;
                    return $path;
                },
                function() {
                    throw new SessionException("Failed to get session archive path");
                }
            );
            return resolve($pathPromise);
        }
        return resolve($this->_archivePath);
    }

protected
function
getArchivePath
(
)
{
if
(
!
isset
(
$
this
->
_archivePath
)
)
{
$
this
->
_archivePath
=
\
Reaction
::
$
app
->
getAlias
(
$
this
->
archivePath
)
;
$
path
=
\
Reaction
::
$
app
->
getAlias
(
$
this
->
archivePath
)
;
$
self
=
$
this
;
$
fs
=
\
Reaction
::
$
app
->
fs
;
$
dirAsFile
=
$
fs
->
file
(
$
path
)
;
$
pathPromise
=
$
dirAsFile
->
exists
(
)
->
then
(
,
function
(
)
use
(
$
path
)
{
return
FileHelperAsc
::
createDir
(
$
path
,
0777
,
true
)
;
}
)
->
then
(
function
(
)
use
(
&
$
self
,
$
path
)
{
$
self
->
_archivePath
=
$
path
;
return
$
path
;
}
,
function
(
)
{
throw
new
SessionException
(
"Failed to get session archive path"
)
;
}
)
;
return
resolve
(
$
pathPromise
)
;
}
return
resolve
(
$
this
->
_archivePath
)
;
}

Get archive path
@return ExtendedPromiseInterface with string


protected function getArchiveFilePath($id, $existCheck = false)
    {
        $fileName = $id . '.json';
        return $this->getArchivePath()->then(
            function($dirPath) use ($fileName) {
                return rtrim($dirPath) . DIRECTORY_SEPARATOR . $fileName;
            }
        )->then(
            function($filePath) use ($existCheck) {
                if ($existCheck) {
                    return \Reaction::$app->fs->file($filePath)->exists()->then(
                        function() use ($filePath) {
                            return $filePath;
                        }
                    );
                }
                return resolve($filePath);
            }
        );
    }

protected function getArchiveFilePath ( $ id , $ existCheck = false ) { $ fileName = $ id . '.json' ; return $ this -> getArchivePath ( ) -> then ( function ( $ dirPath ) use ( $ fileName ) { return rtrim ( $ dirPath ) . DIRECTORY_SEPARATOR . $ fileName ; } ) -> then ( function ( $ filePath ) use ( $ existCheck ) { if ( $ existCheck ) { return \ Reaction :: $ app -> fs -> file ( $ filePath ) -> exists ( ) -> then ( function ( ) use ( $ filePath ) { return $ filePath ; } ) ; } return resolve ( $ filePath ) ; } ) ; }

Get session archive file path
@param string $id Session id
@param bool   $existCheck
@return ExtendedPromiseInterface


public static function cleanupMergedValues($array = []) {
        if (!is_array($array)) {
            return $array;
        }
        foreach ($array as $key => $value) {
            if($value instanceof IgnoreArrayValue || $value instanceof ReplaceArrayValue) {
                $array[$key] = $value->value;
            } elseif ($value instanceof UnsetArrayValue) {
                unset($array[$key]);
            } elseif (is_array($value)) {
                $array[$key] = static::cleanupMergedValues($value);
            }
        }

        return $array;
    }

public static function cleanupMergedValues ( $ array = [ ] ) { if ( ! is_array ( $ array ) ) { return $ array ; } foreach ( $ array as $ key => $ value ) { if ( $ value instanceof IgnoreArrayValue || $ value instanceof ReplaceArrayValue ) { $ array [ $ key ] = $ value -> value ; } elseif ( $ value instanceof UnsetArrayValue ) { unset ( $ array [ $ key ] ) ; } elseif ( is_array ( $ value ) ) { $ array [ $ key ] = static :: cleanupMergedValues ( $ value ) ; } } return $ array ; }

Cleanup merged array values from instances of IgnoreArrayValue, ReplaceArrayValue, UnsetArrayValue
@param array $array
@return array
@internal

Cleanup merged array values from instances of IgnoreArrayValue ReplaceArrayValue UnsetArrayValue


public static function filter($array, $filters)
    {
        $result = [];
        $forbiddenVars = [];

        foreach ($filters as $filter) {
            static::applyArrayFilter($array, $filter, $result, $forbiddenVars);
        }

        foreach ($forbiddenVars as $var) {
            list($globalKey, $localKey) = $var;
            if (array_key_exists($globalKey, $result)) {
                unset($result[$globalKey][$localKey]);
            }
        }

        return $result;
    }

public static function filter ( $ array , $ filters ) { $ result = [ ] ; $ forbiddenVars = [ ] ; foreach ( $ filters as $ filter ) { static :: applyArrayFilter ( $ array , $ filter , $ result , $ forbiddenVars ) ; } foreach ( $ forbiddenVars as $ var ) { list ( $ globalKey , $ localKey ) = $ var ; if ( array_key_exists ( $ globalKey , $ result ) ) { unset ( $ result [ $ globalKey ] [ $ localKey ] ) ; } } return $ result ; }

Filters array according to rules specified.

For example:

```php
$array = [
'A' => [1, 2],
'B' => [
'C' => 1,
'D' => 2,
],
'E' => 1,
];

$result = \Reaction\Helpers\ArrayHelper::filter($array, ['A']);
// $result will be:
// [
//     'A' => [1, 2],
// ]

$result = \Reaction\Helpers\ArrayHelper::filter($array, ['A', 'B.C']);
// $result will be:
// [
//     'A' => [1, 2],
//     'B' => ['C' => 1],
// ]

$result = \Reaction\Helpers\ArrayHelper::filter($array, ['B', '!B.C']);
// $result will be:
// [
//     'B' => ['D' => 2],
// ]
```

@param array $array Source array
@param array $filters Rules that define array keys which should be left or removed from results.
Each rule is:
- `var` - `$array['var']` will be left in result.
- `var.key` = only `$array['var']['key'] will be left in result.
- `!var.key` = `$array['var']['key'] will be removed from result.
@return array Filtered array

Filters array according to rules specified .


function it_should_return_terminal_screen_size()
    {
        self::getTerminalSizes()->shouldBeArray();
        self::getTerminalSizes()->shouldHaveKey("width");
        self::getTerminalSizes()->shouldHaveKey("height");
        self::getTerminalSizes()->shouldHaveCount(2);
    }

function it_should_return_terminal_screen_size ( ) { self :: getTerminalSizes ( ) -> shouldBeArray ( ) ; self :: getTerminalSizes ( ) -> shouldHaveKey ( "width" ) ; self :: getTerminalSizes ( ) -> shouldHaveKey ( "height" ) ; self :: getTerminalSizes ( ) -> shouldHaveCount ( 2 ) ; }

It should return an array with terminal screen sizes


public function style($content, $options = [], $encoding = null)
    {
        return $this->proxyWithCharset(__FUNCTION__, [$content, $options, $encoding]);
    }

public function style ( $ content , $ options = [ ] , $ encoding = null ) { return $ this -> proxyWithCharset ( __FUNCTION__ , [ $ content , $ options , $ encoding ] ) ; }

Generates a style tag.
@param string $content the style content
@param array  $options the tag options in terms of name-value pairs. These will be rendered as
the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
If a value is null, the corresponding attribute will not be rendered.
See [[renderTagAttributes()]] for details on how attributes are being rendered.
@param string $encoding
@return string the generated style tag
@see Html::style()


public function script($content, $options = [], $encoding = null)
    {
        return $this->proxyWithCharset(__FUNCTION__, [$content, $options, $encoding]);
    }

public function script ( $ content , $ options = [ ] , $ encoding = null ) { return $ this -> proxyWithCharset ( __FUNCTION__ , [ $ content , $ options , $ encoding ] ) ; }

Generates a script tag.
@param string $content the script content
@param array $options the tag options in terms of name-value pairs. These will be rendered as
the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
If a value is null, the corresponding attribute will not be rendered.
See [[renderTagAttributes()]] for details on how attributes are being rendered.
@param string $encoding
@return string the generated script tag
@see Html::script()


public function mailto($text, $email = null, $options = [], $encoding = null)
    {
        $this->ensureTranslated($text);
        $this->ensureTranslated($email);
        return $this->proxyWithCharset(__FUNCTION__, [$text, $email, $options, $encoding]);
    }

public function mailto ( $ text , $ email = null , $ options = [ ] , $ encoding = null ) { $ this -> ensureTranslated ( $ text ) ; $ this -> ensureTranslated ( $ email ) ; return $ this -> proxyWithCharset ( __FUNCTION__ , [ $ text , $ email , $ options , $ encoding ] ) ; }

Generates a mailto hyperlink.
@param string $text link body. It will NOT be HTML-encoded. Therefore you can pass in HTML code
such as an image tag. If this is coming from end users, you should consider [[encode()]]
it to prevent XSS attacks.
@param string $email email address. If this is null, the first parameter (link body) will be treated
as the email address and used.
@param array  $options the tag options in terms of name-value pairs. These will be rendered as
the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
If a value is null, the corresponding attribute will not be rendered.
See [[renderTagAttributes()]] for details on how attributes are being rendered.
@param string $encoding
@return string the generated mailto link
@see Html::mailto()


public function staticControl($value, $options = [])
    {
        $this->ensureTranslated($value);
        return $this->proxy(__FUNCTION__, [$value, $options]);
    }

public function staticControl ( $ value , $ options = [ ] ) { $ this -> ensureTranslated ( $ value ) ; return $ this -> proxy ( __FUNCTION__ , [ $ value , $ options ] ) ; }

Renders Bootstrap static form control.

By default value will be HTML-encoded using [[encode()]], you may control this behavior
via 'encode' option.
@param string $value static control value.
@param array $options the tag options in terms of name-value pairs. These will be rendered as
the attributes of the resulting tag. There are also a special options:

- encode: boolean, whether value should be HTML-encoded or not.

@return string generated HTML
@see http://getbootstrap.com/css/#forms-controls-static
@see Html::staticControl()


public function activeStaticControl($model, $attribute, $options = [])
    {
        if (isset($options['value'])) {
            $this->ensureTranslated($options['value']);
        }
        return $this->proxy(__FUNCTION__, [$model, $attribute, $options]);
    }

public function activeStaticControl ( $ model , $ attribute , $ options = [ ] ) { if ( isset ( $ options [ 'value' ] ) ) { $ this -> ensureTranslated ( $ options [ 'value' ] ) ; } return $ this -> proxy ( __FUNCTION__ , [ $ model , $ attribute , $ options ] ) ; }

Generates a Bootstrap static form control for the given model attribute.
@param \Reaction\Base\Model $model the model object.
@param string $attribute the attribute name or expression. See [[getAttributeName()]] for the format
about attribute expression.
@param array $options the tag options in terms of name-value pairs. See [[staticControl()]] for details.
@return string generated HTML
@see staticControl()
@see Html::activeStaticControl()

Generates a Bootstrap static form control for the given model attribute .


public function addCssStyle(&$options, $style, $overwrite = true)
    {
        $this->proxy(__FUNCTION__, [&$options, $style, $overwrite]);
    }

public function addCssStyle ( & $ options , $ style , $ overwrite = true ) { $ this -> proxy ( __FUNCTION__ , [ & $ options , $ style , $ overwrite ] ) ; }

Adds the specified CSS style to the HTML options.

If the options already contain a `style` element, the new style will be merged
with the existing one. If a CSS property exists in both the new and the old styles,
the old one may be overwritten if `$overwrite` is true.

For example,

```php
Html::addCssStyle($options, 'width: 100px; height: 200px');
```

@param array $options the HTML options to be modified.
@param string|array $style the new style string (e.g. `'width: 100px; height: 200px'`) or
array (e.g. `['width' => '100px', 'height' => '200px']`).
@param bool $overwrite whether to overwrite existing CSS properties if the new style
contain them too.
@see removeCssStyle()
@see cssStyleFromArray()
@see cssStyleToArray()
@see Html::addCssStyle()

Adds the specified CSS style to the HTML options .


protected function makeDirectory()
	{
		$path = $this->getPath();

		if( ! $this->filesystem()->isDirectory($path))
		{
			$this->filesystem()->makeDirectory($path, 0755, true);
		}

		return $this;
	}

protected function makeDirectory ( ) { $ path = $ this -> getPath ( ) ; if ( ! $ this -> filesystem ( ) -> isDirectory ( $ path ) ) { $ this -> filesystem ( ) -> makeDirectory ( $ path , 0755 , true ) ; } return $ this ; }

Create destination path if it does not exist

@return $this


public function filesToPublish($path)
	{
		$fs = $this->filesystem();
		if( ! $fs->exists($path) && ! $fs->isDirectory($path))
		{
			throw new \InvalidArgumentException("$path set to be published in does not exist.");
		}
		if($fs->isDirectory($path))
		{
			$this->files = $fs->allFiles($path);
		} else
		{
			$this->files = [$path];
		}

		return $this;
	}

Define what files needs to be published

@param  string $path
@return self


public function init()
    {
        parent::init();

        if ($this->identityClass === null) {
            throw new InvalidConfigException('User::identityClass must be set.');
        }
        if ($this->enableAutoLogin && !isset($this->identityCookie['name'])) {
            throw new InvalidConfigException('User::identityCookie must contain the "name" element.');
        }
        if (!empty($this->accessChecker) && is_string($this->accessChecker)) {
            $this->accessChecker = Reaction::create($this->accessChecker);
        }
    }

Initializes the application component.
@throws InvalidConfigException


public function login(IdentityInterface $identity, $duration = 0)
    {
        //Using root resolve function for promise conversion
        return resolve(true)
            ->then(function() use (&$identity, $duration) {
                return $this->beforeLogin($identity, false, $duration);
            })->then(function() use (&$identity, $duration) {
                $this->switchIdentity($identity, $duration);
                $id = $identity->getId();
                $ip = $this->request->getUserIP();
                if ($this->enableSession) {
                    $log = "User '$id' logged in from $ip with duration $duration.";
                } else {
                    $log = "User '$id' logged in from $ip. Session not enabled.";
                }

                $this->regenerateCsrfToken();

                if (Reaction::isDebug()) {
                    Reaction::info($log);
                }
                return $this->afterLogin($identity, false, $duration);
            });
    }

Logs in a user.

After logging in a user:
- the user's identity information is obtainable from the [[identity]] property

If [[enableSession]] is `true`:
- the identity information will be stored in session and be available in the next requests
- in case of `$duration == 0`: as long as the session remains active or till the user closes the browser
- in case of `$duration > 0`: as long as the session remains active or as long as the cookie
remains valid by it's `$duration` in seconds when [[enableAutoLogin]] is set `true`.

If [[enableSession]] is `false`:
- the `$duration` parameter will be ignored

@param IdentityInterface $identity the user identity (which should already be authenticated)
@param int $duration number of seconds that the user can remain in logged-in status, defaults to `0`
@return ExtendedPromiseInterface with bool whether the user is logged in


protected function regenerateCsrfToken()
    {
        $request = $this->request;
        if ($request->enableCsrfCookie || $this->enableSession) {
            $request->getCsrfToken(true);
        }
    }

protected function regenerateCsrfToken ( ) { $ request = $ this -> request ; if ( $ request -> enableCsrfCookie || $ this -> enableSession ) { $ request -> getCsrfToken ( true ) ; } }


protected function loginByCookie()
    {
        return $this->getIdentityAndDurationFromCookie()
            ->then(function($data) {
                if (isset($data['identity'], $data['duration'])) {
                    /** @var IdentityInterface $identity */
                    $identity = $data['identity'];
                    $duration = $data['duration'];
                    return $this->beforeLogin($identity, true, $duration)
                        ->then(function() use (&$identity, $duration) {
                            $this->switchIdentity($identity, $this->autoRenewCookie ? $duration : 0);
                            $id = $identity->getId();
                            $ip = $this->request->getUserIP();
                            Reaction::info("User '$id' logged in from $ip via cookie.");
                            return $this->afterLogin($identity, true, $duration);
                        });
                } else {
                    return reject(new Error("Invalid cookie value or user identity"));
                }
            });
    }

Logs in a user by cookie.

This method attempts to log in a user using the ID and authKey information
provided by the [[identityCookie|identity cookie]].
@return ExtendedPromiseInterface


public function getReturnUrl($defaultUrl = null)
    {
        $url = $this->app->session->get($this->returnUrlParam, $defaultUrl);
        if (is_array($url)) {
            if (isset($url[0])) {
                return $this->app->urlManager->createUrl($url);
            }

            $url = null;
        }

        return $url === null ? $this->app->urlManager->getHomeUrl() : $url;
    }

public function getReturnUrl ( $ defaultUrl = null ) { $ url = $ this -> app -> session -> get ( $ this -> returnUrlParam , $ defaultUrl ) ; if ( is_array ( $ url ) ) { if ( isset ( $ url [ 0 ] ) ) { return $ this -> app -> urlManager -> createUrl ( $ url ) ; } $ url = null ; } return $ url === null ? $ this -> app -> urlManager -> getHomeUrl ( ) : $ url ; }

Returns the URL that the browser should be redirected to after successful login.

This method reads the return URL from the session. It is usually used by the login action which
may call this method to redirect the browser to where it goes after successful authentication.

@param string|array $defaultUrl the default return URL in case it was not set previously.
If this is null and the return URL was not set previously, [[Application::homeUrl]] will be redirected to.
Please refer to [[setReturnUrl()]] on accepted format of the URL.
@return string the URL that the user should be redirected to after login.
@see loginRequired()

Returns the URL that the browser should be redirected to after successful login .


public function loginRequired($checkAjax = true, $checkAcceptHeader = true)
    {
        $request = $this->request;
        $canRedirect = !$checkAcceptHeader || $this->checkRedirectAcceptable();
        if ($this->enableSession
            && $request->getIsGet()
            && (!$checkAjax || !$request->getIsAjax())
            && $canRedirect
        ) {
            $this->setReturnUrl($request->getUrl());
        }
        if ($this->loginUrl !== null && $canRedirect) {
            $loginUrl = (array)$this->loginUrl;
            if ($loginUrl[0] !== $this->app->getRoute()->getRoutePath(true)) {
                return $this->app->response->redirect($this->loginUrl);
            }
        }
        throw new ForbiddenException(Reaction::t('rct', 'Login Required'));
    }

public
function
loginRequired
(
$
checkAjax
=
true
,
$
checkAcceptHeader
=
true
)
{
$
request
=
$
this
->
request
;
$
canRedirect
=
!
$
checkAcceptHeader
||
$
this
->
checkRedirectAcceptable
(
)
;
if
(
$
this
->
enableSession
&&
$
request
->
getIsGet
(
)
&&
(
!
$
checkAjax
||
!
$
request
->
getIsAjax
(
)
)
&&
$
canRedirect
)
{
$
this
->
setReturnUrl
(
$
request
->
getUrl
(
)
)
;
}
if
(
$
this
->
loginUrl
!==
&&
$
canRedirect
)
{
$
loginUrl
=
(
array
)
$
this
->
loginUrl
;
if
(
$
loginUrl
[
0
]
!==
$
this
->
app
->
getRoute
(
)
->
getRoutePath
(
true
)
)
{
return
$
this
->
app
->
response
->
redirect
(
$
this
->
loginUrl
)
;
}
}
throw
new
ForbiddenException
(
Reaction
::
t
(
'rct'
,
'Login Required'
)
)
;
}

Redirects the user browser to the login page.

Before the redirection, the current URL (if it's not an AJAX url) will be kept as [[returnUrl]] so that
the user browser may be redirected back to the current page after successful login.

Make sure you set [[loginUrl]] so that the user browser can be redirected to the specified login URL after
calling this method.

Note that when [[loginUrl]] is set, calling this method will NOT terminate the application execution.

@param bool $checkAjax whether to check if the request is an AJAX request. When this is true and the request
is an AJAX request, the current URL (for AJAX request) will NOT be set as the return URL.
@param bool $checkAcceptHeader whether to check if the request accepts HTML responses. Defaults to `true`. When this is true and
the request does not accept HTML responses the current URL will not be SET as the return URL. Also instead of
redirecting the user an ForbiddenHttpException is thrown. This parameter is available since version 2.0.8.
@return ResponseBuilderInterface the redirection response if [[loginUrl]] is set
@throws ForbiddenException the "Access Denied" HTTP exception if [[loginUrl]] is not set or a redirect is
not applicable.

Redirects the user browser to the login page .


protected function renewIdentityCookie()
    {
        $name = $this->identityCookie['name'];
        $value = $this->request->getCookies()->getValue($name);
        if ($value !== null) {
            $data = json_decode($value, true);
            if (is_array($data) && isset($data[2])) {
                $cookie = Reaction::create(array_merge($this->identityCookie, [
                    'class' => 'Reaction\Web\Cookie',
                    'value' => $value,
                    'expire' => time() + (int)$data[2],
                ]));
                $this->app->response->getCookies()->add($cookie);
            }
        }
    }

protected function renewIdentityCookie ( ) { $ name = $ this -> identityCookie [ 'name' ] ; $ value = $ this -> request -> getCookies ( ) -> getValue ( $ name ) ; if ( $ value !== null ) { $ data = json_decode ( $ value , true ) ; if ( is_array ( $ data ) && isset ( $ data [ 2 ] ) ) { $ cookie = Reaction :: create ( array_merge ( $ this -> identityCookie , [ 'class' => 'Reaction\Web\Cookie' , 'value' => $ value , 'expire' => time ( ) + ( int ) $ data [ 2 ] , ] ) ) ; $ this -> app -> response -> getCookies ( ) -> add ( $ cookie ) ; } } }

Renews the identity cookie.
This method will set the expiration time of the identity cookie to be the current time
plus the originally specified cookie duration.

Renews the identity cookie . This method will set the expiration time of the identity cookie to be the current time plus the originally specified cookie duration .


protected function renewAuthStatus()
    {
        $session = $this->app->session;
        $id = $session->getHasSessionId() || $session->getIsActive() ? $session->get($this->idParam) : null;

        if ($id === null) {
            $identityPromise = resolve(null);
        } else {
            /* @var $class IdentityInterface */
            $class = $this->identityClass;
            $identityPromise = $class::findIdentity($id);
        }

        return $identityPromise
            ->then(function($identity) use ($session) {
                /** @var IdentityInterface $identity */
                $this->setIdentity($identity);

                $logoutPromise = resolve(true);
                if ($identity !== null && ($this->authTimeout !== null || $this->absoluteAuthTimeout !== null)) {
                    $expire = $this->authTimeout !== null ? $session->get($this->authTimeoutParam) : null;
                    $expireAbsolute = $this->absoluteAuthTimeout !== null ? $session->get($this->absoluteAuthTimeoutParam) : null;
                    if ($expire !== null && $expire < time() || $expireAbsolute !== null && $expireAbsolute < time()) {
                        $logoutPromise = $this->logout(false);
                    } elseif ($this->authTimeout !== null) {
                        $session->set($this->authTimeoutParam, time() + $this->authTimeout);
                    }
                }

                return $logoutPromise->then(function() {
                    if ($this->enableAutoLogin) {
                        if ($this->getIsGuest()) {
                            return $this->loginByCookie();
                        } elseif ($this->autoRenewCookie) {
                            $this->renewIdentityCookie();
                        }
                    }
                    return true;
                });
            });
    }

protected
function
renewAuthStatus
(
)
{
$
session
=
$
this
->
app
->
session
;
$
id
=
$
session
->
getHasSessionId
(
)
||
$
session
->
getIsActive
(
)
$
session
->
get
(
$
this
->
idParam
)
:
;
if
(
$
id
===
)
{
$
identityPromise
=
resolve
(
)
;
}
else
{
/* @var $class IdentityInterface */
$
class
=
$
this
->
identityClass
;
$
identityPromise
=
$
class
::
findIdentity
(
$
id
)
;
}
return
$
identityPromise
->
then
(
function
(
$
identity
)
use
(
$
session
)
{
/** @var IdentityInterface $identity */
$
this
->
setIdentity
(
$
identity
)
;
$
logoutPromise
=
resolve
(
true
)
;
if
(
$
identity
!==
&&
(
$
this
->
authTimeout
!==
||
$
this
->
absoluteAuthTimeout
!==
)
)
{
$
expire
=
$
this
->
authTimeout
!==
$
session
->
get
(
$
this
->
authTimeoutParam
)
:
;
$
expireAbsolute
=
$
this
->
absoluteAuthTimeout
!==
$
session
->
get
(
$
this
->
absoluteAuthTimeoutParam
)
:
;
if
(
$
expire
!==
&&
$
expire
<
time
(
)
||
$
expireAbsolute
!==
&&
$
expireAbsolute
<
time
(
)
)
{
$
logoutPromise
=
$
this
->
logout
(
false
)
;
}
elseif
(
$
this
->
authTimeout
!==
)
{
$
session
->
set
(
$
this
->
authTimeoutParam
,
time
(
)
+
$
this
->
authTimeout
)
;
}
}
return
$
logoutPromise
->
then
(
function
(
)
{
if
(
$
this
->
enableAutoLogin
)
{
if
(
$
this
->
getIsGuest
(
)
)
{
return
$
this
->
loginByCookie
(
)
;
}
elseif
(
$
this
->
autoRenewCookie
)
{
$
this
->
renewIdentityCookie
(
)
;
}
}
return
true
;
}
)
;
}
)
;
}

Updates the authentication status using the information from session and cookie.

This method will try to determine the user identity using the [[idParam]] session variable.

If [[authTimeout]] is set, this method will refresh the timer.

If the user identity cannot be determined by session, this method will try to [[loginByCookie()|login by cookie]]
if [[enableAutoLogin]] is true.
@return ExtendedPromiseInterface

Updates the authentication status using the information from session and cookie .


public function can($permissionName, $params = [], $allowCaching = true)
    {
        //Special permissions for logged in status handling
        if (in_array($permissionName, [static::PERMISSION_NOT_LOGGED_IN, static::PERMISSION_LOGGED_IN])) {
            $isGuest = $this->getIsGuest();
            if ($isGuest && static::PERMISSION_NOT_LOGGED_IN || !$isGuest && static::PERMISSION_LOGGED_IN) {
                return resolve(true);
            }
            return reject(new Error("Uses::can() - denied by logged in status"));
        }
        if ($allowCaching && empty($params) && isset($this->_access[$permissionName])) {
            return $this->_access[$permissionName]
                ? resolve(true)
                : reject(new Error("Uses::can() - denied"));
        }
        if (($accessChecker = $this->getAccessChecker()) === null) {
            return reject(new Error("Uses::can() - denied (no access checker)"));
        }
        return $accessChecker->checkAccess($this->getId(), $permissionName, $params)
            ->otherwise(function() {
                return false;
            })
            ->then(function($access) use ($allowCaching, $permissionName) {
                if ($allowCaching && empty($params)) {
                    $this->_access[$permissionName] = $access;
                }
                return $access ? resolve(true) : reject(new Error("Uses::can() - denied"));
            });
    }

Checks if the user can perform the operation as specified by the given permission.

Note that you must configure "authManager" application component in order to use this method.
Otherwise it will always return false.

@param string $permissionName the name of the permission (e.g. "edit post") that needs access check.
@param array $params name-value pairs that would be passed to the rules associated
with the roles and permissions assigned to the user.
@param bool $allowCaching whether to allow caching the result of access check.
When this parameter is true (default), if the access check of an operation was performed
before, its result will be directly returned when calling this method to check the same
operation. If this parameter is false, this method will always call
[[\Reaction\Rbac\CheckAccessInterface::checkAccess()]] to obtain the up-to-date access result. Note that this
caching is effective only within the same request and only works when `$params = []`.
@return ExtendedPromiseInterface with bool whether the user can perform the operation as specified by the given permission.

Checks if the user can perform the operation as specified by the given permission .


public static function getDaysOfWeek(): array
    {
        return [
            self::WEEK_DAY_MONDAY,
            self::WEEK_DAY_TUESDAY,
            self::WEEK_DAY_WEDNESDAY,
            self::WEEK_DAY_THURSDAY,
            self::WEEK_DAY_FRIDAY,
            self::WEEK_DAY_SATURDAY,
            self::WEEK_DAY_SUNDAY,
        ];
    }

public static function getDaysOfWeek ( ) : array { return [ self :: WEEK_DAY_MONDAY , self :: WEEK_DAY_TUESDAY , self :: WEEK_DAY_WEDNESDAY , self :: WEEK_DAY_THURSDAY , self :: WEEK_DAY_FRIDAY , self :: WEEK_DAY_SATURDAY , self :: WEEK_DAY_SUNDAY , ] ; }

Get the days of week.

@return integer[]


public function save($dir, $filename = null)
    {
        // clean
        $dir = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
        if(!$filename) {
            $filename = $this->name;
        }

        return move_uploaded_file($this->tmp, $dir . $filename);
    }

public
function
save
(
$
dir
,
$
filename
=
)
{
// clean
$
dir
=
rtrim
(
$
dir
,
DIRECTORY_SEPARATOR
)
.
DIRECTORY_SEPARATOR
;
if
(
!
$
filename
)
{
$
filename
=
$
this
->
name
;
}
return
move_uploaded_file
(
$
this
->
tmp
,
$
dir
.
$
filename
)
;
}

Save file to directory

@param string $dir
@param string $filename

@return bool


public function execute()
    {
        if ($this->type == self::SELECT) {
            return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes);
        } else {
            return $this->connection->executeUpdate($this->getSQL(), $this->params, $this->paramTypes);
        }
    }

public function execute ( ) { if ( $ this -> type == self :: SELECT ) { return $ this -> connection -> executeQuery ( $ this -> getSQL ( ) , $ this -> params , $ this -> paramTypes ) ; } else { return $ this -> connection -> executeUpdate ( $ this -> getSQL ( ) , $ this -> params , $ this -> paramTypes ) ; } }

Executes this query using the bound parameters and their types.

Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
for insert, update and delete statements.

@return \Doctrine\DBAL\Driver\Statement|int

Executes this query using the bound parameters and their types .


public function delete($delete = null, $alias = null)
    {
        $this->type = self::DELETE;

        if (!$delete) {
            return $this;
        }

        return $this->add('from', array(
            'table' => $delete,
            'alias' => $alias
        ));
    }

public function delete ( $ delete = null , $ alias = null ) { $ this -> type = self :: DELETE ; if ( ! $ delete ) { return $ this ; } return $ this -> add ( 'from' , array ( 'table' => $ delete , 'alias' => $ alias ) ) ; }

Turns the query being built into a bulk delete query that ranges over
a certain table.

<code>
$qb = $conn->createQueryBuilder()
->delete('users', 'u')
->where('u.id = :user_id');
->setParameter(':user_id', 1);
</code>

@param string $delete The table whose rows are subject to the deletion.
@param string $alias The table alias used in the constructed query.

@return \Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.

Turns the query being built into a bulk delete query that ranges over a certain table .


public function insert($insert = null)
    {
        $this->type = self::INSERT;

        if (!$insert) {
            return $this;
        }

        return $this->add('from', array(
            'table' => $insert
        ));
    }

public function insert ( $ insert = null ) { $ this -> type = self :: INSERT ; if ( ! $ insert ) { return $ this ; } return $ this -> add ( 'from' , array ( 'table' => $ insert ) ) ; }

Turns the query being built into an insert query that inserts into
a certain table

<code>
$qb = $conn->createQueryBuilder()
->insert('users')
->values(
array(
'name' => '?',
'password' => '?'
)
);
</code>

@param string $insert The table into which the rows should be inserted.

@return QueryBuilder This QueryBuilder instance.


public function innerJoin($fromAlias, $join, $alias, $condition = null)
    {
        return $this->add('join', array(
            $fromAlias => array(
                'joinType' => 'inner',
                'joinTable' => $join,
                'joinAlias' => $alias,
                'joinCondition' => $condition
            )
        ), true);
    }

public function innerJoin ( $ fromAlias , $ join , $ alias , $ condition = null ) { return $ this -> add ( 'join' , array ( $ fromAlias => array ( 'joinType' => 'inner' , 'joinTable' => $ join , 'joinAlias' => $ alias , 'joinCondition' => $ condition ) ) , true ) ; }

Creates and adds a join to the query.

<code>
$qb = $conn->createQueryBuilder()
->select('u.name')
->from('users', 'u')
->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
</code>

@param string $fromAlias The alias that points to a from clause.
@param string $join The table name to join.
@param string $alias The alias of the join table.
@param string $condition The condition for the join.

@return \Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.


public function where($predicates)
    {
        if (!(func_num_args() == 1 && $predicates instanceof CompositeExpression)) {
            $predicates = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
        }

        return $this->add('where', $predicates);
    }

public function where ( $ predicates ) { if ( ! ( func_num_args ( ) == 1 && $ predicates instanceof CompositeExpression ) ) { $ predicates = new CompositeExpression ( CompositeExpression :: TYPE_AND , func_get_args ( ) ) ; } return $ this -> add ( 'where' , $ predicates ) ; }

Specifies one or more restrictions to the query result.
Replaces any previously specified restrictions, if any.

<code>
$qb = $conn->createQueryBuilder()
->select('u.name')
->from('users', 'u')
->where('u.id = ?');

// You can optionally programatically build and/or expressions
$qb = $conn->createQueryBuilder();

$or = $qb->expr()->orx();
$or->add($qb->expr()->eq('u.id', 1));
$or->add($qb->expr()->eq('u.id', 2));

$qb->update('users', 'u')
->set('u.password', md5('password'))
->where($or);
</code>

@param mixed $predicates The restriction predicates.

@return \Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.

Specifies one or more restrictions to the query result . Replaces any previously specified restrictions if any .


public function having($having)
    {
        if (!(func_num_args() == 1 && $having instanceof CompositeExpression)) {
            $having = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
        }

        return $this->add('having', $having);
    }

public function having ( $ having ) { if ( ! ( func_num_args ( ) == 1 && $ having instanceof CompositeExpression ) ) { $ having = new CompositeExpression ( CompositeExpression :: TYPE_AND , func_get_args ( ) ) ; } return $ this -> add ( 'having' , $ having ) ; }

Specifies a restriction over the groups of the query.
Replaces any previous having restrictions, if any.

@param mixed $having The restriction over the groups.

@return \Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.

Specifies a restriction over the groups of the query . Replaces any previous having restrictions if any .


private function getSQLForDelete()
    {
        $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
        $query = 'DELETE FROM ' . $table . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string)$this->sqlParts['where']) : '');

        return $query;
    }

private
function
getSQLForDelete
(
)
{
$
table
=
$
this
->
sqlParts
[
'from'
]
[
'table'
]
.
(
$
this
->
sqlParts
[
'from'
]
[
'alias'
]
' '
.
$
this
->
sqlParts
[
'from'
]
[
'alias'
]
:
''
)
;
$
query
=
'DELETE FROM '
.
$
table
.
(
$
this
->
sqlParts
[
'where'
]
!==
' WHERE '
.
(
(
string
)
$
this
->
sqlParts
[
'where'
]
)
:
''
)
;
return
$
query
;
}

Converts this instance into a DELETE string in SQL.

@return string

Converts this instance into a DELETE string in SQL .


public function createPositionalParameter($value, $type = \PDO::PARAM_STR)
    {
        $this->boundCounter++;
        $this->setParameter($this->boundCounter, $value, $type);

        return "?";
    }

public function createPositionalParameter ( $ value , $ type = \ PDO :: PARAM_STR ) { $ this -> boundCounter ++ ; $ this -> setParameter ( $ this -> boundCounter , $ value , $ type ) ; return "?" ; }

Creates a new positional parameter and bind the given value to it.

Attention: If you are using positional parameters with the query builder you have
to be very careful to bind all parameters in the order they appear in the SQL
statement , otherwise they get bound in the wrong order which can lead to serious
bugs in your code.

Example:
<code>
$qb = $conn->createQueryBuilder();
$qb->select('u.*')
->from('users', 'u')
->where('u.username = ' . $qb->createPositionalParameter('Foo', PDO::PARAM_STR))
->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', PDO::PARAM_STR))
</code>

@param mixed $value
@param integer $type

@return string

Creates a new positional parameter and bind the given value to it .


protected static function bindLoggerInterface(Application $app): void
    {
        $handler = new StreamHandler(
            $app->config()['logger']['filePath'],
            LogLevel::DEBUG
        );

        $app->container()->singleton(
            LoggerInterface::class,
            new Monolog(
                $app->config()['logger']['name'],
                [
                    $handler,
                ]
            )
        );
    }

protected static function bindLoggerInterface ( Application $ app ) : void { $ handler = new StreamHandler ( $ app -> config ( ) [ 'logger' ] [ 'filePath' ] , LogLevel :: DEBUG ) ; $ app -> container ( ) -> singleton ( LoggerInterface :: class , new Monolog ( $ app -> config ( ) [ 'logger' ] [ 'name' ] , [ $ handler , ] ) ) ; }

Bind the logger interface.

@param Application $app The application

@throws \Exception

@return void


protected static function bindLogger(Application $app): void
    {
        $app->container()->singleton(
            Logger::class,
            new MonologLogger(
                $app->container()->getSingleton(LoggerInterface::class)
            )
        );
    }

protected static function bindLogger ( Application $ app ) : void { $ app -> container ( ) -> singleton ( Logger :: class , new MonologLogger ( $ app -> container ( ) -> getSingleton ( LoggerInterface :: class ) ) ) ; }

Bind the logger.

@param Application $app The application

@return void


public function setStatusCode($code = 200) {
        $this->_statusCode = $code;
        $this->_statusText = isset(Response::$httpStatuses[$this->_statusCode]) ? Response::$httpStatuses[$this->_statusCode] : '';
        return $this;
    }

public function setStatusCode ( $ code = 200 ) { $ this -> _statusCode = $ code ; $ this -> _statusText = isset ( Response :: $ httpStatuses [ $ this -> _statusCode ] ) ? Response :: $ httpStatuses [ $ this -> _statusCode ] : '' ; return $ this ; }

Set status code
@param int $code
@return ResponseBuilderInterface


public function getFormattedBody() {
        $body = $this->getRawBody();
        $bodyFormatted = null;
        if ($body instanceof StreamInterface) {
            return $body;
        } elseif (isset($this->formatters[$this->format])) {
            $formatter = $this->formatters[$this->format];
            if (!is_object($formatter)) {
                $this->formatters[$this->format] = $formatter = \Reaction::create($formatter);
            }
            if ($formatter instanceof ResponseFormatterInterface) {
                $bodyFormatted = $formatter->format($this);
            } else {
                throw new InvalidConfigException("The '{$this->format}' response formatter is invalid. It must implement the ResponseFormatterInterface.");
            }
        } elseif ($this->format === Response::FORMAT_RAW) {
            $bodyFormatted = $body;
        } else {
            throw new InvalidConfigException("Unsupported response format: {$this->format}");
        }

        if (is_array($bodyFormatted)) {
            throw new InvalidArgumentException('Response content must not be an array.');
        } elseif (is_object($bodyFormatted)) {
            if (method_exists($bodyFormatted, '__toString')) {
                $bodyFormatted = $bodyFormatted->__toString();
            } else {
                throw new InvalidArgumentException('Response content must be a string or an object implementing __toString().');
            }
        }
        return $bodyFormatted;
    }

Get Response body with formatting
@return array|null|StreamInterface|string
@throws InvalidConfigException


public function redirect($url, $statusCode = 302, $checkAjax = true)
    {
        if (is_array($url) && isset($url[0])) {
            // ensure the route is absolute
            $url[0] = '/' . ltrim($url[0], '/');
        }
        $url = $this->app->helpers->url->to($url);
        if (strncmp($url, '/', 1) === 0 && strncmp($url, '//', 2) !== 0) {
            $url = $this->app->reqHelper->getHostInfo() . $url;
        }

        if ($checkAjax) {
            if ($this->app->reqHelper->getIsAjax()) {
                if ($this->app->reqHelper->getHeaders()->get('X-Ie-Redirect-Compatibility') !== null && $statusCode === 302) {
                    // Ajax 302 redirect in IE does not work. Change status code to 200. See https://github.com/yiisoft/yii2/issues/9670
                    $statusCode = 200;
                }
                $this->getHeaders()->set('X-Redirect', $url);
            } else {
                $this->getHeaders()->set('Location', $url);
            }
        } else {
            $this->getHeaders()->set('Location', $url);
        }

        $this->setBody(null);
        $this->setStatusCode($statusCode);

        return $this;
    }

Redirects the browser to the specified URL.

This method adds a "Location" header to the current response. Note that it does not send out
the header until [[send()]] is called. In a controller action you may use this method as follows:

```php
return $app->response->redirect($url);
```

In AJAX mode, this normally will not work as expected unless there are some
client-side JavaScript code handling the redirection. To help achieve this goal,
this method will send out a "X-Redirect" header instead of "Location".

If you use the "yii" JavaScript module, it will handle the AJAX redirection as
described above. Otherwise, you should write the following JavaScript code to
handle the redirection:

```javascript
$document.ajaxComplete(function (event, xhr, settings) {
var url = xhr && xhr.getResponseHeader('X-Redirect');
if (url) {
window.location = url;
}
});
```

@param string|array $url the URL to be redirected to. This can be in one of the following formats:

- a string representing a URL (e.g. "http://example.com")
- a string representing a URL alias (e.g. "@example.com")
- an array in the format of `[$route, ...name-value pairs...]` (e.g. `['site/index', 'ref' => 1]`).
Note that the route is with respect to the whole application, instead of relative to a controller or module.
[[Url::to()]] will be used to convert the array into a URL.

Any relative URL that starts with a single forward slash "/" will be converted
into an absolute one by prepending it with the host info of the current request.

@param int $statusCode the HTTP status code. Defaults to 302.
See <https://tools.ietf.org/html/rfc2616#section-10>
for details about HTTP status code
@param bool $checkAjax whether to specially handle AJAX (and PJAX) requests. Defaults to true,
meaning if the current request is an AJAX or PJAX request, then calling this method will cause the browser
to redirect to the given URL. If this is false, a `Location` header will be sent, which when received as
an AJAX response, may NOT cause browser redirection.
Takes effect only when request header `X-Ie-Redirect-Compatibility` is absent.
@return ResponseBuilderInterface

Redirects the browser to the specified URL .


protected function createEmptyResponse() {
        $config = [];
        $body = $this->getFormattedBody();
        $params = [
            $this->statusCode,
            $this->getHeadersPrepared(),
            $body,
            $this->version,
            $this->_statusText
        ];
        if (is_array($this->responseClass)) {
            $config = ArrayHelper::merge($config, $this->responseClass);
        } else {
            $config['class'] = $this->responseClass;
        }
        /** @var Response $response */
        $response = \Reaction::create($config, $params);
        return $response;
    }

protected
function
createEmptyResponse
(
)
{
$
config
=
[
]
;
$
body
=
$
this
->
getFormattedBody
(
)
;
$
params
=
[
$
this
->
statusCode
,
$
this
->
getHeadersPrepared
(
)
,
$
body
,
$
this
->
version
,
$
this
->
_statusText
]
;
if
(
is_array
(
$
this
->
responseClass
)
)
{
$
config
=
ArrayHelper
::
merge
(
$
config
,
$
this
->
responseClass
)
;
}
else
{
$
config
[
'class'
]
=
$
this
->
responseClass
;
}
/** @var Response $response */
$
response
=
\
Reaction
::
create
(
$
config
,
$
params
)
;
return
$
response
;
}

Create Response instance
@return Response


protected function getHeadersPrepared() {
        $cookiesData = $this->getCookiesPrepared();
        foreach ($cookiesData as $cookieStr) {
            $this->headers->add('Set-Cookie', $cookieStr);
        }
        $headersArray = [];
        if ($this->_headers) {
            foreach ($this->getHeaders() as $name => $values) {
                $name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $name)));
                if (!isset($headersArray[$name])) {
                    $headersArray[$name] = [];
                }
                foreach ($values as $value) {
                    $headersArray[$name][] = $value;
                }
            }
        }
        return $headersArray;
    }

protected
function
getHeadersPrepared
(
)
{
$
cookiesData
=
$
this
->
getCookiesPrepared
(
)
;
foreach
(
$
cookiesData
as
$
cookieStr
)
{
$
this
->
headers
->
add
(
'Set-Cookie'
,
$
cookieStr
)
;
}
$
headersArray
=
[
]
;
if
(
$
this
->
_headers
)
{
foreach
(
$
this
->
getHeaders
(
)
as
$
name
=>
$
values
)
{
$
name
=
str_replace
(
' '
,
'-'
,
ucwords
(
str_replace
(
'-'
,
' '
,
$
name
)
)
)
;
if
(
!
isset
(
$
headersArray
[
$
name
]
)
)
{
$
headersArray
[
$
name
]
=
[
]
;
}
foreach
(
$
values
as
$
value
)
{
$
headersArray
[
$
name
]
[
]
=
$
value
;
}
}
}
return
$
headersArray
;
}

Get prepared headers array
@return array
@throws InvalidConfigException


protected function getCookiesPrepared() {
        $cookies = [];
        if ($this->_cookies) {
            $request = $this->app->reqHelper;
            if ($request->enableCookieValidation) {
                if ($request->cookieValidationKey == '') {
                    throw new InvalidConfigException(get_class($request) . '::cookieValidationKey must be configured with a secret key.');
                }
                $validationKey = $request->cookieValidationKey;
            } else {
                $validationKey = null;
            }
            foreach ($this->getCookies() as $name => $cookie) {
                /** @var Cookie $cookie */
                $cookies[] = $cookie->getForHeader($validationKey);
            }
        }

        return $cookies;
    }

Get cookies prepared for 'Set-Cookie' header
@return string[]
@throws InvalidConfigException

Get cookies prepared for Set - Cookie header


protected function defaultFormatters()
    {
        return [
            Response::FORMAT_HTML => [
                'class' => 'Reaction\Web\Formatters\HtmlResponseFormatter',
            ],
            Response::FORMAT_XML => [
                'class' => 'Reaction\Web\Formatters\XmlResponseFormatter',
            ],
            Response::FORMAT_JSON => [
                'class' => 'Reaction\Web\Formatters\JsonResponseFormatter',
            ],
            Response::FORMAT_JSONP => [
                'class' => 'Reaction\Web\Formatters\JsonResponseFormatter',
                'useJsonp' => true,
            ],
        ];
    }

Get default formatters
@return array the formatters that are supported by default


private static function extractAuthUserPass($encodedString)
    {
        if (0 >= strlen($encodedString)) {
            return false;
        }
        $decodedString = base64_decode($encodedString, true);
        if (false === $decodedString) {
            return false;
        }

        $firstColonPos = strpos($decodedString, ':');
        if (false === $firstColonPos) {
            return false;
        }

        return array(
            'authUser' => substr($decodedString, 0, $firstColonPos),
            'authPass' => substr($decodedString, $firstColonPos + 1),
        );
    }

private static function extractAuthUserPass ( $ encodedString ) { if ( 0 >= strlen ( $ encodedString ) ) { return false ; } $ decodedString = base64_decode ( $ encodedString , true ) ; if ( false === $ decodedString ) { return false ; } $ firstColonPos = strpos ( $ decodedString , ':' ) ; if ( false === $ firstColonPos ) { return false ; } return array ( 'authUser' => substr ( $ decodedString , 0 , $ firstColonPos ) , 'authPass' => substr ( $ decodedString , $ firstColonPos + 1 ) , ) ; }

Extract the authUser and authPass from the BASE64 encoded string.

@param string $encodedString the BASE64 encoded colon separated
authUser and authPass

@return mixed array containing authUser and authPass or false if
the decoding fails

Extract the authUser and authPass from the BASE64 encoded string .


public function scenarios()
    {
        $scenarios = [self::SCENARIO_DEFAULT => []];
        $this->fillScenariosKeys($scenarios);

        $this->fillScenariosAttributes($scenarios);

        foreach ($scenarios as $scenario => $attributes) {
            if (!empty($attributes)) {
                $scenarios[$scenario] = array_keys($attributes);
            }
        }

        return $scenarios;
    }

public function scenarios ( ) { $ scenarios = [ self :: SCENARIO_DEFAULT => [ ] ] ; $ this -> fillScenariosKeys ( $ scenarios ) ; $ this -> fillScenariosAttributes ( $ scenarios ) ; foreach ( $ scenarios as $ scenario => $ attributes ) { if ( ! empty ( $ attributes ) ) { $ scenarios [ $ scenario ] = array_keys ( $ attributes ) ; } } return $ scenarios ; }

Returns a list of scenarios and the corresponding active attributes.

An active attribute is one that is subject to validation in the current scenario.
The returned array should be in the following format:

```php
[
'scenario1' => ['attribute11', 'attribute12', ...],
'scenario2' => ['attribute21', 'attribute22', ...],
...
]
```

By default, an active attribute is considered safe and can be massively assigned.
If an attribute should NOT be massively assigned (thus considered unsafe),
please prefix the attribute with an exclamation character (e.g. `'!rank'`).

The default implementation of this method will return all scenarios found in the [[rules()]]
declaration. A special scenario named [[SCENARIO_DEFAULT]] will contain all attributes
found in the [[rules()]]. Each scenario will be associated with the attributes that
are being validated by the validation rules that apply to the scenario.

@return array a list of scenarios and the corresponding active attributes.

Returns a list of scenarios and the corresponding active attributes .


protected function fillScenariosAttributes(array &$scenarios) {
        $names = array_keys($scenarios);
        foreach ($this->getValidators() as $validator) {
            if (empty($validator->on) && empty($validator->except)) {
                foreach ($names as $name) {
                    foreach ($validator->attributes as $attribute) {
                        $scenarios[$name][$attribute] = true;
                    }
                }
            } elseif (empty($validator->on)) {
                foreach ($names as $name) {
                    if (!in_array($name, $validator->except, true)) {
                        foreach ($validator->attributes as $attribute) {
                            $scenarios[$name][$attribute] = true;
                        }
                    }
                }
            } else {
                foreach ($validator->on as $name) {
                    foreach ($validator->attributes as $attribute) {
                        $scenarios[$name][$attribute] = true;
                    }
                }
            }
        }
    }

protected function fillScenariosAttributes ( array & $ scenarios ) { $ names = array_keys ( $ scenarios ) ; foreach ( $ this -> getValidators ( ) as $ validator ) { if ( empty ( $ validator -> on ) && empty ( $ validator -> except ) ) { foreach ( $ names as $ name ) { foreach ( $ validator -> attributes as $ attribute ) { $ scenarios [ $ name ] [ $ attribute ] = true ; } } } elseif ( empty ( $ validator -> on ) ) { foreach ( $ names as $ name ) { if ( ! in_array ( $ name , $ validator -> except , true ) ) { foreach ( $ validator -> attributes as $ attribute ) { $ scenarios [ $ name ] [ $ attribute ] = true ; } } } } else { foreach ( $ validator -> on as $ name ) { foreach ( $ validator -> attributes as $ attribute ) { $ scenarios [ $ name ] [ $ attribute ] = true ; } } } } }

Fill scenarios with attributes
@param array $scenarios
@throws InvalidConfigException


public function formName()
    {
        try {
            $reflector = new ReflectionClass($this);
            if (PHP_VERSION_ID >= 70000 && $reflector->isAnonymous()) {
                throw new InvalidConfigException('The "formName()" method should be explicitly defined for anonymous models');
            }
            return $reflector->getShortName();
        } catch (\ReflectionException $exception) {
            $className = explode('\\', static::class);
            return end($className);
        }
    }

Returns the form name that this model class should use.

The form name is mainly used by [[\Reaction\Widgets\ActiveForm]] to determine how to name
the input fields for the attributes in a model. If the form name is "A" and an attribute
name is "b", then the corresponding input name would be "A[b]". If the form name is
an empty string, then the input name would be "b".

The purpose of the above naming schema is that for forms which contain multiple different models,
the attributes of each model are grouped in sub-arrays of the POST-data and it is easier to
differentiate between them.

By default, this method returns the model class name (without the namespace part)
as the form name. You may override it when the model is used in different forms.

@return string the form name of this model class.
@see load()
@throws InvalidConfigException when form is defined with anonymous class and `formName()` method is
not overridden.

Returns the form name that this model class should use .


public function attributes()
    {
        try {
            $class = new ReflectionClass($this);
            $names = [];
            foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
                if (!$property->isStatic()) {
                    $names[] = $property->getName();
                }
            }
        } catch (\ReflectionException $exception) {
            Reaction::error($exception);
            $names = [];
        }

        return $names;
    }

public function attributes ( ) { try { $ class = new ReflectionClass ( $ this ) ; $ names = [ ] ; foreach ( $ class -> getProperties ( \ ReflectionProperty :: IS_PUBLIC ) as $ property ) { if ( ! $ property -> isStatic ( ) ) { $ names [ ] = $ property -> getName ( ) ; } } } catch ( \ ReflectionException $ exception ) { Reaction :: error ( $ exception ) ; $ names = [ ] ; } return $ names ; }

Returns the list of attribute names.
By default, this method returns all public non-static properties of the class.
You may override this method to change the default behavior.
@return array list of attribute names.

Returns the list of attribute names . By default this method returns all public non - static properties of the class . You may override this method to change the default behavior .


public function validate($attributeNames = null, $clearErrors = true)
    {
        if ($clearErrors) {
            $this->clearErrors();
        }

        if (!$this->beforeValidate()) {
            return reject(new ValidationError("Before validate error"));
        }

        $scenarios = $this->scenarios();
        $scenario = $this->getScenario();
        if (!isset($scenarios[$scenario])) {
            throw new InvalidArgumentException("Unknown scenario: $scenario");
        }

        if ($attributeNames === null) {
            $attributeNames = $this->activeAttributes();
        }

        $attributeNames = (array)$attributeNames;

        $validationPromises = [];
        foreach ($this->getActiveValidators() as $validator) {
            $validationPromises[] = $validator->validateAttributes($this, $attributeNames);
        }
        return Reaction\Promise\allInOrder($validationPromises)
            ->always(function() {
                $this->afterValidate();
            })->then(function() {
                return !$this->hasErrors() ? true : reject(new ValidationError("Validation error"));
            });
    }

public
function
validate
(
$
attributeNames
=
,
$
clearErrors
=
true
)
{
if
(
$
clearErrors
)
{
$
this
->
clearErrors
(
)
;
}
if
(
!
$
this
->
beforeValidate
(
)
)
{
return
reject
(
new
ValidationError
(
"Before validate error"
)
)
;
}
$
scenarios
=
$
this
->
scenarios
(
)
;
$
scenario
=
$
this
->
getScenario
(
)
;
if
(
!
isset
(
$
scenarios
[
$
scenario
]
)
)
{
throw
new
InvalidArgumentException
(
"Unknown scenario: $scenario"
)
;
}
if
(
$
attributeNames
===
)
{
$
attributeNames
=
$
this
->
activeAttributes
(
)
;
}
$
attributeNames
=
(
array
)
$
attributeNames
;
$
validationPromises
=
[
]
;
foreach
(
$
this
->
getActiveValidators
(
)
as
$
validator
)
{
$
validationPromises
[
]
=
$
validator
->
validateAttributes
(
$
this
,
$
attributeNames
)
;
}
return
Reaction
\
Promise
\
allInOrder
(
$
validationPromises
)
->
always
(
function
(
)
{
$
this
->
afterValidate
(
)
;
}
)
->
then
(
function
(
)
{
return
!
$
this
->
hasErrors
(
)
true
:
reject
(
new
ValidationError
(
"Validation error"
)
)
;
}
)
;
}

Performs the data validation.

This method executes the validation rules applicable to the current [[scenario]].
The following criteria are used to determine whether a rule is currently applicable:

- the rule must be associated with the attributes relevant to the current scenario;
- the rules must be effective for the current scenario.

This method will call [[beforeValidate()]] and [[afterValidate()]] before and
after the actual validation, respectively. If [[beforeValidate()]] returns false,
the validation will be cancelled and [[afterValidate()]] will not be called.

Errors found during the validation can be retrieved via [[getErrors()]],
[[getFirstErrors()]] and [[getFirstError()]].

@param string[]|string $attributeNames attribute name or list of attribute names that should be validated.
If this parameter is empty, it means any attribute listed in the applicable
validation rules should be validated.
@param bool $clearErrors whether to call [[clearErrors()]] before performing validation
@return ExtendedPromiseInterface with bool whether the validation is successful without any error.
@throws InvalidArgumentException if the current scenario is unknown.


public static function validateMultiple($models, $attributeNames = null)
    {
        $promises = [];
        /* @var $model Model */
        foreach ($models as $model) {
            $promises[] = new Reaction\Promise\LazyPromise(function() use(&$model, $attributeNames) {
                return $model->validate($attributeNames);
            });
        }

        return Reaction\Promise\allInOrder($promises);
    }

public
static
function
validateMultiple
(
$
models
,
$
attributeNames
=
)
{
$
promises
=
[
]
;
/* @var $model Model */
foreach
(
$
models
as
$
model
)
{
$
promises
[
]
=
new
Reaction
\
Promise
\
LazyPromise
(
function
(
)
use
(
&
$
model
,
$
attributeNames
)
{
return
$
model
->
validate
(
$
attributeNames
)
;
}
)
;
}
return
Reaction
\
Promise
\
allInOrder
(
$
promises
)
;
}

Validates multiple models.
This method will validate every model. The models being validated may
be of the same or different types.
@param array $models the models to be validated
@param array $attributeNames list of attribute names that should be validated.
If this parameter is empty, it means any attribute listed in the applicable
validation rules should be validated.
@return ExtendedPromiseInterface with bool whether all models are valid. RejectedPromise will be returned if one
or multiple models have validation error.

Validates multiple models . This method will validate every model . The models being validated may be of the same or different types .


public function t($category, $message, $params = [], $language = null)
    {
        if (!isset($language) && isset($this->app)) {
            $language = $this->app->language;
        }
        return isset($language)
            ? Reaction::t($category, $message, $params, $language)
            : Reaction::tp($category, $message, $params, $language);
    }

public function t ( $ category , $ message , $ params = [ ] , $ language = null ) { if ( ! isset ( $ language ) && isset ( $ this -> app ) ) { $ language = $ this -> app -> language ; } return isset ( $ language ) ? Reaction :: t ( $ category , $ message , $ params , $ language ) : Reaction :: tp ( $ category , $ message , $ params , $ language ) ; }

Translates a message to the specified language.
Or returns a TranslationPromise for further translation

@param string $category Message category
@param string $message Message for translation
@param array  $params Parameters array
@param string $language Language translate to
@return string|Reaction\I18n\TranslationPromise

Translates a message to the specified language . Or returns a TranslationPromise for further translation


public function addAttachment($file, $forceFileName = '', $forceMimeType = '')
    {
        $this->attachments[] = array(
            'file' => $file,
            'fileName' => $forceFileName,
            'mimeType' => $forceMimeType,
        );

        return $this;
    }

public function addAttachment ( $ file , $ forceFileName = '' , $ forceMimeType = '' ) { $ this -> attachments [ ] = array ( 'file' => $ file , 'fileName' => $ forceFileName , 'mimeType' => $ forceMimeType , ) ; return $ this ; }

Autodetect mime type relies on php fileinfo extension
@param string $file
@param string $forceFileName
@param string $forceMimeType
@return $this


public function addPlugin(RequestPluginAdapter $plugin)
    {
        $subscriber = $plugin->add();
        $this->request->addSubscriber($subscriber);

        return $this;
    }

public function addPlugin ( RequestPluginAdapter $ plugin ) { $ subscriber = $ plugin -> add ( ) ; $ this -> request -> addSubscriber ( $ subscriber ) ; return $ this ; }

Adds normalized plugins to the Http client.

@param \RestGalleries\Http\Plugins\RequestPluginAdapter $plugin

Adds normalized plugins to the Http client .


public function sendRequest($method = 'GET', $endPoint = '')
    {
        $options = array_filter([
            'query'   => $this->getQuery(),
            'headers' => $this->getHeaders(),
            'body'    => $this->getBody()
        ]);
        $url = $this->url . $endPoint;

        $request     = $this->request->createRequest($method, $url, $options);
        $rawResponse = $this->request->send($request);

        return $this->newResponse($rawResponse);

    }

public function sendRequest ( $ method = 'GET' , $ endPoint = '' ) { $ options = array_filter ( [ 'query' => $ this -> getQuery ( ) , 'headers' => $ this -> getHeaders ( ) , 'body' => $ this -> getBody ( ) ] ) ; $ url = $ this -> url . $ endPoint ; $ request = $ this -> request -> createRequest ( $ method , $ url , $ options ) ; $ rawResponse = $ this -> request -> send ( $ request ) ; return $ this -> newResponse ( $ rawResponse ) ; }

Gets the request options, creates the request, sends it and returns new response object.

@param  string $method
@param  string $endPoint
@return \RestGalleries\Http\Guzzle\GuzzleResponse

Gets the request options creates the request sends it and returns new response object .


public static function loadClass($classname, $type = null, $silent = false)
    {
        // search in bundles
        $bundles = CarteBlanche::getContainer()->get('bundles');
        $full_classname = $type.$classname;
        $classfile = ucfirst($classname).'.php';
        if (!empty($bundles)) {
            foreach($bundles as $_n=>$_bundle) {
                $_namespace = $_bundle->getNamespace();
                if (!empty($type)) {
                    $bundle_file = rtrim($_bundle->getDirectory(), '/').'/'
                        .rtrim($type, '/').'/'
                        .$classfile;
                    $full_namespace = '\\'.$_namespace.'\\'.$type.'\\'.ucfirst($classname);
                    if ($_ce = self::classExists($full_namespace)) {
                        return $full_namespace;
                    } elseif ($_f = Locator::locate($bundle_file)) {
                        if (true===self::load($_f)) {
                            return $full_namespace;
                        }
                    }
                } else {
                    if ($_namespace == substr(trim($classname, '\\'), 0, strlen($_namespace))) {
                        $bundle_file = str_replace('\\', DIRECTORY_SEPARATOR,
                            rtrim($_bundle->getDirectory(), '/')
                            .substr(trim($classname, '\\'), strlen($_namespace))
                            .'.php'
                        );
                        $full_namespace = $classname;
                        if ($_ce = self::classExists($full_namespace)) {
                            return $full_namespace;
                        } elseif ($_f = Locator::locate($bundle_file)) {
                            if (true===self::load($_f)) {
                                return $classname;
                            }
                        }
                    }
                }
            }
        }

        // silently return if the class has not been found
        if (0!==error_reporting() && true!==$silent) {
            throw new ErrorException("Class '$classname' not found!");
        }
        return false;
    }

Class autoloader to scan bundles directory

@param   string          $classname  The name of the class to load
@param   null/string     $type       The namespace type (Controller for example)
@param   bool            $silent     Exit silently if not found (default is false)
@return  bool/string     TRUE if the classfile had been found
@throws  \CarteBlanche\Exception\ErrorException if the class can't be found & $silent is false


public function getListeners(string ...$classes): array
    {
        $annotations = [];

        // Iterate through all the classes
        foreach ($classes as $class) {
            $listeners = $this->methodsAnnotationsType('Listener', $class);

            // Get all the annotations for each class and iterate through them
            /** @var \Valkyrja\Events\Annotations\Listener $annotation */
            foreach ($listeners as $annotation) {
                $this->setListenerProperties($annotation);
                // Set the annotation in the annotations list
                $annotations[] = $this->getListenerFromAnnotation($annotation);
            }
        }

        return $annotations;
    }

Get the events.

@param string[] $classes The classes

@throws \ReflectionException

@return \Valkyrja\Events\Listener[]


protected function setListenerProperties(Listener $listener): void
    {
        $classReflection = $this->getClassReflection($listener->getClass());

        if (
            $listener->getMethod()
            || $classReflection->hasMethod('__construct')
        ) {
            $methodReflection = $this->getMethodReflection(
                $listener->getClass(),
                $listener->getMethod() ?? '__construct'
            );
            $parameters       = $methodReflection->getParameters();

            // Set the dependencies
            $listener->setDependencies($this->getDependencies(...$parameters));
        }

        $listener->setMatches();
    }

protected
function
setListenerProperties
(
Listener
$
listener
)
:
void
{
$
classReflection
=
$
this
->
getClassReflection
(
$
listener
->
getClass
(
)
)
;
if
(
$
listener
->
getMethod
(
)
||
$
classReflection
->
hasMethod
(
'__construct'
)
)
{
$
methodReflection
=
$
this
->
getMethodReflection
(
$
listener
->
getClass
(
)
,
$
listener
->
getMethod
(
)
??
'__construct'
)
;
$
parameters
=
$
methodReflection
->
getParameters
(
)
;
// Set the dependencies
$
listener
->
setDependencies
(
$
this
->
getDependencies
(
...
$
parameters
)
)
;
}
$
listener
->
setMatches
(
)
;
}

Set the properties for a listener annotation.

@param Listener $listener

@throws \ReflectionException

@return void

Set the properties for a listener annotation .


protected function getListenerFromAnnotation(Listener $listener): EventListener
    {
        $eventListener = new EventListener();

        $eventListener
            ->setEvent($listener->getEvent())
            ->setId($listener->getId())
            ->setName($listener->getName())
            ->setClass($listener->getClass())
            ->setProperty($listener->getProperty())
            ->setMethod($listener->getMethod())
            ->setStatic($listener->isStatic())
            ->setFunction($listener->getFunction())
            ->setMatches($listener->getMatches())
            ->setDependencies($listener->getDependencies())
            ->setArguments($listener->getArguments());

        return $eventListener;
    }

protected function getListenerFromAnnotation ( Listener $ listener ) : EventListener { $ eventListener = new EventListener ( ) ; $ eventListener -> setEvent ( $ listener -> getEvent ( ) ) -> setId ( $ listener -> getId ( ) ) -> setName ( $ listener -> getName ( ) ) -> setClass ( $ listener -> getClass ( ) ) -> setProperty ( $ listener -> getProperty ( ) ) -> setMethod ( $ listener -> getMethod ( ) ) -> setStatic ( $ listener -> isStatic ( ) ) -> setFunction ( $ listener -> getFunction ( ) ) -> setMatches ( $ listener -> getMatches ( ) ) -> setDependencies ( $ listener -> getDependencies ( ) ) -> setArguments ( $ listener -> getArguments ( ) ) ; return $ eventListener ; }

Get a listener from a listener annotation.

@param Listener $listener The listener annotation

@return \Valkyrja\Events\Listener

Get a listener from a listener annotation .


public function getOptions($option = null)
    {
        if ($option === null) {
            return $this->_options;
        }

        if (!array_key_exists($option, $this->_options)) {
            return null;
        }

        return $this->_options[$option];
    }

public function getOptions ( $ option = null ) { if ( $ option === null ) { return $ this -> _options ; } if ( ! array_key_exists ( $ option , $ this -> _options ) ) { return null ; } return $ this -> _options [ $ option ] ; }

Returns one or all set options

@param string $option (Optional) Option to return
@return mixed


public function setOptions(array $options)
    {
        foreach ($options as $key => $option) {
            $method = 'set' . $key;
            if (method_exists($this, $method)) {
                $this->$method($option);
            }
        }

        return $this;
    }

public function setOptions ( array $ options ) { foreach ( $ options as $ key => $ option ) { $ method = 'set' . $ key ; if ( method_exists ( $ this , $ method ) ) { $ this -> $ method ( $ option ) ; } } return $ this ; }

Sets all or one option

@param  array $options
@return Zend_Filter_Compress_Bz2


public function getKeyValue($keyType, $keyValue)
    {
        $list = Keyvalue::getKeyvaluesByKeyType($keyType);
        if (isset($list[$keyValue])) {
            return $list[$keyValue];
        }
        return null;
    }

public function getKeyValue ( $ keyType , $ keyValue ) { $ list = Keyvalue :: getKeyvaluesByKeyType ( $ keyType ) ; if ( isset ( $ list [ $ keyValue ] ) ) { return $ list [ $ keyValue ] ; } return null ; }

Fetches a single keyvalue by key type and key value

@param string $keyType
@param string $keyValue
@return Fluent


public function fromArray(array $input) {
        $fillable = $this->getFillableFields();

        foreach($input as $key => $value) {
            if(in_array($key, $fillable)) {
                $this->{'set' . ucfirst($key)}($value);
            } else {
                throw new MassAssignmentException($key);
            }
        }
    }

public function fromArray ( array $ input ) { $ fillable = $ this -> getFillableFields ( ) ; foreach ( $ input as $ key => $ value ) { if ( in_array ( $ key , $ fillable ) ) { $ this -> { 'set' . ucfirst ( $ key ) } ( $ value ) ; } else { throw new MassAssignmentException ( $ key ) ; } } }

Fills the entity from and array.

@param array $input
@return void
@throws MassAssignmentException if the input tries to assign an not-fillable field.


public function loadEntitiesFrom($directory) {
        $metadata = $this->app['config']['doctrine.managers.default.paths'];
        $metadata[] = $directory;
        $this->app['config']->set('doctrine.managers.default.paths', $metadata);
    }

public function loadEntitiesFrom ( $ directory ) { $ metadata = $ this -> app [ 'config' ] [ 'doctrine.managers.default.paths' ] ; $ metadata [ ] = $ directory ; $ this -> app [ 'config' ] -> set ( 'doctrine.managers.default.paths' , $ metadata ) ; }

Register a directory of Doctrine entities.

@param  string  $directory
@return void

Register a directory of Doctrine entities .


public function extendEntityManager(callable $closure) {
        // use 'em' instead of full class name to get around bug: https://github.com/laravel/framework/issues/11226
        if($this->app->resolved('em')) {
            $closure($this->app[EntityManager::class]);
        } else {
            $this->app->resolving(EntityManager::class, $closure);
        }
    }

Modify the entity manager

@param callable $closure


public function checkPredictions()
    {
        $exception = new AggregateException("Some predictions failed:\n");
        foreach ($this->prophecies as $prophecy) {
            try {
                $prophecy->checkPredictions();
            } catch (PredictionException $e) {
                $exception->append($e);
            }
        }

        $this->prophecies = [];
        MockRegistry::getInstance()->unregisterAll();

        if (count($exception->getExceptions())) {
            throw $exception;
        }

    }

public
function
checkPredictions
(
)
{
$
exception
=
new
AggregateException
(
"Some predictions failed:\n"
)
;
foreach
(
$
this
->
prophecies
as
$
prophecy
)
{
try
{
$
prophecy
->
checkPredictions
(
)
;
}
catch
(
PredictionException
$
e
)
{
$
exception
->
append
(
$
e
)
;
}
}
$
this
->
prophecies
=
[
]
;
MockRegistry
::
getInstance
(
)
->
unregisterAll
(
)
;
if
(
count
(
$
exception
->
getExceptions
(
)
)
)
{
throw
$
exception
;
}
}

Check all prophecies for predictions

@throws AggregateException


protected function _processExtends(SimpleXMLElement $element, $section, array $config = array())
    {
        if (!isset($element->$section)) {

            throw new Zend_Config_Exception("Section '$section' cannot be found");
        }

        $thisSection  = $element->$section;
        $nsAttributes = $thisSection->attributes(self::XML_NAMESPACE);

        if (isset($thisSection['extends']) || isset($nsAttributes['extends'])) {
            $extendedSection = (string) (isset($nsAttributes['extends']) ? $nsAttributes['extends'] : $thisSection['extends']);
            $this->_assertValidExtend($section, $extendedSection);

            if (!$this->_skipExtends) {
                $config = $this->_processExtends($element, $extendedSection, $config);
            }
        }

        $config = $this->_arrayMergeRecursive($config, $this->_toArray($thisSection));

        return $config;
    }

protected
function
_processExtends
(
SimpleXMLElement
$
element
,
$
section
,
array
$
config
=
array
(
)
)
{
if
(
!
isset
(
$
element
->
$
section
)
)
{
throw
new
Zend_Config_Exception
(
"Section '$section' cannot be found"
)
;
}
$
thisSection
=
$
element
->
$
section
;
$
nsAttributes
=
$
thisSection
->
attributes
(
self
::
XML_NAMESPACE
)
;
if
(
isset
(
$
thisSection
[
'extends'
]
)
||
isset
(
$
nsAttributes
[
'extends'
]
)
)
{
$
extendedSection
=
(
string
)
(
isset
(
$
nsAttributes
[
'extends'
]
)
$
nsAttributes
[
'extends'
]
:
$
thisSection
[
'extends'
]
)
;
$
this
->
_assertValidExtend
(
$
section
,
$
extendedSection
)
;
if
(
!
$
this
->
_skipExtends
)
{
$
config
=
$
this
->
_processExtends
(
$
element
,
$
extendedSection
,
$
config
)
;
}
}
$
config
=
$
this
->
_arrayMergeRecursive
(
$
config
,
$
this
->
_toArray
(
$
thisSection
)
)
;
return
$
config
;
}

Helper function to process each element in the section and handle
the "extends" inheritance attribute.

@param  SimpleXMLElement $element XML Element to process
@param  string           $section Section to process
@param  array            $config  Configuration which was parsed yet
@throws Zend_Config_Exception When $section cannot be found
@return array

Helper function to process each element in the section and handle the extends inheritance attribute .


public function verifyClassMethod(Dispatch $dispatch): void
    {
        // If a class and method are set and not callable
        if (
            null !== $dispatch->getClass()
            && null !== $dispatch->getMethod()
            && ! method_exists(
                $dispatch->getClass(),
                $dispatch->getMethod()
            )
        ) {
            // Throw a new invalid method exception
            throw new InvalidMethodException(
                'Method does not exist in class : '
                . $dispatch->getName() . ' '
                . $dispatch->getClass()
                . '@'
                . $dispatch->getMethod()
            );
        }
    }

Verify the class and method of a dispatch.

@param Dispatch $dispatch The dispatch

@throws \Valkyrja\Dispatcher\Exceptions\InvalidMethodException

@return void

Verify the class and method of a dispatch .


public function verifyClassProperty(Dispatch $dispatch): void
    {
        // If a class and method are set and not callable
        if (
            null !== $dispatch->getClass()
            && null !== $dispatch->getProperty()
            && ! property_exists(
                $dispatch->getClass(),
                $dispatch->getProperty()
            )
        ) {
            // Throw a new invalid property exception
            throw new InvalidPropertyException(
                'Property does not exist in class : '
                . $dispatch->getName() . ' '
                . $dispatch->getClass()
                . '@'
                . $dispatch->getProperty()
            );
        }
    }

Verify the class and property of a dispatch.

@param Dispatch $dispatch The dispatch

@throws \Valkyrja\Dispatcher\Exceptions\InvalidPropertyException

@return void

Verify the class and property of a dispatch .


public function verifyFunction(Dispatch $dispatch): void
    {
        // If a function is set and is not callable
        if (
            null !== $dispatch->getFunction()
            && ! \is_callable($dispatch->getFunction())
        ) {
            // Throw a new invalid function exception
            throw new InvalidFunctionException(
                'Function is not callable for : '
                . $dispatch->getName() . ' '
                . $dispatch->getFunction()
            );
        }
    }

Verify the function of a dispatch.

@param Dispatch $dispatch The dispatch

@throws \Valkyrja\Dispatcher\Exceptions\InvalidFunctionException

@return void


public function verifyClosure(Dispatch $dispatch): void
    {
        // If a closure is set and is not callable
        if (
            null === $dispatch->getFunction()
            && null === $dispatch->getClass()
            && null === $dispatch->getMethod()
            && null === $dispatch->getProperty()
            && null === $dispatch->getClosure()
        ) {
            // Throw a new invalid closure exception
            throw new InvalidClosureException(
                'Closure is not valid for : '
                . $dispatch->getName()
            );
        }
    }

Verify the closure of a dispatch.

@param Dispatch $dispatch The dispatch

@throws \Valkyrja\Dispatcher\Exceptions\InvalidClosureException

@return void


public function verifyDispatch(Dispatch $dispatch): void
    {
        // If a function, closure, and class or method are not set
        if (
            null === $dispatch->getFunction()
            && null === $dispatch->getClosure()
            && null === $dispatch->getClass()
            && null === $dispatch->getMethod()
            && null === $dispatch->getProperty()

        ) {
            // Throw a new invalid dispatch capability exception
            throw new InvalidDispatchCapabilityException(
                'Dispatch capability is not valid for : '
                . $dispatch->getName()
            );
        }

        $this->verifyClassMethod($dispatch);
        $this->verifyClassProperty($dispatch);
        $this->verifyFunction($dispatch);
        $this->verifyClosure($dispatch);
    }

Verify the dispatch's dispatch capabilities.

@param Dispatch $dispatch The dispatch

@throws \Valkyrja\Dispatcher\Exceptions\InvalidClosureException
@throws \Valkyrja\Dispatcher\Exceptions\InvalidDispatchCapabilityException
@throws \Valkyrja\Dispatcher\Exceptions\InvalidFunctionException
@throws \Valkyrja\Dispatcher\Exceptions\InvalidMethodException
@throws \Valkyrja\Dispatcher\Exceptions\InvalidPropertyException

@return void

Verify the dispatch s dispatch capabilities .


protected function getDependencies(Dispatch $dispatch): ? array
    {
        $dependencies = null;

        // If the dispatch is static it doesn't need dependencies
        if ($dispatch->isStatic()) {
            return $dependencies;
        }

        $dependencies = [];
        $context      = $dispatch->getClass() ?? $dispatch->getFunction();
        $member       = $dispatch->getProperty() ?? $dispatch->getMethod();

        // If there are dependencies
        if ($dispatch->getDependencies()) {
            // Iterate through all the dependencies
            foreach ($dispatch->getDependencies() as $dependency) {
                // Set the dependency in the list
                $dependencies[] = $this->app->container()->get(
                    $dependency,
                    null,
                    $context,
                    $member
                );
            }
        }

        return $dependencies;
    }

Get a dispatch's dependencies.

@param Dispatch $dispatch The dispatch

@return array


protected function getArguments(Dispatch $dispatch, array $arguments = null): ? array
    {
        // Get either the arguments passed or from the dispatch model
        $arguments = $arguments ?? $dispatch->getArguments();
        $context   = $dispatch->getClass() ?? $dispatch->getFunction();
        $member    = $dispatch->getProperty() ?? $dispatch->getMethod();

        // Set the listener arguments to a new blank array
        $dependencies = $this->getDependencies($dispatch);

        // If there are no arguments
        if (null === $arguments) {
            // Return the dependencies only
            return $dependencies;
        }

        // Iterate through the arguments
        foreach ($arguments as $argument) {
            // If the argument is a service
            if ($argument instanceof Service) {
                // Dispatch the argument and set the results to the argument
                $argument = $this->app->container()->get(
                    $argument->getId(),
                    null,
                    $context,
                    $member
                );
            } // If the argument is a dispatch
            elseif ($argument instanceof Dispatch) {
                // Dispatch the argument and set the results to the argument
                $argument = $this->dispatchCallable($argument);
            }

            // Append the argument to the arguments list
            $dependencies[] = $argument;
        }

        return $dependencies;
    }

Get a dispatch's arguments.

@param Dispatch $dispatch  The dispatch
@param array    $arguments [optional] The arguments

@return array


public function dispatchClassMethod(Dispatch $dispatch, array $arguments = null)
    {
        $response = null;

        // Ensure a class and method exist before continuing
        if (null === $dispatch->getClass() || null === $dispatch->getMethod()) {
            return $response;
        }

        // Set the class through the container if this isn't a static method
        $class    = $dispatch->isStatic()
            ? $dispatch->getClass()
            : $this->app->container()->get($dispatch->getClass());
        $method   = $dispatch->getMethod();
        $response = null;

        // If there are arguments
        if (null !== $arguments) {
            // Unpack arguments and dispatch
            if ($dispatch->isStatic()) {
                $response = $class::$method(...$arguments);
            } else {
                $response = $class->$method(...$arguments);
            }
        } else {
            // Dispatch without unpacking
            if ($dispatch->isStatic()) {
                $response = $class::$method();
            } else {
                $response = $class->$method();
            }
        }

        return $response ?? $this->DISPATCHED;
    }

Dispatch a class method.

@param Dispatch $dispatch  The dispatch
@param array    $arguments [optional] The arguments

@return mixed


public function dispatchClassProperty(Dispatch $dispatch)
    {
        $response = null;

        // Ensure a class and property exist before continuing
        if (
            null === $dispatch->getClass()
            || null === $dispatch->getProperty()
        ) {
            return $response;
        }

        $class    = $dispatch->getClass();
        $property = $dispatch->getProperty();

        // If this is a static property
        if ($dispatch->isStatic()) {
            $response = $class::$$property;
        } else {
            // Get the class from the container
            $class    = $this->app->container()->get($dispatch->getClass());
            $response = $class->{$property};
        }

        return $response ?? $this->DISPATCHED;
    }

Dispatch a class property.

@param Dispatch $dispatch The dispatch

@return mixed


public function dispatchClass(Dispatch $dispatch, array $arguments = null)
    {
        // Ensure a class exists before continuing
        if (null === $dispatch->getClass()) {
            return $dispatch->getClass();
        }

        // If the class is the id then this item is not yet set
        // in the service container yet so it needs a new
        // instance returned
        if ($dispatch->getClass() === $dispatch->getId()) {
            // Get the class from the dispatcher
            $class = $dispatch->getClass();

            // If there are argument
            if (null !== $arguments) {
                // Get a new class instance with the arguments
                $class = new $class(...$arguments);
            } else {
                // Otherwise just get a new class instance
                $class = new $class();
            }
        } else {
            // Set the class through the container
            $class = $this->app->container()->get(
                $dispatch->getClass(),
                $arguments
            );
        }

        return $class ?? $this->DISPATCHED;
    }

Dispatch a class.

@param Dispatch $dispatch  The dispatch
@param array    $arguments [optional] The arguments

@return mixed


public function dispatchFunction(Dispatch $dispatch, array $arguments = null)
    {
        // Ensure a function exists before continuing
        if (null === $dispatch->getFunction()) {
            return $dispatch->getFunction();
        }

        $function = $dispatch->getFunction();
        $response = null;

        // If there are arguments
        if (null !== $arguments) {
            // Unpack arguments and dispatch
            $response = $function(...$arguments);
        } else {
            // Dispatch without unpacking
            $response = $function();
        }

        return $response ?? $this->DISPATCHED;
    }

Dispatch a function.

@param Dispatch $dispatch  The dispatch
@param array    $arguments [optional] The arguments

@return mixed


public function dispatchClosure(Dispatch $dispatch, array $arguments = null)
    {
        // Ensure a closure exists before continuing
        if (null === $dispatch->getClosure()) {
            return $dispatch->getClosure();
        }

        $closure  = $dispatch->getClosure();
        $response = null;

        // If there are arguments
        if (null !== $arguments) {
            // Unpack arguments and dispatch
            $response = $closure(...$arguments);
        } else {
            // Dispatch without unpacking
            $response = $closure();
        }

        return $response ?? $this->DISPATCHED;
    }

Dispatch a closure.

@param Dispatch $dispatch  The dispatch
@param array    $arguments [optional] The arguments

@return mixed


public function dispatchCallable(Dispatch $dispatch, array $arguments = null)
    {
        // Get the arguments with dependencies
        $arguments = $this->getArguments($dispatch, $arguments);

        // Attempt to dispatch the dispatch
        $response = $this->dispatchClassMethod($dispatch, $arguments)
            ?? $this->dispatchClassProperty($dispatch)
            ?? $this->dispatchClass($dispatch, $arguments)
            ?? $this->dispatchFunction($dispatch, $arguments)
            ?? $this->dispatchClosure($dispatch, $arguments);
        // TODO: Add Constant and Variable ability

        // If the response was initially null and we added the dispatched
        // text to avoid calling each subsequent dispatcher thereafter
        if ($response === $this->DISPATCHED) {
            // Reset the response to null
            $response = null;
        }

        return $response;
    }

Dispatch a callable.

@param Dispatch $dispatch  The dispatch
@param array    $arguments [optional] The arguments

@return mixed


public function getStringArguments(): string
    {
        $arguments       = $this->getRequestArguments();
        $globalArguments = $this->getGlobalOptionsFlat();

        foreach ($arguments as $key => $argument) {
            if (\in_array($argument, $globalArguments, true)) {
                unset($arguments[$key]);
            }
        }

        return implode(' ', $arguments);
    }

public
function
getStringArguments
(
)
:
string
{
$
arguments
=
$
this
->
getRequestArguments
(
)
;
$
globalArguments
=
$
this
->
getGlobalOptionsFlat
(
)
;
foreach
(
$
arguments
as
$
key
=>
$
argument
)
{
if
(
\
in_array
(
$
argument
,
$
globalArguments
,
true
)
)
{
unset
(
$
arguments
[
$
key
]
)
;
}
}
return
implode
(
' '
,
$
arguments
)
;
}

Get the arguments as a string.

@return string


public function getRequestArguments(): array
    {
        if (null !== $this->requestArguments) {
            return $this->requestArguments;
        }

        $arguments = $this->request->server()->get('argv');

        // strip the application name
        array_shift($arguments);

        return $this->requestArguments = $arguments;
    }

public
function
getRequestArguments
(
)
:
array
{
if
(
!==
$
this
->
requestArguments
)
{
return
$
this
->
requestArguments
;
}
$
arguments
=
$
this
->
request
->
server
(
)
->
get
(
'argv'
)
;
// strip the application name
array_shift
(
$
arguments
)
;
return
$
this
->
requestArguments
=
$
arguments
;
}

Get the arguments from the request.

@return array


protected function parseRequestArguments(): void
    {
        // Iterate through the request arguments
        foreach ($this->getRequestArguments() as $argument) {
            // Split the string on an equal sign
            $exploded = explode('=', $argument);

            $key   = $exploded[0];
            $value = $exploded[1] ?? true;
            $type  = 'arguments';

            // If the key has double dash it is a long option
            if (strpos($key, '--') !== false) {
                $type = 'longOptions';
            } // If the key has a single dash it is a short option
            elseif (strpos($key, '-') !== false) {
                $type = 'shortOptions';
            }

            // If the key is already set
            if (isset($this->{$type}[$key])) {
                // If the key isn't already an array
                if (! \is_array($this->{$type}[$key])) {
                    // Make it an array with the current value
                    $this->{$type}[$key] = [$this->{$type}[$key]];
                }

                // Add the next value to the array
                $this->{$type}[$key][] = $value;

                continue;
            }

            // Set the key value pair
            $this->{$type}[$key] = $value;
        }
    }

Parse request arguments to split by options and arguments.

@return void

Parse request arguments to split by options and arguments .