public static function getDetailedMessage($exception)
    {
        $message = $exception->getMessage();

        if (!($exception instanceof ApplicationException) && Config::get('app.debug', FALSE)) {
            $message = sprintf('"%s" on line %s of %s',
                $exception->getMessage(),
                $exception->getLine(),
                $exception->getFile()
            );

            $message .= $exception->getTraceAsString();
        }

        return $message;
    }

public
static
function
getDetailedMessage
(
$
exception
)
{
$
message
=
$
exception
->
getMessage
(
)
;
if
(
!
(
$
exception
instanceof
ApplicationException
)
&&
Config
::
get
(
'app.debug'
,
FALSE
)
)
{
$
message
=
sprintf
(
'"%s" on line %s of %s'
,
$
exception
->
getMessage
(
)
,
$
exception
->
getLine
(
)
,
$
exception
->
getFile
(
)
)
;
$
message
.=
$
exception
->
getTraceAsString
(
)
;
}
return
$
message
;
}

Returns a more descriptive error message if application
debug mode is turned on.
@param Exception $exception
@return string

Returns a more descriptive error message if application debug mode is turned on .


public function mainAction()
    {
        try {
            $host = $this->getHost();
            $port = $this->getPort($host);

            $this->run($host, $port);
        } catch (\Exception $e) {
            $this->block([$e->getMessage()], 'error');
            return;
        }
    }

public function mainAction ( ) { try { $ host = $ this -> getHost ( ) ; $ port = $ this -> getPort ( $ host ) ; $ this -> run ( $ host , $ port ) ; } catch ( \ Exception $ e ) { $ this -> block ( [ $ e -> getMessage ( ) ] , 'error' ) ; return ; } }

Runs a local web server

@option --host : Define the host or ip to use. Default : 127.0.0.1.
@option --port : Define the port to use. Default : 8000.


public function registering()
    {
        $di = $this->getDI();

        $di->set(Services::SESSION_BAG, Bag::class);

        $di->setShared(Services::SESSION, function () {
            /** @var \Phalcon\DiInterface $this */

            $sessionConfig = $this->getShared(Services::CONFIG)->session;

            if (!isset($sessionConfig->adapter)) {
                if (!isset($sessionConfig->stores[$sessionConfig->default])) {
                    throw new \RuntimeException("Session store {$sessionConfig->default} not found in stores");
                }

                $sessionConfig = $sessionConfig->stores[$sessionConfig->default];
            }

            $adapter = $sessionConfig->adapter;

            switch ($adapter){
                case 'Aerospike':
                case 'Database':
                case 'HandlerSocket':
                case 'Mongo':
                case 'Files':
                case 'Libmemcached':
                case 'Memcache':
                case 'Redis':
                    $class = 'Phalcon\Session\Adapter\\' . $adapter;
                    break;
                case FilesAdapter::class:
                case LibmemcachedAdapter::class:
                case MemcacheAdapter::class:
                case RedisAdapter::class:
                    $class = $adapter;
                    break;
                default:
                    $class = $adapter;

                    if(!class_exists($adapter)){
                        throw new \RuntimeException("Session Adapter $class not found.");
                    }
            }

            try {
                $options = [];
                if (!empty($sessionConfig->options)) {
                    $options = $sessionConfig->options->toArray();
                }
                /** @var \Phalcon\Session\Adapter|\Phalcon\Session\AdapterInterface $session */
                $session = new $class($options);
            } catch (\Throwable $e) {
                throw new \RuntimeException("Session Adapter $class construction fail.", $e);
            }

            $session->start();

            return $session;
        });
    }

Start the session the first time some component request the session service

@throws \RuntimeException

@return void


public function toDateTime(DateTime $date = null): DateTime
    {
        if (!$date) {
            $date = new DateTime('1970-01-01 00:00:00');
        }
        elseif (!($date instanceof DateTimeImmutable)) {
            $date = clone $date;
        }

        return $date->setTime($this->hours, $this->minutes);
    }

public
function
toDateTime
(
DateTime
$
date
=
)
:
DateTime
{
if
(
!
$
date
)
{
$
date
=
new
DateTime
(
'1970-01-01 00:00:00'
)
;
}
elseif
(
!
(
$
date
instanceof
DateTimeImmutable
)
)
{
$
date
=
clone
$
date
;
}
return
$
date
->
setTime
(
$
this
->
hours
,
$
this
->
minutes
)
;
}

Convert to DateTime object.

@param \DateTime|null $date
@return \DateTime


public function prepareOutput($file, $strict = false)
    {
        if ($strict && PHP_VERSION_ID < 70000) {
            throw new RuntimeException('Strict mode requires PHP 7 or greater.');
        }

        $dir = dirname($file);
        if (!is_dir($dir) && !mkdir($dir, 0777, true)) {
            throw new RuntimeException("Unable to create directory $dir.");
        }

        $r = fopen($file, 'w');

        if (!$r) {
            throw new RuntimeException("Unable to open $file for writing.");
        }

        if ($strict) {
            fwrite($r, "<?php declare(strict_types=1);\n");
        } else {
            fwrite($r, "<?php\n");
        }

        return $r;
    }

Prepare the output file and directory.

@param string $file
@param bool   $strict Use strict type. Only for PHP7

@return resource


public function getCode($file)
    {
        $stmts = $this->parse($file);
        $stmts = $this->traverse($stmts);
        $content = $this->prettyPrint($stmts);

        return $content;
    }

public function getCode ( $ file ) { $ stmts = $ this -> parse ( $ file ) ; $ stmts = $ this -> traverse ( $ stmts ) ; $ content = $ this -> prettyPrint ( $ stmts ) ; return $ content ; }

Get a pretty printed string of code from a file while applying visitors.

@param string $file

@return string

Get a pretty printed string of code from a file while applying visitors .


public function parse($file)
    {
        if (!is_string($file) || empty($file)) {
            throw new RuntimeException('Invalid filename provided.');
        }

        if (!is_readable($file)) {
            throw new RuntimeException("Cannot open $file for reading.");
        }

        $content = php_strip_whitespace($file);

        return $this->parser->parse($content);
    }

public
function
parse
(
$
file
)
{
if
(
!
is_string
(
$
file
)
||
empty
(
$
file
)
)
{
throw
new
RuntimeException
(
'Invalid filename provided.'
)
;
}
if
(
!
is_readable
(
$
file
)
)
{
throw
new
RuntimeException
(
"Cannot open $file for reading."
)
;
}
$
content
=
php_strip_whitespace
(
$
file
)
;
return
$
this
->
parser
->
parse
(
$
content
)
;
}

Parses PHP code into a node tree.

@param string $file

@return null|\PhpParser\Node[]
@throws \RuntimeException


public function registering()
    {
        $di = $this->getDI();

        $database = (array)$di->getShared(Services::CONFIG)->database;
        $connections = (array)$database['connections'];

        if (count($connections) > 1) {
            $di->setShared(Services::DB, DatabaseStrategy::class);

            foreach ($connections as $name => $connection) {
                $di->setShared(Services::DB . '.' . $name, function () use ($connection) {
                    return new $connection['adapter']((array)$connection['config']);
                });
            }
        } else {
            $connection = array_shift($connections);
            $serviceName = Services::DB . '.' . $database['default'];

            $service = new Service($serviceName, function () use ($connection) {
                return new $connection['adapter']((array)$connection['config']);
            }, true);

            $di->setRaw($serviceName, $service);
            $di->setRaw(Services::DB, $service);
        }
    }

public function registering ( ) { $ di = $ this -> getDI ( ) ; $ database = ( array ) $ di -> getShared ( Services :: CONFIG ) -> database ; $ connections = ( array ) $ database [ 'connections' ] ; if ( count ( $ connections ) > 1 ) { $ di -> setShared ( Services :: DB , DatabaseStrategy :: class ) ; foreach ( $ connections as $ name => $ connection ) { $ di -> setShared ( Services :: DB . '.' . $ name , function ( ) use ( $ connection ) { return new $ connection [ 'adapter' ] ( ( array ) $ connection [ 'config' ] ) ; } ) ; } } else { $ connection = array_shift ( $ connections ) ; $ serviceName = Services :: DB . '.' . $ database [ 'default' ] ; $ service = new Service ( $ serviceName , function ( ) use ( $ connection ) { return new $ connection [ 'adapter' ] ( ( array ) $ connection [ 'config' ] ) ; } , true ) ; $ di -> setRaw ( $ serviceName , $ service ) ; $ di -> setRaw ( Services :: DB , $ service ) ; } }

Database connection is created based in the parameters defined in the configuration file


public function getNodeData($id, $required = FALSE)
    {
        $query = $this->toBase();

        $query->where($this->model->getKeyName(), '=', $id);

        $data = $query->first([$this->model->getLftName(),
            $this->model->getRgtName()]);

        if (!$data && $required) {
            throw new ModelNotFoundException;
        }

        return (array)$data;
    }

public function getNodeData ( $ id , $ required = FALSE ) { $ query = $ this -> toBase ( ) ; $ query -> where ( $ this -> model -> getKeyName ( ) , '=' , $ id ) ; $ data = $ query -> first ( [ $ this -> model -> getLftName ( ) , $ this -> model -> getRgtName ( ) ] ) ; if ( ! $ data && $ required ) { throw new ModelNotFoundException ; } return ( array ) $ data ; }

Get node's `lft` and `rgt` values.

@since 2.0

@param mixed $id
@param bool $required

@return array


public function whereAncestorOf($id, $andSelf = FALSE, $boolean = 'and')
    {
        $keyName = $this->model->getKeyName();

        if (NestedSet::isNode($id)) {
            $value = '?';

            $this->query->addBinding($id->getRgt());

            $id = $id->getKey();
        }
        else {
            $valueQuery = $this->model
                ->newQuery()
                ->toBase()
                ->select("_.".$this->model->getRgtName())
                ->from($this->model->getTable().' as _')
                ->where($keyName, '=', $id)
                ->limit(1);

            $this->query->mergeBindings($valueQuery);

            $value = '('.$valueQuery->toSql().')';
        }

        $this->query->whereNested(function ($inner) use ($value, $andSelf, $id) {
            list($lft, $rgt) = $this->wrappedColumns();

            $inner->whereRaw("{$value} between {$lft} and {$rgt}");

            if (!$andSelf) {
                $inner->where($this->model->getKeyName(), '<>', $id);
            }
        }, $boolean);

        return $this;
    }

public
function
whereAncestorOf
(
$
id
,
$
andSelf
=
FALSE
,
$
boolean
=
'and'
)
{
$
keyName
=
$
this
->
model
->
getKeyName
(
)
;
if
(
NestedSet
::
isNode
(
$
id
)
)
{
$
value
=
'?'
;
$
this
->
query
->
addBinding
(
$
id
->
getRgt
(
)
)
;
$
id
=
$
id
->
getKey
(
)
;
}
else
{
$
valueQuery
=
$
this
->
model
->
newQuery
(
)
->
toBase
(
)
->
select
(
"_."
.
$
this
->
model
->
getRgtName
(
)
)
->
from
(
$
this
->
model
->
getTable
(
)
.
' as _'
)
->
where
(
$
keyName
,
'='
,
$
id
)
->
limit
(
1
)
;
$
this
->
query
->
mergeBindings
(
$
valueQuery
)
;
$
value
=
'('
.
$
valueQuery
->
toSql
(
)
.
')'
;
}
$
this
->
query
->
whereNested
(
function
(
$
inner
)
use
(
$
value
,
$
andSelf
,
$
id
)
{
list
(
$
lft
,
$
rgt
)
=
$
this
->
wrappedColumns
(
)
;
$
inner
->
whereRaw
(
"{$value} between {$lft} and {$rgt}"
)
;
if
(
!
$
andSelf
)
{
$
inner
->
where
(
$
this
->
model
->
getKeyName
(
)
,
'<>'
,
$
id
)
;
}
}
,
$
boolean
)
;
return
$
this
;
}

Limit results to ancestors of specified node.

@since 2.0

@param mixed $id
@param bool $andSelf

@param string $boolean

@return $this

Limit results to ancestors of specified node .


public function whereNodeBetween($values, $boolean = 'and', $not = FALSE)
    {
        $this->query->whereBetween($this->model->getLftName(), $values, $boolean, $not);

        return $this;
    }

public function whereNodeBetween ( $ values , $ boolean = 'and' , $ not = FALSE ) { $ this -> query -> whereBetween ( $ this -> model -> getLftName ( ) , $ values , $ boolean , $ not ) ; return $ this ; }

Add node selection statement between specified range.

@since 2.0

@param array $values
@param string $boolean
@param bool $not

@return $this

Add node selection statement between specified range .


public function whereDescendantOf($id, $boolean = 'and', $not = FALSE,
        $andSelf = FALSE
    )
    {
        if (NestedSet::isNode($id)) {
            $data = $id->getBounds();
        }
        else {
            $data = $this->model->newNestedSetQuery()
                                ->getPlainNodeData($id, TRUE);
        }

        // Don't include the node
        if (!$andSelf) {
            ++$data[0];
        }

        return $this->whereNodeBetween($data, $boolean, $not);
    }

public
function
whereDescendantOf
(
$
id
,
$
boolean
=
'and'
,
$
not
=
FALSE
,
$
andSelf
=
FALSE
)
{
if
(
NestedSet
::
isNode
(
$
id
)
)
{
$
data
=
$
id
->
getBounds
(
)
;
}
else
{
$
data
=
$
this
->
model
->
newNestedSetQuery
(
)
->
getPlainNodeData
(
$
id
,
TRUE
)
;
}
// Don't include the node
if
(
!
$
andSelf
)
{
++
$
data
[
0
]
;
}
return
$
this
->
whereNodeBetween
(
$
data
,
$
boolean
,
$
not
)
;
}

Add constraint statement to descendants of specified node.

@since 2.0

@param mixed $id
@param string $boolean
@param bool $not
@param bool $andSelf

@return $this

Add constraint statement to descendants of specified node .


public function descendantsOf($id, array $columns = ['*'], $andSelf = FALSE)
    {
        try {
            return $this->whereDescendantOf($id, 'and', FALSE, $andSelf)->get($columns);
        } catch (ModelNotFoundException $e) {
            return $this->model->newCollection();
        }
    }

public function descendantsOf ( $ id , array $ columns = [ '*' ] , $ andSelf = FALSE ) { try { return $ this -> whereDescendantOf ( $ id , 'and' , FALSE , $ andSelf ) -> get ( $ columns ) ; } catch ( ModelNotFoundException $ e ) { return $ this -> model -> newCollection ( ) ; } }

Get descendants of specified node.

@since 2.0

@param mixed $id
@param array $columns
@param bool $andSelf

@return Collection


public function withDepth($as = 'depth')
    {
        if ($this->query->columns === null) $this->query->columns = ['*'];

        $table = $this->wrappedTable();

        list($lft, $rgt) = $this->wrappedColumns();

        $alias = '_d';
        $wrappedAlias = $this->query->getGrammar()->wrapTable($alias);

        $query = $this->model
            ->newScopedQuery('_d')
            ->toBase()
            ->selectRaw('count(1) - 1')
            ->from($this->model->getTable().' as '.$alias)
            ->whereRaw("{$table}.{$lft} between {$wrappedAlias}.{$lft} and {$wrappedAlias}.{$rgt}");

        $this->query->selectSub($query, $as);

        return $this;
    }

Include depth level into the result.

@param string $as

@return $this


protected function wrappedColumns()
    {
        $grammar = $this->query->getGrammar();

        return [
            $grammar->wrap($this->model->getLftName()),
            $grammar->wrap($this->model->getRgtName()),
        ];
    }

protected function wrappedColumns ( ) { $ grammar = $ this -> query -> getGrammar ( ) ; return [ $ grammar -> wrap ( $ this -> model -> getLftName ( ) ) , $ grammar -> wrap ( $ this -> model -> getRgtName ( ) ) , ] ; }

Get wrapped `lft` and `rgt` column names.

@since 2.0

@return array


public function hasChildren()
    {
        list($lft, $rgt) = $this->wrappedColumns();

        $this->query->whereRaw("{$rgt} > {$lft} + 1");

        return $this;
    }

public
function
hasChildren
(
)
{
list
(
$
lft
,
$
rgt
)
=
$
this
->
wrappedColumns
(
)
;
$
this
->
query
->
whereRaw
(
"{$rgt} > {$lft} + 1"
)
;
return
$
this
;
}

Get only nodes that have children.

@since 2.0
@deprecated since v4.1

@return $this


public function defaultOrder($dir = 'asc')
    {
        $this->query->orders = null;

        $this->query->orderBy($this->model->getLftName(), $dir);

        return $this;
    }

public function defaultOrder ( $ dir = 'asc' ) { $ this -> query -> orders = null ; $ this -> query -> orderBy ( $ this -> model -> getLftName ( ) , $ dir ) ; return $ this ; }

Order by node position.

@param string $dir

@return $this


public function moveNode($key, $position)
    {
        list($lft, $rgt) = $this->model->newNestedSetQuery()
                                       ->getPlainNodeData($key, TRUE);

        if ($lft < $position && $position <= $rgt) {
            throw new LogicException('Cannot move node into itself.');
        }

        // Get boundaries of nodes that should be moved to new position
        $from = min($lft, $position);
        $to = max($rgt, $position - 1);

        // The height of node that is being moved
        $height = $rgt - $lft + 1;

        // The distance that our node will travel to reach it's destination
        $distance = $to - $from + 1 - $height;

        // If no distance to travel, just return
        if ($distance === 0) {
            return 0;
        }

        if ($position > $lft) {
            $height *= -1;
        }
        else {
            $distance *= -1;
        }

        $params = compact('lft', 'rgt', 'from', 'to', 'height', 'distance');

        $boundary = [$from, $to];

        $query = $this->toBase()->where(function (Query $inner) use ($boundary) {
            $inner->whereBetween($this->model->getLftName(), $boundary);
            $inner->orWhereBetween($this->model->getRgtName(), $boundary);
        });

        return $query->update($this->patch($params));
    }

Move a node to the new position.

@param mixed $key
@param int $position

@return int


public function makeGap($cut, $height)
    {
        $params = compact('cut', 'height');

        $query = $this->toBase()->whereNested(function (Query $inner) use ($cut) {
            $inner->where($this->model->getLftName(), '>=', $cut);
            $inner->orWhere($this->model->getRgtName(), '>=', $cut);
        });

        return $query->update($this->patch($params));
    }

public function makeGap ( $ cut , $ height ) { $ params = compact ( 'cut' , 'height' ) ; $ query = $ this -> toBase ( ) -> whereNested ( function ( Query $ inner ) use ( $ cut ) { $ inner -> where ( $ this -> model -> getLftName ( ) , '>=' , $ cut ) ; $ inner -> orWhere ( $ this -> model -> getRgtName ( ) , '>=' , $ cut ) ; } ) ; return $ query -> update ( $ this -> patch ( $ params ) ) ; }

Make or remove gap in the tree. Negative height will remove gap.

@since 2.0

@param int $cut
@param int $height

@return int

Make or remove gap in the tree . Negative height will remove gap .


protected function patch(array $params)
    {
        $grammar = $this->query->getGrammar();

        $columns = [];

        foreach ([$this->model->getLftName(), $this->model->getRgtName()] as $col) {
            $columns[$col] = $this->columnPatch($grammar->wrap($col), $params);
        }

        return $columns;
    }

protected function patch ( array $ params ) { $ grammar = $ this -> query -> getGrammar ( ) ; $ columns = [ ] ; foreach ( [ $ this -> model -> getLftName ( ) , $ this -> model -> getRgtName ( ) ] as $ col ) { $ columns [ $ col ] = $ this -> columnPatch ( $ grammar -> wrap ( $ col ) , $ params ) ; } return $ columns ; }

Get patch for columns.

@since 2.0

@param array $params

@return array


protected function columnPatch($col, array $params)
    {
        extract($params);

        /** @var int $height */
        if ($height > 0) $height = '+'.$height;

        if (isset($cut)) {
            return new Expression("case when {$col} >= {$cut} then {$col}{$height} else {$col} end");
        }

        /** @var int $distance */
        /** @var int $lft */
        /** @var int $rgt */
        /** @var int $from */
        /** @var int $to */
        if ($distance > 0) $distance = '+'.$distance;

        return new Expression("case ".
            "when {$col} between {$lft} and {$rgt} then {$col}{$distance} ". // Move the node
            "when {$col} between {$from} and {$to} then {$col}{$height} ". // Move other nodes
            "else {$col} end"
        );
    }

Get patch for single column.

@since 2.0

@param string $col
@param array $params

@return string


public function countErrors()
    {
        $checks = [];

        // Check if lft and rgt values are ok
        $checks['oddness'] = $this->getOdnessQuery();

        // Check if lft and rgt values are unique
        $checks['duplicates'] = $this->getDuplicatesQuery();

        // Check if parent_id is set correctly
        $checks['wrong_parent'] = $this->getWrongParentQuery();

        // Check for nodes that have missing parent
        $checks['missing_parent'] = $this->getMissingParentQuery();

        $query = $this->query->newQuery();

        foreach ($checks as $key => $inner) {
            $inner->selectRaw('count(1)');

            $query->selectSub($inner, $key);
        }

        return (array)$query->first();
    }

Get statistics of errors of the tree.

@since 2.0

@return array


public function fixTree()
    {
        $columns = [
            $this->model->getKeyName(),
            $this->model->getParentIdName(),
            $this->model->getLftName(),
            $this->model->getRgtName(),
        ];

        $dictionary = $this->model->newNestedSetQuery()
                                  ->defaultOrder()
                                  ->get($columns)
                                  ->groupBy($this->model->getParentIdName())
                                  ->all();

        return self::fixNodes($dictionary);
    }

public function fixTree ( ) { $ columns = [ $ this -> model -> getKeyName ( ) , $ this -> model -> getParentIdName ( ) , $ this -> model -> getLftName ( ) , $ this -> model -> getRgtName ( ) , ] ; $ dictionary = $ this -> model -> newNestedSetQuery ( ) -> defaultOrder ( ) -> get ( $ columns ) -> groupBy ( $ this -> model -> getParentIdName ( ) ) -> all ( ) ; return self :: fixNodes ( $ dictionary ) ; }

Fixes the tree based on parentage info.

Nodes with invalid parent are saved as roots.

@return int The number of fixed nodes

Fixes the tree based on parentage info .


public function rebuildTree(array $data, $delete = FALSE)
    {
        if ($this->model->usesSoftDelete()) {
            $this->withTrashed();
        }

        $existing = $this->get()->getDictionary();
        $dictionary = [];

        $this->buildRebuildDictionary($dictionary, $data, $existing);

        if (!empty($existing)) {
            if ($delete && !$this->model->usesSoftDelete()) {
                $this->model
                    ->newScopedQuery()
                    ->whereIn($this->model->getKeyName(), array_keys($existing))
                    ->delete();
            }
            else {
                foreach ($existing as $model) {
                    $dictionary[$model->getParentId()][] = $model;

                    if ($delete && $this->model->usesSoftDelete() &&
                        !$model->{$model->getDeletedAtColumn()}
                    ) {
                        $time = $this->model->fromDateTime($this->model->freshTimestamp());

                        $model->{$model->getDeletedAtColumn()} = $time;
                    }
                }
            }
        }

        return $this->fixNodes($dictionary);
    }

public function rebuildTree ( array $ data , $ delete = FALSE ) { if ( $ this -> model -> usesSoftDelete ( ) ) { $ this -> withTrashed ( ) ; } $ existing = $ this -> get ( ) -> getDictionary ( ) ; $ dictionary = [ ] ; $ this -> buildRebuildDictionary ( $ dictionary , $ data , $ existing ) ; if ( ! empty ( $ existing ) ) { if ( $ delete && ! $ this -> model -> usesSoftDelete ( ) ) { $ this -> model -> newScopedQuery ( ) -> whereIn ( $ this -> model -> getKeyName ( ) , array_keys ( $ existing ) ) -> delete ( ) ; } else { foreach ( $ existing as $ model ) { $ dictionary [ $ model -> getParentId ( ) ] [ ] = $ model ; if ( $ delete && $ this -> model -> usesSoftDelete ( ) && ! $ model -> { $ model -> getDeletedAtColumn ( ) } ) { $ time = $ this -> model -> fromDateTime ( $ this -> model -> freshTimestamp ( ) ) ; $ model -> { $ model -> getDeletedAtColumn ( ) } = $ time ; } } } } return $ this -> fixNodes ( $ dictionary ) ; }

Rebuild the tree based on raw data.

If item data does not contain primary key, new node will be created.

@param array $data
@param bool $delete Whether to delete nodes that exists but not in the data
array

@return int


public static function bootPurgeable()
    {
        if (!property_exists(get_called_class(), 'purgeable'))
            throw new Exception(sprintf(
                'You must define a $purgeable property in %s to use the Purgeable trait.', get_called_class()
            ));

        /*
         * Remove any purge attributes from the data set
         */
        static::extend(function ($model) {
            $model->bindEvent('model.saveInternal', function () use ($model) {
                $model->purgeAttributes();
            });
        });
    }

Boot the purgeable trait for a model.
@return void
@throws \Exception


public function addPurgeable($attributes = null)
    {
        $attributes = is_array($attributes) ? $attributes : func_get_args();

        $this->purgeable = array_merge($this->purgeable, $attributes);

        return $this;
    }

public function addPurgeable ( $ attributes = null ) { $ attributes = is_array ( $ attributes ) ? $ attributes : func_get_args ( ) ; $ this -> purgeable = array_merge ( $ this -> purgeable , $ attributes ) ; return $ this ; }

Adds an attribute to the purgeable attributes list

@param  array|string|null $attributes

@return $this


public function purgeAttributes($attributesToPurge = null)
    {
        if ($attributesToPurge !== null) {
            $purgeable = is_array($attributesToPurge) ? $attributesToPurge : [$attributesToPurge];
        }
        else {
            $purgeable = $this->getPurgeableAttributes();
        }

        $attributes = $this->getAttributes();
        $cleanAttributes = array_diff_key($attributes, array_flip($purgeable));
        $originalAttributes = array_diff_key($attributes, $cleanAttributes);

        if (is_array($this->originalPurgeableValues)) {
            $this->originalPurgeableValues = array_merge($this->originalPurgeableValues, $originalAttributes);
        }
        else {
            $this->originalPurgeableValues = $originalAttributes;
        }

        return $this->attributes = $cleanAttributes;
    }

public function purgeAttributes ( $ attributesToPurge = null ) { if ( $ attributesToPurge !== null ) { $ purgeable = is_array ( $ attributesToPurge ) ? $ attributesToPurge : [ $ attributesToPurge ] ; } else { $ purgeable = $ this -> getPurgeableAttributes ( ) ; } $ attributes = $ this -> getAttributes ( ) ; $ cleanAttributes = array_diff_key ( $ attributes , array_flip ( $ purgeable ) ) ; $ originalAttributes = array_diff_key ( $ attributes , $ cleanAttributes ) ; if ( is_array ( $ this -> originalPurgeableValues ) ) { $ this -> originalPurgeableValues = array_merge ( $ this -> originalPurgeableValues , $ originalAttributes ) ; } else { $ this -> originalPurgeableValues = $ originalAttributes ; } return $ this -> attributes = $ cleanAttributes ; }

Removes purged attributes, used before saving.

@param null $attributesToPurge

@return array Clean attributes

Removes purged attributes used before saving .


public function getOriginalPurgeValue($attribute)
    {
        return isset($this->originalPurgeableValues[$attribute])
            ? $this->originalPurgeableValues[$attribute]
            : null;
    }

public function getOriginalPurgeValue ( $ attribute ) { return isset ( $ this -> originalPurgeableValues [ $ attribute ] ) ? $ this -> originalPurgeableValues [ $ attribute ] : null ; }

Returns the original value of a single attribute.

@param $attribute

@return null

Returns the original value of a single attribute .


public function get($key, $default = null)
    {
        $this->load();

        return Arr::get($this->items, $key, $default);
    }

public function get ( $ key , $ default = null ) { $ this -> load ( ) ; return Arr :: get ( $ this -> items , $ key , $ default ) ; }

Get a specific key from the settings data.

@param  string|array $key
@param  mixed $default Optional default value.

@return mixed

Get a specific key from the settings data .


public function set($key, $value = null)
    {
        $this->load();
        $this->unsaved = TRUE;

        if (is_array($key)) {
            foreach ($key as $k => $v) {
                Arr::set($this->items, $k, $v);
            }
        }
        else {
            Arr::set($this->items, $key, $value);
        }

        return $this;
    }

public function set ( $ key , $ value = null ) { $ this -> load ( ) ; $ this -> unsaved = TRUE ; if ( is_array ( $ key ) ) { foreach ( $ key as $ k => $ v ) { Arr :: set ( $ this -> items , $ k , $ v ) ; } } else { Arr :: set ( $ this -> items , $ key , $ value ) ; } return $ this ; }

Set a specific key to a value in the settings data.

@param string|array $key Key string or associative array of key => value
@param mixed $value Optional only if the first argument is an array

Set a specific key to a value in the settings data .


public function forget($key)
    {
        $this->unsaved = TRUE;

        if ($this->has($key)) {
            Arr::forget($this->items, $key);
        }
    }

public function forget ( $ key ) { $ this -> unsaved = TRUE ; if ( $ this -> has ( $ key ) ) { Arr :: forget ( $ this -> items , $ key ) ; } }

Unset a key in the settings data.

@param  string $key


public function save()
    {
        if (!$this->unsaved) {
            // either nothing has been changed, or data has not been loaded, so
            // do nothing by returning early
            return;
        }

        $this->write($this->items);
        $this->unsaved = FALSE;
    }

Save any changes done to the settings data.
@return void

Save any changes done to the settings data .


public function load($force = FALSE)
    {
        if (!$this->loaded || $force) {
            $this->items = $this->read();
            $this->loaded = TRUE;
        }
    }

public function load ( $ force = FALSE ) { if ( ! $ this -> loaded || $ force ) { $ this -> items = $ this -> read ( ) ; $ this -> loaded = TRUE ; } }

Make sure data is loaded.

@param bool $force Force a reload of data. Default false.


public function compileFunction($name, $arguments, $funcArguments)
    {
        if (!Str::startsWith($name, 'str_') || function_exists($name)) {
            return null;
        }

        $name = substr($name, 4);

        if (method_exists(Str::class, $name) && Reflexion::getReflectionMethod(Str::class, $name)->isPublic()) {
            return Str::class . '::' . $name . '(' . $arguments . ')';
        }

        return null;
    }

public function compileFunction ( $ name , $ arguments , $ funcArguments ) { if ( ! Str :: startsWith ( $ name , 'str_' ) || function_exists ( $ name ) ) { return null ; } $ name = substr ( $ name , 4 ) ; if ( method_exists ( Str :: class , $ name ) && Reflexion :: getReflectionMethod ( Str :: class , $ name ) -> isPublic ( ) ) { return Str :: class . '::' . $ name . '(' . $ arguments . ')' ; } return null ; }

This method is called on any attempt to compile a function call

@param $name
@param $arguments

@return null|string


public function mainAction()
    {
        if (APP_DEBUG && !$this->hasOption('f', 'force')) {
            $this->info('Application is in debug mode.');
            $this->info('For optimize in debug please use the --force, -f option.');

            return;
        }

        $this->optimizer = $this->getDI()->get(Composer::class, [
            BASE_PATH . '/bootstrap/compile/loader.php',
            BASE_PATH . '/vendor/composer',
            BASE_PATH
        ]);

        if ($this->hasOption('m', 'memory')) {
            $this->optimizeMemory();
        } else {
            $this->optimizeProcess();
        }

        $this->optimizeClass();

        foreach ($this->compileTasks as $compileTask) {
            $this->application->handle([
                'task' => $compileTask
            ]);
        }
    }

Runs all optimization

@description Runs all optimization.

@option      -m, --memory: Generate a memory optimized autoloader.
@option      -f, --force: Force optimization.


public function after(Event $event, $source, $data = null)
    {
        $this->addHeader($this->resolveRequestSignature(), false);

        return true;
    }

public function after ( Event $ event , $ source , $ data = null ) { $ this -> addHeader ( $ this -> resolveRequestSignature ( ) , false ) ; return true ; }

Called after the execution of handler

@param \Phalcon\Events\Event|mixed $event
@param \Phalcon\Dispatcher|mixed   $source
@param mixed|null                  $data

@throws \Exception
@return bool


protected function addHeader($signature, $tooManyAttempts = false)
    {
        /** @var \Phalcon\Http\Response $response */
        $response = $this->getDI()->getShared(Services::RESPONSE);

        $limiter = $this->getLimiter();

        $response->setHeader('X-RateLimit-Limit', $this->max);
        if ($tooManyAttempts) {
            $msg = StatusCode::message(StatusCode::TOO_MANY_REQUESTS);

            $response
                ->setContent($msg)
                ->setStatusCode(StatusCode::TOO_MANY_REQUESTS, $msg)
                ->setHeader('X-RateLimit-Remaining', 0)
                ->setHeader(
                'Retry-After',
                $limiter->availableIn($signature, $this->decay)
            );
        } else {
            $response->setHeader(
                'X-RateLimit-Remaining',
                $limiter->retriesLeft($signature, $this->max, $this->decay)
            );
        }
    }

Add the limit header information to the response.

@param string $signature
@param bool   $tooManyAttempts Bind specific values when there are too many attempts

Add the limit header information to the response .


protected function getLimiter()
    {
        if (!isset($this->limiter)) {
            $this->limiter = $this->getDI()->get(RateLimiter::class, [$this->name]);
        }

        return $this->limiter;
    }

protected function getLimiter ( ) { if ( ! isset ( $ this -> limiter ) ) { $ this -> limiter = $ this -> getDI ( ) -> get ( RateLimiter :: class , [ $ this -> name ] ) ; } return $ this -> limiter ; }

Bind and return the limiter instance.

@return \Neutrino\Security\RateLimiter


public function update($attributes = [])
    {
        $attributes = array_filter($attributes);

        foreach ($attributes as $key => $attribute) {
            $this->$key = $attribute;
        }

        return $this;
    }

public function update ( $ attributes = [ ] ) { $ attributes = array_filter ( $ attributes ) ; foreach ( $ attributes as $ key => $ attribute ) { $ this -> $ key = $ attribute ; } return $ this ; }

Update the attributes.

@param  array $attributes

@return $this


public function log($file, $batch)
    {
        $record = ['migration' => $file, 'group' => $this->getGroup(), 'batch' => $batch];

        $this->table()->insert($record);
    }

public function log ( $ file , $ batch ) { $ record = [ 'migration' => $ file , 'group' => $ this -> getGroup ( ) , 'batch' => $ batch ] ; $ this -> table ( ) -> insert ( $ record ) ; }

Log that a migration was run.
Overrides the parent method and allows insertion of group data

@param  string $file
@param  int $batch

@return void

Log that a migration was run . Overrides the parent method and allows insertion of group data


public function createRepository()
    {
        $schema = $this->getConnection()->getSchemaBuilder();

        $method = (!$schema->hasTable($this->table))
            ? 'create' : 'table';

        $schema->$method($this->table, function (Blueprint $table) use ($method) {
            // Drop old columns from CI_Migration library
            if ($method == 'table') {
                $table->dropColumn('type');
                $table->dropColumn('version');
            }

            // The migrations table is responsible for keeping track of which of the
            // migrations have actually run for the application. We'll create the
            // table to hold the migration file's path as well as the batch ID.
            $table->increments('id');
            $table->string('group');
            $table->string('migration');
            $table->integer('batch');
        });
    }

Create the migration repository data store.
@return void

Create the migration repository data store .


protected function table()
    {
        return $this->getConnection()
                    ->table($this->table)
                    ->where('group', $this->getGroup())
                    ->useWritePdo();
    }

protected function table ( ) { return $ this -> getConnection ( ) -> table ( $ this -> table ) -> where ( 'group' , $ this -> getGroup ( ) ) -> useWritePdo ( ) ; }

Get a query builder for the migration table.
@return \Illuminate\Database\Query\Builder

Get a query builder for the migration table .


public function getDatabaseName()
	{
		$dsn = $this->result->connection->getDsn();
		$matches = [];
		if (preg_match('~\b(database|dbname)=(.*?)(;|$)~', $dsn, $matches))
		{
			return $matches[2];
		}
		return NULL;
	}

public function getDatabaseName ( ) { $ dsn = $ this -> result -> connection -> getDsn ( ) ; $ matches = [ ] ; if ( preg_match ( '~\b(database|dbname)=(.*?)(;|$)~' , $ dsn , $ matches ) ) { return $ matches [ 2 ] ; } return NULL ; }

Database name, fulltext index or similar, NULL if not applicable

@return NULL|string

Database name fulltext index or similar NULL if not applicable


public function setAttribute($key, $value = null)
    {
        if (is_null($value)) {
            $this->getAttributeMap()->remove($key);
        } else {
            $this->getAttributeMap()->set($key, $value);
        }
        return $this;
    }

public function setAttribute ( $ key , $ value = null ) { if ( is_null ( $ value ) ) { $ this -> getAttributeMap ( ) -> remove ( $ key ) ; } else { $ this -> getAttributeMap ( ) -> set ( $ key , $ value ) ; } return $ this ; }

set attribute to html element

@param       string      $key        html element attribute key
@param       string      $value      html element attribute value
@return      HtmlElementAbstract


public function appendAttribute($key, $value = null, $seperater = null)
    {
        if (!is_null($value)) {
            if ($this->getAttributeMap()->hasKey($key)) {
                if (strlen($seperater) > 0) {
                    $values = array();
                    $values[] = $this->getAttributeMap()->get($key);
                    $values[] = $value;
                    $newValue = implode($seperater, $values);
                } else {
                    $newValue = $this->getAttributeMap()->get($key) . $value;
                }
            } else {
                $newValue = $value;
            }
            $this->getAttributeMap()->set($key, $newValue);
        }
        return $this;
    }

public function appendAttribute ( $ key , $ value = null , $ seperater = null ) { if ( ! is_null ( $ value ) ) { if ( $ this -> getAttributeMap ( ) -> hasKey ( $ key ) ) { if ( strlen ( $ seperater ) > 0 ) { $ values = array ( ) ; $ values [ ] = $ this -> getAttributeMap ( ) -> get ( $ key ) ; $ values [ ] = $ value ; $ newValue = implode ( $ seperater , $ values ) ; } else { $ newValue = $ this -> getAttributeMap ( ) -> get ( $ key ) . $ value ; } } else { $ newValue = $ value ; } $ this -> getAttributeMap ( ) -> set ( $ key , $ newValue ) ; } return $ this ; }

append attribute to html element

@param       string      $key        html element attribute key
@param       string      $value      html element attribute value
@param       string      $seperater  html element attribute seperater
@return      HtmlElementAbstract


public function setContent($content)
    {
        if (!is_null($content)) {
            if ($content instanceof HtmlElementInterface) {
                $htmlElementObject = $content;
            } else {
                $htmlElementObject = new HtmlElementContent($content);
            }
            $this->getChildElementCollection()->clear();
            $this->getChildElementCollection()->add($htmlElementObject);
        }
        return $this;
    }

public function setContent ( $ content ) { if ( ! is_null ( $ content ) ) { if ( $ content instanceof HtmlElementInterface ) { $ htmlElementObject = $ content ; } else { $ htmlElementObject = new HtmlElementContent ( $ content ) ; } $ this -> getChildElementCollection ( ) -> clear ( ) ; $ this -> getChildElementCollection ( ) -> add ( $ htmlElementObject ) ; } return $ this ; }

set html element content, replace all child elements

@param       string      $content        html element content
@return      HtmlElementAbstract

set html element content replace all child elements


public function addContent($content = null)
    {
        if (!is_null($content)) {
            $htmlElementObject = new HtmlElementContent($content);
            $this->getChildElementCollection()->add($htmlElementObject);
        }
        return $this;
    }

public function addContent ( $ content = null ) { if ( ! is_null ( $ content ) ) { $ htmlElementObject = new HtmlElementContent ( $ content ) ; $ this -> getChildElementCollection ( ) -> add ( $ htmlElementObject ) ; } return $ this ; }

add html element content

@param       string      $content        html element content
@return      HtmlElementAbstract


protected function registerCommands(array $commands)
    {
        foreach ($commands as $class => $command) {
            $this->{"register{$class}Command"}($command);
        }

        $this->commands(array_values($commands));
    }

protected function registerCommands ( array $ commands ) { foreach ( $ commands as $ class => $ command ) { $ this -> { "register{$class}Command" } ( $ command ) ; } $ this -> commands ( array_values ( $ commands ) ) ; }

Register the given commands.

@param  array $commands

@return void


public function mainAction()
    {
        $this->output->write(Decorate::notice(str_pad('Generating http-routes cache', 40, ' ')), false);

        try {
            $router = $this->loadHttpRouter();

            $str = $this->compile($router);

            file_put_contents(BASE_PATH . '/bootstrap/compile/http-routes.php', "<?php\n$str");

            $this->info("Success");
        } catch (\Exception $e) {
            $this->error("Error");
            $this->block([$e->getMessage()], 'error');

            @unlink(BASE_PATH . '/bootstrap/compile/http-routes.php');
        }
    }

public
function
mainAction
(
)
{
$
this
->
output
->
write
(
Decorate
::
notice
(
str_pad
(
'Generating http-routes cache'
,
40
,
' '
)
)
,
false
)
;
try
{
$
router
=
$
this
->
loadHttpRouter
(
)
;
$
str
=
$
this
->
compile
(
$
router
)
;
file_put_contents
(
BASE_PATH
.
'/bootstrap/compile/http-routes.php'
,
"<?php\n$str"
)
;
$
this
->
info
(
"Success"
)
;
}
catch
(
\
Exception
$
e
)
{
$
this
->
error
(
"Error"
)
;
$
this
->
block
(
[
$
e
->
getMessage
(
)
]
,
'error'
)
;
@
unlink
(
BASE_PATH
.
'/bootstrap/compile/http-routes.php'
)
;
}
}

Generate a cache for http kernel's routes.

Generate a cache for http kernel s routes .


public static function getQueries(\Closure $callback, $pretend = false)
    {
        $db = Di::getDefault()->get(Services::DB);

        if (is_null($em = $db->getEventsManager())) {
            $db->setEventsManager($em = new Manager());
        }

        $queries = [];

        $listener = function (Event $event, Adapter $db) use (&$queries, $pretend) {
            $queries[] = $db->getRealSQLStatement();

            if ($pretend && $event->isCancelable()) {
                $event->stop();
            }

            return !$pretend;
        };

        $em->attach(Events\Db::BEFORE_QUERY, $listener);

        $callback();

        $em->detach(Events\Db::BEFORE_QUERY, $listener);

        return $queries;
    }

public static function getQueries ( \ Closure $ callback , $ pretend = false ) { $ db = Di :: getDefault ( ) -> get ( Services :: DB ) ; if ( is_null ( $ em = $ db -> getEventsManager ( ) ) ) { $ db -> setEventsManager ( $ em = new Manager ( ) ) ; } $ queries = [ ] ; $ listener = function ( Event $ event , Adapter $ db ) use ( & $ queries , $ pretend ) { $ queries [ ] = $ db -> getRealSQLStatement ( ) ; if ( $ pretend && $ event -> isCancelable ( ) ) { $ event -> stop ( ) ; } return ! $ pretend ; } ; $ em -> attach ( Events \ Db :: BEFORE_QUERY , $ listener ) ; $ callback ( ) ; $ em -> detach ( Events \ Db :: BEFORE_QUERY , $ listener ) ; return $ queries ; }

Return queries randed behind callback.

@param \Closure $callback
@param bool     $pretend

@return array


public function tooManyAttempts($key, $maxAttempts, $decaySeconds = 1)
    {
        /** @var \Neutrino\Cache\CacheStrategy $cache */
        $cache = $this->{Services::CACHE};

        if ($cache->exists($this->name . $key . $this->klock, $decaySeconds)) {
            return true;
        }
        if ($this->attempts($key, $decaySeconds) >= $maxAttempts) {
            $cache->save(
                $this->name . $key . $this->klock,
                time() + ($decaySeconds),
                $decaySeconds
            );

            $this->resetAttempts($key);

            return true;
        }

        return false;
    }

Determine if the given key has been "accessed" too many times.

@param  string $key
@param  int    $maxAttempts
@param  int    $decaySeconds

@return bool

Determine if the given key has been accessed too many times .


public function hit($key, $decaySeconds = 1)
    {
        $key = $this->name . $key;

        /** @var \Neutrino\Cache\CacheStrategy $cache */
        $cache = $this->{Services::CACHE};

        if (!$cache->exists($key, $decaySeconds)) {
            $cache->save($key, 0, $decaySeconds);
        }

        $value = (int)$cache->get($key, $decaySeconds);

        $value++;
        $cache->save($key, $value, $decaySeconds);

        return $value;
    }

Increment the counter for a given key for a given decay time.

@param  string $key
@param  int    $decaySeconds

@return int

Increment the counter for a given key for a given decay time .


public function attempts($key, $decaySeconds = 1)
    {
        $value = $this->{Services::CACHE}->get($this->name . $key, $decaySeconds);

        return is_null($value) ? 0 : (int)$value;
    }

public function attempts ( $ key , $ decaySeconds = 1 ) { $ value = $ this -> { Services :: CACHE } -> get ( $ this -> name . $ key , $ decaySeconds ) ; return is_null ( $ value ) ? 0 : ( int ) $ value ; }

Get the number of attempts for the given key.

@param  string $key
@param  int    $decaySeconds

@return mixed

Get the number of attempts for the given key .


public function clear($key)
    {
        $this->resetAttempts($key);

        $this->{Services::CACHE}->delete($this->name . $key . $this->klock);
    }

public function clear ( $ key ) { $ this -> resetAttempts ( $ key ) ; $ this -> { Services :: CACHE } -> delete ( $ this -> name . $ key . $ this -> klock ) ; }

Clear the hits and lockout for the given key.

@param  string $key

@return void

Clear the hits and lockout for the given key .


public function availableIn($key, $decaySeconds)
    {
        $time = $this->{Services::CACHE}->get($this->name . $key . $this->klock, $decaySeconds);

        return $time - time();
    }

public function availableIn ( $ key , $ decaySeconds ) { $ time = $ this -> { Services :: CACHE } -> get ( $ this -> name . $ key . $ this -> klock , $ decaySeconds ) ; return $ time - time ( ) ; }

Get the number of seconds until the "key" is accessible again.

@param  string $key
@param  int    $decaySeconds

@return int

Get the number of seconds until the key is accessible again .


public function mainAction()
    {
        $this->output->write(Decorate::notice(str_pad('Generating dotconst cache', 40, ' ')), false);

        try {
            self::generateCache();

            $this->info("Success");
        } catch (\Exception $e) {
            $this->error("Error");
            $this->block([$e->getMessage()], 'error');
        }
    }

public
function
mainAction
(
)
{
$
this
->
output
->
write
(
Decorate
::
notice
(
str_pad
(
'Generating dotconst cache'
,
40
,
' '
)
)
,
false
)
;
try
{
self
::
generateCache
(
)
;
$
this
->
info
(
"Success"
)
;
}
catch
(
\
Exception
$
e
)
{
$
this
->
error
(
"Error"
)
;
$
this
->
block
(
[
$
e
->
getMessage
(
)
]
,
'error'
)
;
}
}

Dotconst compile & cache.

@description Dotconst compile & cache.

@throws \Exception


protected function registerNativeFilesystem()
    {
        $this->app->singleton('files', function () {
            $config = $this->app['config'];
            $files = new Filesystem;
            $files->filePermissions = $config->get('system.filePermissions', null);
            $files->folderPermissions = $config->get('system.folderPermissions', null);
            $files->pathSymbols = [
                '$' => $config->get('system.extensionsPath', base_path('extensions')),
                '~' => base_path(),
            ];

            return $files;
        });
    }

protected function registerNativeFilesystem ( ) { $ this -> app -> singleton ( 'files' , function ( ) { $ config = $ this -> app [ 'config' ] ; $ files = new Filesystem ; $ files -> filePermissions = $ config -> get ( 'system.filePermissions' , null ) ; $ files -> folderPermissions = $ config -> get ( 'system.folderPermissions' , null ) ; $ files -> pathSymbols = [ '$' => $ config -> get ( 'system.extensionsPath' , base_path ( 'extensions' ) ) , '~' => base_path ( ) , ] ; return $ files ; } ) ; }

Register the native filesystem implementation.
@return void

Register the native filesystem implementation .


public static function swap($instance)
    {
        self::$resolvedInstance[static::getFacadeAccessor()] = $instance;

        static::$di->setShared(static::getFacadeAccessor(), $instance);
    }

public static function swap ( $ instance ) { self :: $ resolvedInstance [ static :: getFacadeAccessor ( ) ] = $ instance ; static :: $ di -> setShared ( static :: getFacadeAccessor ( ) , $ instance ) ; }

Hotswap the underlying instance behind the facade.

@param  mixed $instance

@return void

Hotswap the underlying instance behind the facade .


public static function shouldReceive(...$params)
    {
        $name = static::getFacadeAccessor();
        if (static::isMock()) {
            $mock = self::$resolvedInstance[$name];
        } else {
            $mock = static::createFreshMockInstance();
        }

        return $mock->shouldReceive(...$params);
    }

public static function shouldReceive ( ... $ params ) { $ name = static :: getFacadeAccessor ( ) ; if ( static :: isMock ( ) ) { $ mock = self :: $ resolvedInstance [ $ name ] ; } else { $ mock = static :: createFreshMockInstance ( ) ; } return $ mock -> shouldReceive ( ... $ params ) ; }

Initiate a mock expectation on the facade.

@param mixed ...$params

@return \Mockery\Expectation

Initiate a mock expectation on the facade .


protected static function createFreshMockInstance()
    {
        $name = static::getFacadeAccessor();

        self::$resolvedInstance[$name] = $mock = static::createMockInstance();

        $mock->shouldAllowMockingProtectedMethods();

        if (isset(static::$di)) {
            static::$di->setShared($name, $mock);
        }

        return $mock;
    }

protected static function createFreshMockInstance ( ) { $ name = static :: getFacadeAccessor ( ) ; self :: $ resolvedInstance [ $ name ] = $ mock = static :: createMockInstance ( ) ; $ mock -> shouldAllowMockingProtectedMethods ( ) ; if ( isset ( static :: $ di ) ) { static :: $ di -> setShared ( $ name , $ mock ) ; } return $ mock ; }

Create a fresh mock instance.

@return MockInterface


protected static function isMock()
    {
        $name = static::getFacadeAccessor();

        return isset(self::$resolvedInstance[$name]) && self::$resolvedInstance[$name] instanceof MockInterface;
    }

protected static function isMock ( ) { $ name = static :: getFacadeAccessor ( ) ; return isset ( self :: $ resolvedInstance [ $ name ] ) && self :: $ resolvedInstance [ $ name ] instanceof MockInterface ; }

Determines whether a mock is set as the instance of the facade.

@return bool

Determines whether a mock is set as the instance of the facade .


protected static function resolveFacadeInstance($name)
    {
        if (is_object($name)) {
            return $name;
        }

        if (isset(self::$resolvedInstance[$name])) {
            return self::$resolvedInstance[$name];
        }

        return self::$resolvedInstance[$name] = static::$di->getShared($name);
    }

protected static function resolveFacadeInstance ( $ name ) { if ( is_object ( $ name ) ) { return $ name ; } if ( isset ( self :: $ resolvedInstance [ $ name ] ) ) { return self :: $ resolvedInstance [ $ name ] ; } return self :: $ resolvedInstance [ $ name ] = static :: $ di -> getShared ( $ name ) ; }

Resolve the facade root instance from the container.

@param  string|object $name

@return mixed
@throws RuntimeException

Resolve the facade root instance from the container .


public function processSelect(Finder $finder, $result)
    {
        if ($result === null) {
            return null;
        }

        $fileName = array_get($result, 'fileName');

        return [$fileName => $this->parseTemplateContent($result, $fileName)];
    }

public function processSelect ( Finder $ finder , $ result ) { if ( $ result === null ) { return null ; } $ fileName = array_get ( $ result , 'fileName' ) ; return [ $ fileName => $ this -> parseTemplateContent ( $ result , $ fileName ) ] ; }

Process the results of a singular "select" query.

@param  \Igniter\Flame\Pagic\Finder $finder
@param  array $result

@return array

Process the results of a singular select query .


public function processSelectAll(Finder $finder, $results)
    {
        if (!count($results)) {
            return [];
        }

        $items = [];

        foreach ($results as $result) {
            $fileName = array_get($result, 'fileName');
            $items[$fileName] = $this->parseTemplateContent($result, $fileName);
        }

        return $items;
    }

public function processSelectAll ( Finder $ finder , $ results ) { if ( ! count ( $ results ) ) { return [ ] ; } $ items = [ ] ; foreach ( $ results as $ result ) { $ fileName = array_get ( $ result , 'fileName' ) ; $ items [ $ fileName ] = $ this -> parseTemplateContent ( $ result , $ fileName ) ; } return $ items ; }

Process the results of a "select" query.

@param  \Igniter\Flame\Pagic\Finder $finder
@param  array $results

@return array


protected function parseTemplateContent($result, $fileName)
    {
        $content = array_get($result, 'content');

        $processed = FileParser::parse($content);

        $content = [
            'fileName' => $fileName,
            'mTime'    => array_get($result, 'mTime'),
            'content'  => $content,
            'markup'   => $processed['markup'],
            'code'     => $processed['code'],
        ];

        if (!empty($processed['data']))
            $content = $content + $processed['data'];

        return $content;
    }

protected function parseTemplateContent ( $ result , $ fileName ) { $ content = array_get ( $ result , 'content' ) ; $ processed = FileParser :: parse ( $ content ) ; $ content = [ 'fileName' => $ fileName , 'mTime' => array_get ( $ result , 'mTime' ) , 'content' => $ content , 'markup' => $ processed [ 'markup' ] , 'code' => $ processed [ 'code' ] , ] ; if ( ! empty ( $ processed [ 'data' ] ) ) $ content = $ content + $ processed [ 'data' ] ; return $ content ; }

Helper to break down template content in to a useful array.

@param $result
@param $fileName

@return array

Helper to break down template content in to a useful array .


public function processUpdate(Finder $finder, $data)
    {
        $existingData = $finder->getModel()->attributesToArray();

        return FileParser::render($data + $existingData);
    }

public function processUpdate ( Finder $ finder , $ data ) { $ existingData = $ finder -> getModel ( ) -> attributesToArray ( ) ; return FileParser :: render ( $ data + $ existingData ) ; }

Process the data in to an update action.

@param  \Igniter\Flame\Pagic\Finder $finder
@param  array $data

@return string

Process the data in to an update action .


public function attach()
    {
        $em = $this->getEventsManager();

        if (!empty($this->space)) {
            foreach ($this->space as $space) {
                $em->attach($space, $this);
            }
        }

        if (!empty($this->listen)) {
            foreach ($this->listen as $event => $callback) {
                if (!method_exists($this, $callback)) {
                    throw new \RuntimeException(
                        "Method '$callback' not exist in " . get_class($this)
                    );
                }

                $this->closures[$event] = $closure = function (Event $event, $handler, $data = null) use ($callback) {
                    return $this->$callback($event, $handler, $data);
                };

                $em->attach($event, $closure);
            }
        }
    }

public
function
attach
(
)
{
$
em
=
$
this
->
getEventsManager
(
)
;
if
(
!
empty
(
$
this
->
space
)
)
{
foreach
(
$
this
->
space
as
$
space
)
{
$
em
->
attach
(
$
space
,
$
this
)
;
}
}
if
(
!
empty
(
$
this
->
listen
)
)
{
foreach
(
$
this
->
listen
as
$
event
=>
$
callback
)
{
if
(
!
method_exists
(
$
this
,
$
callback
)
)
{
throw
new
\
RuntimeException
(
"Method '$callback' not exist in "
.
get_class
(
$
this
)
)
;
}
$
this
->
closures
[
$
event
]
=
$
closure
=
function
(
Event
$
event
,
$
handler
,
$
data
=
)
use
(
$
callback
)
{
return
$
this
->
$
callback
(
$
event
,
$
handler
,
$
data
)
;
}
;
$
em
->
attach
(
$
event
,
$
closure
)
;
}
}
}

Attach all require event to make the listener


public function detach()
    {
        $em = $this->getEventsManager();

        if (!empty($this->space)) {
            foreach ($this->space as $space) {
                $em->detach($space, $this);
            }
        }

        foreach ($this->closures as $event => $closure) {
            $em->detach($event, $closure);
        }

        $this->closures = [];
    }

public function detach ( ) { $ em = $ this -> getEventsManager ( ) ; if ( ! empty ( $ this -> space ) ) { foreach ( $ this -> space as $ space ) { $ em -> detach ( $ space , $ this ) ; } } foreach ( $ this -> closures as $ event => $ closure ) { $ em -> detach ( $ event , $ closure ) ; } $ this -> closures = [ ] ; }

Detach all event attached to the EventsManager


public function geocodeQuery(GeoQueryInterface $query): Collection
    {
        $url = sprintf(
            array_get($this->config, 'endpoints.geocode'),
            urlencode($query->getText()),
            $query->getLimit()
        );

        $result = [];
        try {
            $result = $this->cacheCallback($url, function () use ($query, $url) {
                return $this->hydrateResponse(
                    $this->requestUrl($url, $query)
                );
            });
        }
        catch (Throwable $ex) {
            $this->log(sprintf(
                'Provider "%s" could not geocode address, "%s".',
                $this->getName(), $ex->getMessage()
            ));
        }

        return new Collection($result);
    }

Handle the geocoder request.

@param \Igniter\Flame\Geolite\Contracts\GeoQueryInterface $query
@return \Illuminate\Support\Collection


public function reverseQuery(GeoQueryInterface $query): Collection
    {
        $coordinates = $query->getCoordinates();

        $url = sprintf(
            array_get($this->config, 'endpoints.reverse'),
            $coordinates->getLatitude(),
            $coordinates->getLongitude(),
            $query->getData('zoom', 18)
        );

        $result = [];
        try {
            $result = $this->cacheCallback($url, function () use ($query, $url) {
                return $this->hydrateResponse(
                    $this->requestUrl($url, $query)
                );
            });
        }
        catch (Throwable $e) {
            $coordinates = $query->getCoordinates();
            $this->log(sprintf(
                'Provider "%s" could not reverse coordinates: "%f %f".',
                $this->getName(), $coordinates->getLatitude(), $coordinates->getLongitude()
            ));
        }

        return new Collection($result);
    }

Handle the reverse geocoding request.

@param \Igniter\Flame\Geolite\Contracts\GeoQueryInterface $query
@return \Illuminate\Support\Collection


protected function getStatusFor(array $ran)
    {
        return array_map(function ($migration) use ($ran) {
            $migrationName = $this->migrator->getMigrationName($migration);

            return [
                'Ran?'      => in_array($migrationName, $ran)
                    ? Decorate::info('Y')
                    : Decorate::apply('N', 'red'),
                'Migration' => $migrationName
            ];
        }, $this->getAllMigrationFiles());
    }

protected function getStatusFor ( array $ ran ) { return array_map ( function ( $ migration ) use ( $ ran ) { $ migrationName = $ this -> migrator -> getMigrationName ( $ migration ) ; return [ 'Ran?' => in_array ( $ migrationName , $ ran ) ? Decorate :: info ( 'Y' ) : Decorate :: apply ( 'N' , 'red' ) , 'Migration' => $ migrationName ] ; } , $ this -> getAllMigrationFiles ( ) ) ; }

Get the status for the given ran migrations.

@param array $ran

@return array

Get the status for the given ran migrations .


public function mainAction()
    {
        $infos = $this->getHttpRoutesInfos();

        $datas = [];
        foreach ($infos['routes'] as $route) {
            /** @var \Phalcon\Mvc\Router\Route $route */
            $paths = $route->getPaths();

            if (!$this->hasOption('no-substitution')) {
                $compiled = Helper::describeRoutePattern($route, true);
            } else {
                $compiled = $route->getPattern();
            }

            $httpMethods = $route->getHttpMethods();

            if (is_array($httpMethods)) {
                $httpMethods = implode('|', $httpMethods);
            }
            $middlewares = Arr::fetch($paths, 'middleware');
            if (is_array($middlewares)) {
                $_middlewares = [];
                foreach ($middlewares as $key => $middleware) {
                    if (is_int($key)) {
                        $_middlewares[] = $middleware;
                    } else {
                        $_middlewares[] = $key;
                    }
                }
                $middleware = implode('|', $_middlewares);
            } else {
                $middleware = $middlewares;
            }

            if (Arr::has($paths, 'controller')) {
                $controller = Str::capitalize($paths['controller']);
            } else {
                $controller = Decorate::notice('{controller}');
            }

            $controller .= Arr::fetch($infos, 'controllerSuffix', '');

            if (Arr::has($paths, 'action')) {
                $action = $paths['action'];
            } else {
                $action = Decorate::notice('{action}');
            }

            $action .= Arr::fetch($infos, 'actionSuffix', '');

            $module = Arr::get($paths, 'module');
            $namespace = Arr::fetch($paths, 'namespace', Arr::fetch($infos['defaults'], 'namespace'));

            $datas[$module . '::' . $namespace][] = [
                'domain'     => $route->getHostname(),
                'name'       => $route->getName(),
                'method'     => $httpMethods,
                'pattern'    => $compiled,
                'action'     => $controller . '::' . $action,
                'middleware' => $middleware
            ];
        }

        foreach ($datas as $key => $data) {
            $parts = explode('::', $key, 2);

            $this->table([['MODULE    : '.$parts[0]],['NAMESPACE : ' . $parts[1]]], [], Table::NO_HEADER);

            $this->table($data);

            $this->line('');
        }
    }

List all routes.

@description List all routes.

@option      --no-substitution: Doesn't replace matching group by params name


protected function getHttpRoutesInfos()
    {
        Router::clearResolvedInstances();

        $cliRouter = $this->router;
        $cliDispatcher = $this->dispatcher;

        $this->di->remove(Services::ROUTER);
        $this->di->remove(Services::DISPATCHER);

        $httpRouterProvider = new \Neutrino\Providers\Http\Router;
        $httpRouterProvider->registering();
        $httpDispatcherProvider = new \Neutrino\Providers\Http\Dispatcher;
        $httpDispatcherProvider->registering();

        require BASE_PATH . '/routes/http.php';
        /** @var \Phalcon\Mvc\Dispatcher $httpDispatcher */
        $httpDispatcher = $this->di->get(Services::DISPATCHER);
        $reflexionProperty = (new \ReflectionClass(get_class($httpDispatcher)))->getProperty('_handlerSuffix');
        $reflexionProperty->setAccessible(true);

        $routes = Router::getRoutes();
        $defaults = Router::getDefaults();
        $actionSuffix = $httpDispatcher->getActionSuffix();
        $controllerSuffix = $reflexionProperty->getValue($httpDispatcher);

        Router::clearResolvedInstances();

        $this->di->remove(Services::ROUTER);
        $this->di->remove(Services::DISPATCHER);

        $this->di->setShared(Services::ROUTER, $cliRouter);
        $this->di->setShared(Services::DISPATCHER, $cliDispatcher);

        return [
            'routes'           => $routes,
            'defaults'         => $defaults,
            'actionSuffix'     => $actionSuffix,
            'controllerSuffix' => $controllerSuffix,
        ];
    }


protected function curlOptions($ch)
    {
        $method = $this->method;

        if ($method === Method::HEAD) {
            curl_setopt($ch, CURLOPT_NOBODY, true);
        }

        // Default Options
        curl_setopt_array($ch,
            [
                CURLOPT_URL             => $this->uri->build(),
                CURLOPT_CUSTOMREQUEST   => $method,
                CURLOPT_AUTOREFERER     => true,
                CURLOPT_RETURNTRANSFER  => true,
                CURLOPT_FOLLOWLOCATION  => true,
                CURLOPT_MAXREDIRS       => 20,
                CURLOPT_HEADER          => $this->fullResponse,
                CURLOPT_PROTOCOLS       => CURLPROTO_HTTP | CURLPROTO_HTTPS,
                CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
                CURLOPT_HEADERFUNCTION  => [$this, 'curlHeaderFunction'],
            ]);

        curl_setopt_array($ch, $this->options);
    }

protected
function
curlOptions
(
$
ch
)
{
$
method
=
$
this
->
method
;
if
(
$
method
===
Method
::
HEAD
)
{
curl_setopt
(
$
ch
,
CURLOPT_NOBODY
,
true
)
;
}
// Default Options
curl_setopt_array
(
$
ch
,
[
CURLOPT_URL
=>
$
this
->
uri
->
build
(
)
,
CURLOPT_CUSTOMREQUEST
=>
$
method
,
CURLOPT_AUTOREFERER
=>
true
,
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_FOLLOWLOCATION
=>
true
,
CURLOPT_MAXREDIRS
=>
20
,
CURLOPT_HEADER
=>
$
this
->
fullResponse
,
CURLOPT_PROTOCOLS
=>
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
,
CURLOPT_REDIR_PROTOCOLS
=>
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
,
CURLOPT_HEADERFUNCTION
=>
[
$
this
,
'curlHeaderFunction'
]
,
]
)
;
curl_setopt_array
(
$
ch
,
$
this
->
options
)
;
}

Apply options to curl resource

@param resource $ch


protected function curlInfos($ch)
    {
        $this->response->setCode(curl_getinfo($ch, CURLINFO_HTTP_CODE));

        if (($errno = curl_errno($ch)) !== 0) {
            $this->response->setErrorCode(curl_errno($ch));
            $this->response->setError(curl_error($ch));
        }

        $this->response->setProviderDatas(curl_getinfo($ch));
    }

protected function curlInfos ( $ ch ) { $ this -> response -> setCode ( curl_getinfo ( $ ch , CURLINFO_HTTP_CODE ) ) ; if ( ( $ errno = curl_errno ( $ ch ) ) !== 0 ) { $ this -> response -> setErrorCode ( curl_errno ( $ ch ) ) ; $ this -> response -> setError ( curl_error ( $ ch ) ) ; } $ this -> response -> setProviderDatas ( curl_getinfo ( $ ch ) ) ; }

Apply curl info to response

@param resource $ch


public static function compile($basePath, $compilePath)
    {
        $extensions = Dotconst::getExtensions();

        $raw = Loader::loadRaw($basePath);

        $config = Loader::fromFiles($basePath);

        $r = fopen($compilePath . '/consts.php', 'w');

        if ($r === false) {
            throw new InvalidFileException('Can\'t create file : ' . $compilePath);
        }

        fwrite($r, "<?php" . PHP_EOL);

        $nested = [];

        foreach ($raw as $const => $value) {
            foreach ($extensions as $k => $extension) {
                if(is_string($extension)){
                    $extensions[$k] = $extension = new $extension;
                }

                if ($extension->identify($value)) {
                    fwrite($r, "define('$const', " . $extension->compile($value, $basePath, $compilePath) . ");" . PHP_EOL);

                    continue 2;
                }
            }

            if (preg_match('#^@\{(\w+)\}@?#', $value, $match)) {
                $key = strtoupper($match[1]);

                $value = preg_replace('#^@\{(\w+)\}@?#', '', $value);

                $draw = '';
                $require = null;
                if(isset($config[$key])){
                    $draw .= $key;
                    $require = $key;
                } else {
                    $draw .= $match[1] ;
                }
                if(!empty($value)){
                    $draw .= " . '$value'";
                }

                $nested[$const] = ['draw' => $draw, 'require' => $require];

                continue;
            }

            fwrite($r, "define('$const', " . var_export($value, true) . ");" . PHP_EOL);
        }

        $nested = Helper::nestedConstSort($nested);

        foreach ($nested as $const => $item) {
            fwrite($r, "define('$const', {$item['draw']});" . PHP_EOL);
        }

        fclose($r);
    }

public
static
function
compile
(
$
basePath
,
$
compilePath
)
{
$
extensions
=
Dotconst
::
getExtensions
(
)
;
$
raw
=
Loader
::
loadRaw
(
$
basePath
)
;
$
config
=
Loader
::
fromFiles
(
$
basePath
)
;
$
r
=
fopen
(
$
compilePath
.
'/consts.php'
,
'w'
)
;
if
(
$
r
===
false
)
{
throw
new
InvalidFileException
(
'Can\'t create file : '
.
$
compilePath
)
;
}
fwrite
(
$
r
,
"<?php"
.
PHP_EOL
)
;
$
nested
=
[
]
;
foreach
(
$
raw
as
$
const
=>
$
value
)
{
foreach
(
$
extensions
as
$
k
=>
$
extension
)
{
if
(
is_string
(
$
extension
)
)
{
$
extensions
[
$
k
]
=
$
extension
=
new
$
extension
;
}
if
(
$
extension
->
identify
(
$
value
)
)
{
fwrite
(
$
r
,
"define('$const', "
.
$
extension
->
compile
(
$
value
,
$
basePath
,
$
compilePath
)
.
");"
.
PHP_EOL
)
;
continue
2
;
}
}
if
(
preg_match
(
'#^@\{(\w+)\}@?#'
,
$
value
,
$
match
)
)
{
$
key
=
strtoupper
(
$
match
[
1
]
)
;
$
value
=
preg_replace
(
'#^@\{(\w+)\}@?#'
,
''
,
$
value
)
;
$
draw
=
''
;
$
require
=
;
if
(
isset
(
$
config
[
$
key
]
)
)
{
$
draw
.=
$
key
;
$
require
=
$
key
;
}
else
{
$
draw
.=
$
match
[
1
]
;
}
if
(
!
empty
(
$
value
)
)
{
$
draw
.=
" . '$value'"
;
}
$
nested
[
$
const
]
=
[
'draw'
=>
$
draw
,
'require'
=>
$
require
]
;
continue
;
}
fwrite
(
$
r
,
"define('$const', "
.
var_export
(
$
value
,
true
)
.
");"
.
PHP_EOL
)
;
}
$
nested
=
Helper
::
nestedConstSort
(
$
nested
)
;
foreach
(
$
nested
as
$
const
=>
$
item
)
{
fwrite
(
$
r
,
"define('$const', {$item['draw']});"
.
PHP_EOL
)
;
}
fclose
(
$
r
)
;
}

Compile loaded & parsed ini files to php files.

@param string $basePath
@param string $compilePath

@throws \Neutrino\Dotconst\Exception\InvalidFileException

Compile loaded & parsed ini files to php files .


public function start()
    {
        $this->spec = [
            // 0 => ['pipe', 'w+'],
          1 => fopen('php://temp/maxmemory:' . (1024 * 1024), 'w+'),
          2 => fopen('php://temp/maxmemory:' . (1024 * 1024), 'w+'),
        ];

        if ('\\' === DIRECTORY_SEPARATOR) {
            $this->options = array_merge(['bypass_shell' => true], (array)$this->options);
        }

        /** @var Error $error */
        $error = null;

        set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) {
            $error = Error::fromError($errno, $errstr, $errfile, $errline);
        });

        $this->proc = proc_open($this->cmd, $this->spec, $this->pipes, $this->cwd, null, $this->options);

        restore_error_handler();

        $this->pipes = $this->spec;

        if (!is_null($error)) {
            throw new Exception('Can\'t create process', 0, new Exception($error->message, $error->code));
        }
        if (!$this->isRunning()) {
            throw new Exception('Can\'t create process');
        }

        return $this;
    }

public
function
start
(
)
{
$
this
->
spec
=
[
// 0 => ['pipe', 'w+'],
1
=>
fopen
(
'php://temp/maxmemory:'
.
(
1024
*
1024
)
,
'w+'
)
,
2
=>
fopen
(
'php://temp/maxmemory:'
.
(
1024
*
1024
)
,
'w+'
)
,
]
;
if
(
'\\'
===
DIRECTORY_SEPARATOR
)
{
$
this
->
options
=
array_merge
(
[
'bypass_shell'
=>
true
]
,
(
array
)
$
this
->
options
)
;
}
/** @var Error $error */
$
error
=
;
set_error_handler
(
function
(
$
errno
,
$
errstr
,
$
errfile
,
$
errline
)
use
(
&
$
error
)
{
$
error
=
Error
::
fromError
(
$
errno
,
$
errstr
,
$
errfile
,
$
errline
)
;
}
)
;
$
this
->
proc
=
proc_open
(
$
this
->
cmd
,
$
this
->
spec
,
$
this
->
pipes
,
$
this
->
cwd
,
,
$
this
->
options
)
;
restore_error_handler
(
)
;
$
this
->
pipes
=
$
this
->
spec
;
if
(
!
is_null
(
$
error
)
)
{
throw
new
Exception
(
'Can\'t create process'
,
0
,
new
Exception
(
$
error
->
message
,
$
error
->
code
)
)
;
}
if
(
!
$
this
->
isRunning
(
)
)
{
throw
new
Exception
(
'Can\'t create process'
)
;
}
return
$
this
;
}

Start a process

@return $this
@throws Exception


public function wait($timeout = null, $step = 1000)
    {
        $withTimeout = false === is_null($timeout);

        if ($withTimeout) {
            $start = microtime(true);
            if ($timeout < $step) {
                $step = $timeout;
            }
        }

        while ($this->isRunning()) {
            usleep($step * 1000);

            if ($withTimeout && ($start + $timeout) > microtime(true)) {
                return;
            }
        }
    }

public function wait ( $ timeout = null , $ step = 1000 ) { $ withTimeout = false === is_null ( $ timeout ) ; if ( $ withTimeout ) { $ start = microtime ( true ) ; if ( $ timeout < $ step ) { $ step = $ timeout ; } } while ( $ this -> isRunning ( ) ) { usleep ( $ step * 1000 ) ; if ( $ withTimeout && ( $ start + $ timeout ) > microtime ( true ) ) { return ; } } }

Wait until process end or wait time

@param int|null $timeout in ms
@param int $step in ms


public function stop($timeout = 1000)
    {
        $timeout = microtime(true) + ($timeout * 1000);

        if ($this->isRunning()) {
            proc_terminate($this->proc);
        }
        while ($this->isRunning() && microtime(true) < $timeout) {
            usleep(1000);
        }

        $this->readOutput();
        $this->readError();

        return $this;
    }

public function stop ( $ timeout = 1000 ) { $ timeout = microtime ( true ) + ( $ timeout * 1000 ) ; if ( $ this -> isRunning ( ) ) { proc_terminate ( $ this -> proc ) ; } while ( $ this -> isRunning ( ) && microtime ( true ) < $ timeout ) { usleep ( 1000 ) ; } $ this -> readOutput ( ) ; $ this -> readError ( ) ; return $ this ; }

Stop a process

@param int $timeout in ms

@return $this


public function close()
    {
        $this->stop(0);

        if (is_resource($this->proc)) {
            proc_close($this->proc);
        }

        foreach ($this->pipes as $pipe) {
            if (is_resource($pipe)) {
                fclose($pipe);
            }
        }
    }

public function close ( ) { $ this -> stop ( 0 ) ; if ( is_resource ( $ this -> proc ) ) { proc_close ( $ this -> proc ) ; } foreach ( $ this -> pipes as $ pipe ) { if ( is_resource ( $ pipe ) ) { fclose ( $ pipe ) ; } } }


public function exec($timeout = null)
    {
        try {
            $this->start();
            $this->wait($timeout, 500);
            if ($this->isRunning()) {
                throw new Timeout;
            }
        } finally {
            $this->close();
        }
    }

public function exec ( $ timeout = null ) { try { $ this -> start ( ) ; $ this -> wait ( $ timeout , 500 ) ; if ( $ this -> isRunning ( ) ) { throw new Timeout ; } } finally { $ this -> close ( ) ; } }

Execute a process

@param int|null $timeout in ms

@throws Exception


public function optimizeMemory()
    {
        $this->composer->dumpautoload(false);

        $files      = $this->autoload->getFiles();
        $namespaces = $this->autoload->getNamespaces();
        $psr        = $this->autoload->getPsr4();
        $classes    = $this->autoload->getClassmap();

        $_namespaces = [];
        $_dirs       = [];
        foreach ($namespaces as $namespace => $directories) {
            $_namespaces[trim($namespace, '\\')] = $directories;
            foreach ($directories as $directory) {
                $_dirs[$directory] = $directory;
            }
        }
        foreach ($psr as $namespace => $dir) {
            $_namespaces[trim($namespace, '\\')] = $dir;
        }

        return $this->generateOutput($files, $_namespaces, $_dirs, $classes);
    }

public function optimizeMemory ( ) { $ this -> composer -> dumpautoload ( false ) ; $ files = $ this -> autoload -> getFiles ( ) ; $ namespaces = $ this -> autoload -> getNamespaces ( ) ; $ psr = $ this -> autoload -> getPsr4 ( ) ; $ classes = $ this -> autoload -> getClassmap ( ) ; $ _namespaces = [ ] ; $ _dirs = [ ] ; foreach ( $ namespaces as $ namespace => $ directories ) { $ _namespaces [ trim ( $ namespace , '\\' ) ] = $ directories ; foreach ( $ directories as $ directory ) { $ _dirs [ $ directory ] = $ directory ; } } foreach ( $ psr as $ namespace => $ dir ) { $ _namespaces [ trim ( $ namespace , '\\' ) ] = $ dir ; } return $ this -> generateOutput ( $ files , $ _namespaces , $ _dirs , $ classes ) ; }

Build an memory optimized autoloader

@return bool|int


protected function generateOutput($files = null, $namespaces = null, $directories = null, $classmap = null)
    {
        $res = fopen($this->loaderFilePath, 'w');

        if ($res == false) {
            return false;
        }

        fwrite($res, '<?php' . "\n");

        if (isset($this->basePath)) {
            $relativePath = Path::findRelative(dirname($this->loaderFilePath), $this->basePath);
            fwrite($res, '$basePath = __DIR__ . ' . var_export('/' . $relativePath . '/', true) . ";\n");
        }

        fwrite($res, '$loader = new Phalcon\Loader;' . "\n");

        if (Version::getPart(Version::VERSION_MAJOR) >= 3 && Version::getPart(Version::VERSION_MEDIUM) >= 4) {
            fwrite($res, '$loader->setFileCheckingCallback("stream_resolve_include_path");' . "\n");
        }

        if (!empty($files)) {
            fwrite($res, '$loader->registerFiles(' . $this->prepareOutput(array_values($files)) . ');' . "\n");
        }
        if (!empty($directories)) {
            fwrite($res, '$loader->registerDirs(' . $this->prepareOutput(array_values($directories)) . ');' . "\n");
        }
        if (!empty($namespaces)) {
            fwrite($res, '$loader->registerNamespaces(' . $this->prepareOutput($namespaces) . ');' . "\n");
        }
        if (!empty($classmap)) {
            fwrite($res, '$loader->registerClasses(' . $this->prepareOutput($classmap) . ');' . "\n");
        }

        fwrite($res, '$loader->register();' . "\n");

        fclose($res);

        return true;
    }

Generate phalcon loader

@param array|null $files
@param array|null $namespaces
@param array|null $directories
@param array|null $classmap

@return int|bool


public static function fill(&$target, $key, $value)
    {
        return self::set($target, $key, $value, false);
    }

public static function fill ( & $ target , $ key , $ value ) { return self :: set ( $ target , $ key , $ value , false ) ; }

Fill in data where it's missing.

@param  mixed        $target
@param  string|array $key
@param  mixed        $value

@return mixed


public static function read($object, $property, $default = null)
    {
        if (is_null($object)) {
            return self::value($default);
        }

        if (isset($object->$property) || property_exists($object, $property)) {
            return $object->$property;
        }

        return self::value($default);
    }

public static function read ( $ object , $ property , $ default = null ) { if ( is_null ( $ object ) ) { return self :: value ( $ default ) ; } if ( isset ( $ object -> $ property ) || property_exists ( $ object , $ property ) ) { return $ object -> $ property ; } return self :: value ( $ default ) ; }

Get an item from an object.

@param      $object
@param      $property
@param null $default

@return null


public static function fetch($object, $property, $default = null)
    {
        if (is_null($object)) {
            return self::value($default);
        }

        return isset($object->$property) ? $object->$property : self::value($default);
    }

public static function fetch ( $ object , $ property , $ default = null ) { if ( is_null ( $ object ) ) { return self :: value ( $ default ) ; } return isset ( $ object -> $ property ) ? $ object -> $ property : self :: value ( $ default ) ; }

Get an item, no null, from an object.

@param      $object
@param      $property
@param null $default

@return null


public static function get($target, $key, $default = null)
    {
        if (is_null($key) || !is_object($target)) {
            return self::value($default);
        }

        if (!is_array($key)) {
            if (isset($target->{$key}) || property_exists($target, $key)) {
                return $target->{$key};
            }

            $keys = explode('.', $key);
        } else {
            $keys = $key;
        }
        foreach ($keys as $segment) {
            if (is_object($target) && isset($target->{$segment})) {
                $target = $target->{$segment};
            } else {
                return self::value($default);
            }
        }

        return $target;
    }

public static function get ( $ target , $ key , $ default = null ) { if ( is_null ( $ key ) || ! is_object ( $ target ) ) { return self :: value ( $ default ) ; } if ( ! is_array ( $ key ) ) { if ( isset ( $ target -> { $ key } ) || property_exists ( $ target , $ key ) ) { return $ target -> { $ key } ; } $ keys = explode ( '.' , $ key ) ; } else { $ keys = $ key ; } foreach ( $ keys as $ segment ) { if ( is_object ( $ target ) && isset ( $ target -> { $ segment } ) ) { $ target = $ target -> { $ segment } ; } else { return self :: value ( $ default ) ; } } return $ target ; }

Get an item from an array or object using "dot" notation.

@param  mixed        $target
@param  string|array $key
@param  mixed        $default

@return mixed

Get an item from an array or object using dot notation .


public static function set(&$target, $key, $value, $overwrite = true)
    {
        if (is_null($key)) {
            return $target;
        }

        if (!is_array($key)) {
            if (isset($target->{$key}) || property_exists($target, $key)) {
                if ($overwrite) {
                    $target->{$key} = self::value($value);
                }

                return $target;
            }

            $keys = explode('.', $key);
        } else {
            $keys = $key;
        }

        $keep = $target;

        while (count($keys) > 1) {
            $key = array_shift($keys);

            // If the key doesn't exist at this depth, we will just create an empty array
            // to hold the next value, allowing us to create the arrays to hold final
            // values at the correct depth. Then we'll keep digging into the array.
            if (!isset($target->{$key}) || !is_object($target->{$key}) && $overwrite) {
                $target->{$key} = new \stdClass;
            } elseif (!is_object($target->{$key})) {
                return $target;
            }

            $target = &$target->{$key};
        }

        $key = array_shift($keys);
        if (!isset($target->{$key}) || $overwrite) {
            $target->{$key} = self::value($value);
        }

        return $keep;
    }

Set an item on an array or object using dot notation.

@param  mixed        $target
@param  string|array $key
@param  mixed        $value
@param  bool         $overwrite

@return mixed

Set an item on an array or object using dot notation .


public static function register()
    {
        set_error_handler(function ($errno, $errstr, $errfile, $errline) {
            self::handleError($errno, $errstr, $errfile, $errline);
        });
        set_exception_handler(function ($e) {
            self::handleException($e);
        });
        register_shutdown_function(function () {
            // Handle Fatal error
            $error = error_get_last();
            if (isset($error['type']) && $error['type'] === E_ERROR) {
                self::handleError($error['type'], $error['message'], $error['file'], $error['line']);
            }
        });
    }

public
static
function
register
(
)
{
set_error_handler
(
function
(
$
errno
,
$
errstr
,
$
errfile
,
$
errline
)
{
self
::
handleError
(
$
errno
,
$
errstr
,
$
errfile
,
$
errline
)
;
}
)
;
set_exception_handler
(
function
(
$
e
)
{
self
::
handleException
(
$
e
)
;
}
)
;
register_shutdown_function
(
function
(
)
{
// Handle Fatal error
$
error
=
error_get_last
(
)
;
if
(
isset
(
$
error
[
'type'
]
)
&&
$
error
[
'type'
]
===
E_ERROR
)
{
self
::
handleError
(
$
error
[
'type'
]
,
$
error
[
'message'
]
,
$
error
[
'file'
]
,
$
error
[
'line'
]
)
;
}
}
)
;
}

Registers itself as error and exception handler.

@return void

Registers itself as error and exception handler .


public static function handleError($errno, $errstr, $errfile, $errline)
    {
        if (!($errno & error_reporting())) {
            return;
        }

        static::handle(Error::fromError($errno, $errstr, $errfile, $errline));
    }

public static function handleError ( $ errno , $ errstr , $ errfile , $ errline ) { if ( ! ( $ errno & error_reporting ( ) ) ) { return ; } static :: handle ( Error :: fromError ( $ errno , $ errstr , $ errfile , $ errline ) ) ; }

Handle an php Error

@param int    $errno
@param string $errstr
@param string $errfile
@param int    $errline


public static function handle(Error $error)
    {
        foreach (self::$writers as $class => $writer) {
            if (is_null($writer)) {
                self::$writers[$class] = $writer = new $class();
            }
            $writer->handle($error);
        }
    }

public static function handle ( Error $ error ) { foreach ( self :: $ writers as $ class => $ writer ) { if ( is_null ( $ writer ) ) { self :: $ writers [ $ class ] = $ writer = new $ class ( ) ; } $ writer -> handle ( $ error ) ; } }

Logs the error and dispatches an error controller.

@param  \Neutrino\Error\Error $error

Logs the error and dispatches an error controller .


public function resolve($file)
    {
        $class = Str::studly(implode('_', array_slice(explode('_', $file), 4)));
        if (!class_exists($class)) {
            $className = str_replace('.', '\\', $this->getRepository()->getGroup());
            $class = $className.'\\Database\\Migrations\\'.$class;
        }

        return new $class;
    }

public function resolve ( $ file ) { $ class = Str :: studly ( implode ( '_' , array_slice ( explode ( '_' , $ file ) , 4 ) ) ) ; if ( ! class_exists ( $ class ) ) { $ className = str_replace ( '.' , '\\' , $ this -> getRepository ( ) -> getGroup ( ) ) ; $ class = $ className . '\\Database\\Migrations\\' . $ class ; } return new $ class ; }

Resolve a migration instance from a file.

@param  string $file

@return object

Resolve a migration instance from a file .


protected function shouldLog($level)
    {
        if ($this->levels === ['*'] || $this->levels === ['all']) {
            return true;
        }

        return in_array($level, $this->levels);
    }

protected function shouldLog ( $ level ) { if ( $ this -> levels === [ '*' ] || $ this -> levels === [ 'all' ] ) { return true ; } return in_array ( $ level , $ this -> levels ) ; }

Should the message be logged?

@param string $level

@return bool


public function useFiles($path, $level = 'debug')
    {
        if ($this->logger instanceof Log) {
            $this->logger->useFiles($path, $level);
        }
    }

public function useFiles ( $ path , $ level = 'debug' ) { if ( $ this -> logger instanceof Log ) { $ this -> logger -> useFiles ( $ path , $ level ) ; } }

Register a file log handler.

@param string $path
@param string $level

@return void


public function useDailyFiles($path, $days = 0, $level = 'debug')
    {
        if ($this->logger instanceof Log) {
            $this->logger->useDailyFiles($path, $days, $level);
        }
    }

public function useDailyFiles ( $ path , $ days = 0 , $ level = 'debug' ) { if ( $ this -> logger instanceof Log ) { $ this -> logger -> useDailyFiles ( $ path , $ days , $ level ) ; } }

Register a daily file log handler.

@param string $path
@param int    $days
@param string $level

@return void


protected function registerLogger()
    {
        $this->app->singleton('logger', function (Container $app) {
            $loggers = [];

            foreach ($app->config->get('logger.loggers', []) as $logger => $levels) {
                $loggers[] = new LevelAwareLogger($app->make($logger), (array) $levels);
            }

            return new LoggerWrapper($loggers);
        });

        $this->app->alias('logger', LoggerWrapper::class);
        $this->app->alias('logger', LoggerInterface::class);
        $this->app->alias('logger', Log::class);
    }

protected function registerLogger ( ) { $ this -> app -> singleton ( 'logger' , function ( Container $ app ) { $ loggers = [ ] ; foreach ( $ app -> config -> get ( 'logger.loggers' , [ ] ) as $ logger => $ levels ) { $ loggers [ ] = new LevelAwareLogger ( $ app -> make ( $ logger ) , ( array ) $ levels ) ; } return new LoggerWrapper ( $ loggers ) ; } ) ; $ this -> app -> alias ( 'logger' , LoggerWrapper :: class ) ; $ this -> app -> alias ( 'logger' , LoggerInterface :: class ) ; $ this -> app -> alias ( 'logger' , Log :: class ) ; }

Register the logger class.

@return void


public function setUp($options = [])
    {
        $this->setupProperty($options, 'dbType', 'DB_TYPE');
        $this->setupProperty($options, 'server', 'DB_HOST');
        $this->setupProperty($options, 'username', 'DB_USERNAME');
        $this->setupProperty($options, 'password', 'DB_PASSWORD');
        $this->setupProperty($options, 'database', 'DB_DATABASE');
        $this->setupProperty($options, 'port', 'DB_PORT');
        $this->setupProperty($options, 'connectionSettings', 'DB_SETUP');
    }

public function setUp ( $ options = [ ] ) { $ this -> setupProperty ( $ options , 'dbType' , 'DB_TYPE' ) ; $ this -> setupProperty ( $ options , 'server' , 'DB_HOST' ) ; $ this -> setupProperty ( $ options , 'username' , 'DB_USERNAME' ) ; $ this -> setupProperty ( $ options , 'password' , 'DB_PASSWORD' ) ; $ this -> setupProperty ( $ options , 'database' , 'DB_DATABASE' ) ; $ this -> setupProperty ( $ options , 'port' , 'DB_PORT' ) ; $ this -> setupProperty ( $ options , 'connectionSettings' , 'DB_SETUP' ) ; }

SetUp Object to be ready for connect

@param array $options Object Options (company,url,user,password,evidence,
prefix,defaultUrlParams,debug)


public function logSqlError($ignoreErrors = false)
    {
        if (!$this->result && !$ignoreErrors) {
            $queryRaw        = $this->lastQuery;
            $callerBackTrace = debug_backtrace();
            $callerBackTrace = $callerBackTrace[2];
            $caller          = $callerBackTrace['function'].'()';
            if (isset($callerBackTrace['class'])) {
                $caller .= ' in '.$callerBackTrace['class'];
            }
            if (isset($callerBackTrace['object'])) {
                $caller .= ' ('.get_class($callerBackTrace['object']).')';
            }
            \Ease\Shared::logger()->addStatusMessage(new \Ease\Logger\Message('ExeQuery: #'.$this->errorNumber.': '.$this->errorText."\n".$queryRaw,
                    'error', $caller));
        }
    }

public
function
logSqlError
(
$
ignoreErrors
=
false
)
{
if
(
!
$
this
->
result
&&
!
$
ignoreErrors
)
{
$
queryRaw
=
$
this
->
lastQuery
;
$
callerBackTrace
=
debug_backtrace
(
)
;
$
callerBackTrace
=
$
callerBackTrace
[
2
]
;
$
caller
=
$
callerBackTrace
[
'function'
]
.
'()'
;
if
(
isset
(
$
callerBackTrace
[
'class'
]
)
)
{
$
caller
.=
' in '
.
$
callerBackTrace
[
'class'
]
;
}
if
(
isset
(
$
callerBackTrace
[
'object'
]
)
)
{
$
caller
.=
' ('
.
get_class
(
$
callerBackTrace
[
'object'
]
)
.
')'
;
}
\
Ease
\
Shared
::
logger
(
)
->
addStatusMessage
(
new
\
Ease
\
Logger
\
Message
(
'ExeQuery: #'
.
$
this
->
errorNumber
.
': '
.
$
this
->
errorText
.
"\n"
.
$
queryRaw
,
'error'
,
$
caller
)
)
;
}
}

Do when SQL error occurs.

@param bool $ignoreErrors


public function &addItemSmart($pageItem, $properties = [])
    {
        if (is_array($pageItem)) {
            foreach ($pageItem as $item) {
                $this->addItemSmart($item);
            }
            $itemAdded = &$this->lastItem;
        } else {
            if (isset($pageItem->tagType) && $pageItem->tagType == 'li') {
                $itemAdded = parent::addItem($pageItem);
            } else {
                $itemAdded = parent::addItem(new LiTag($pageItem, $properties));
            }
        }

        return $itemAdded;
    }

public function & addItemSmart ( $ pageItem , $ properties = [ ] ) { if ( is_array ( $ pageItem ) ) { foreach ( $ pageItem as $ item ) { $ this -> addItemSmart ( $ item ) ; } $ itemAdded = & $ this -> lastItem ; } else { if ( isset ( $ pageItem -> tagType ) && $ pageItem -> tagType == 'li' ) { $ itemAdded = parent :: addItem ( $ pageItem ) ; } else { $ itemAdded = parent :: addItem ( new LiTag ( $ pageItem , $ properties ) ) ; } } return $ itemAdded ; }

Every item id added in LiTag envelope.

@param mixed  $pageItem   obsah vkládaný jako položka výčtu
@param string $properties Vlastnosti LI tagu

@return mixed


public function getProperty($property, $default = null)
    {
        if (!$property) return $default;

        $value = isset($this->properties[$property]) ? $this->properties[$property] : $default;

        // If the attribute exists within the cast array, we will convert it to
        // an appropriate native PHP type dependant upon the associated value
        // given with the key in the pair. Dayle made this comment line up.
        if ($this->hasCast($property)) {
            return $this->castGetProperty($property, $value);
        }

        return $value;
    }

Get an property from the entity.

@param  string $property
@param  mixed $default
@return mixed


public function setProperty($property, $value)
    {
        $this->properties[$property] = ($this->hasCast($property)) ? $this->castSetProperty($property, $value) : $value;
        return $this;
    }

public function setProperty ( $ property , $ value ) { $ this -> properties [ $ property ] = ( $ this -> hasCast ( $ property ) ) ? $ this -> castSetProperty ( $ property , $ value ) : $ value ; return $ this ; }

Set a given property on the entity.

@param  string $property
@param  mixed $value
@return $this


public function setProperties(array $properties, $sync = false)
    {
        $this->properties = [];

        foreach ($properties as $property => $value) {
            $setMethod = 'set' . ucfirst($property);
            if (method_exists($this, $setMethod)) {
                $this->$setMethod($value);
            } else {
                $this->setProperty($property, $value);
            }
        }

        if ($sync) {
            $this->syncOriginal();
        }

        return $this;
    }

public function setProperties ( array $ properties , $ sync = false ) { $ this -> properties = [ ] ; foreach ( $ properties as $ property => $ value ) { $ setMethod = 'set' . ucfirst ( $ property ) ; if ( method_exists ( $ this , $ setMethod ) ) { $ this -> $ setMethod ( $ value ) ; } else { $ this -> setProperty ( $ property , $ value ) ; } } if ( $ sync ) { $ this -> syncOriginal ( ) ; } return $ this ; }

Set the array of entity properties.

@param  array $properties
@param  bool $sync
@return $this


public function getOriginal($property = null, $default = null)
    {
        if (is_null($property)) return $this->original;

        return isset($this->original[$property]) ? $this->original[$property] : $default;
    }

public function getOriginal ( $ property = null , $ default = null ) { if ( is_null ( $ property ) ) return $ this -> original ; return isset ( $ this -> original [ $ property ] ) ? $ this -> original [ $ property ] : $ default ; }

Get the entity original attribute values.

@param  string|null $property
@param  mixed $default
@return mixed|array

Get the entity original attribute values .


public function hasCast($property, $types = null)
    {
        if (array_key_exists($property, $this->casts)) {
            return $types ? in_array($this->getCastType($property), (array)$types, true) : true;
        }

        return false;
    }

public function hasCast ( $ property , $ types = null ) { if ( array_key_exists ( $ property , $ this -> casts ) ) { return $ types ? in_array ( $ this -> getCastType ( $ property ) , ( array ) $ types , true ) : true ; } return false ; }

Determine whether an attribute should be cast to a native type.

@param  string $property
@param  array|string|null $types
@return bool

Determine whether an attribute should be cast to a native type .