protected function convertArrayToHeaderString(array $data) {
        $strings = [];
        foreach ($data as $key => $val) {
            if (null === $val) {
                $strings[] = $key;
                continue;
            }
            if (is_bool($val)) {
                $val = !empty($val) ? 1 : 0;
            }
            $strings[] = $key . '=' . $val;
        }
        return implode('; ', $strings);
    }

protected
function
convertArrayToHeaderString
(
array
$
data
)
{
$
strings
=
[
]
;
foreach
(
$
data
as
$
key
=>
$
val
)
{
if
(
===
$
val
)
{
$
strings
[
]
=
$
key
;
continue
;
}
if
(
is_bool
(
$
val
)
)
{
$
val
=
!
empty
(
$
val
)
1
:
0
;
}
$
strings
[
]
=
$
key
.
'='
.
$
val
;
}
return
implode
(
'; '
,
$
strings
)
;
}

Convert cookie data array to Set-cookie header string
@param array $data
@return string

Convert cookie data array to Set - cookie header string


protected function combine($array, $section_sep) {
		foreach ($array as $section_spec => $settings) {
			$section_spec = array_map("trim", explode($section_sep, $section_spec));
			if (count($section_spec) > 1) {
				$sections[$section_spec[0]] = array_merge(
					$sections[$section_spec[1]],
					$settings
				);
			} else {
				$sections[$section_spec[0]] = $settings;
			}
		}
		return $sections;
	}

protected function combine ( $ array , $ section_sep ) { foreach ( $ array as $ section_spec => $ settings ) { $ section_spec = array_map ( "trim" , explode ( $ section_sep , $ section_spec ) ) ; if ( count ( $ section_spec ) > 1 ) { $ sections [ $ section_spec [ 0 ] ] = array_merge ( $ sections [ $ section_spec [ 1 ] ] , $ settings ) ; } else { $ sections [ $ section_spec [ 0 ] ] = $ settings ; } } return $ sections ; }

Combine individual sections with their parent section
@param array $array the config array
@param string $section_sep the section extension separator
@return array merged sections


protected function walk(&$ptr, $key, $val, $key_sep) {
		foreach (explode($key_sep, $key) as $sub) {
			$ptr = &$ptr[$sub];
		}
		$ptr = $val;
	}

protected function walk ( & $ ptr , $ key , $ val , $ key_sep ) { foreach ( explode ( $ key_sep , $ key ) as $ sub ) { $ ptr = & $ ptr [ $ sub ] ; } $ ptr = $ val ; }

Walk a key split by the key separator into an array up and set the
respective value on the leaf
@param mixed $ptr current leaf pointer in the array
@param string $key the array key
@param mixed $val the value to set
@param string $key_sep the key separator for traversal


public function explode($string, $delimiter = ',', $trim = true, $skipEmpty = false)
    {
        return $this->proxy(__FUNCTION__, [$string, $delimiter, $trim, $skipEmpty]);
    }

public function explode ( $ string , $ delimiter = ',' , $ trim = true , $ skipEmpty = false ) { return $ this -> proxy ( __FUNCTION__ , [ $ string , $ delimiter , $ trim , $ skipEmpty ] ) ; }

Explodes string into array, optionally trims values and skips empty ones.

@param string $string String to be exploded.
@param string $delimiter Delimiter. Default is ','.
@param mixed $trim Whether to trim each element. Can be:
- boolean - to trim normally;
- string - custom characters to trim. Will be passed as a second argument to `trim()` function.
- callable - will be called for each value instead of trim. Takes the only argument - value.
@param bool $skipEmpty Whether to skip empty strings between delimiters. Default is false.
@return array
@see \Reaction\Helpers\StringHelper::explode()

Explodes string into array optionally trims values and skips empty ones .


public function reportAction($code = null)
    {
        $referer = $this->getContainer()->get('router')->getReferer();
        $txt_message = $this->view(
            'error_mail_content',
            array(
                'url'=>$referer,
                'code'=>$code
            )
        );

        $webmaster_email = CarteBlanche::getConfig('app.webmaster_email', null);
        $webmaster_name = CarteBlanche::getConfig('app.webmaster_name', null);
        $mail = new \MimeEmail\Lib\MimeEmail();
        $mail
            ->setTo($webmaster_email, $webmaster_name)
            ->setSubject($this->trans('Error report'))
            ->setText($txt_message);
        $ok = $mail->send(true);
        if ($ok) {
            $this->getContainer()->get('session')
                ->setFlash("info:".$this->trans('OK - A report has been sent concerning your error. Thank you.'));
        } else {
            $this->getContainer()->get('session')
                ->setFlash("error:".$this->trans('ERROR - An error occurred while trying to send email ...'));
        }
        $this->getContainer()->get('router')->redirect($_SERVER['HTTP_REFERER']);
    }

Send a mail report to the website contact


public function error403Action()
    {
        $this->getContainer()->get('router')->setReferer();
        $_args=array(
            'offset'=>null,'limit'=>null,'table'=>null,'altdb'=>null,
            'orderby'=>null, 'orderway'=>null
        );
        $url_args = CarteBlanche::getConfig('routing.arguments_mapping');
        foreach ($_args as $_arg_var=>$_arg_val) {
            if (!empty($_arg_val)) {
                if (in_array($_arg_var, $url_args))
                    $args[ array_search($_arg_var, $url_args) ] = $_arg_val;
                else
                    $args[ $_arg_var ] = $_arg_val;
            }
        }
        $searchbox = new \Tool\SearchBox(array(
            'hiddens'=>$_args, 'advanced_search'=>true
        ));
        $ctt = (string) $searchbox;

        $_f = CarteBlanche::getContainer()->get('locator')->locateView(self::$views_dir.'403.md');
        $_txt = new \Tool\Text(array(
//            'original_str'=>file_get_contents(CarteBlanche::getPath('root_path')._CarteBlanche_DIR._VIEWSDIR.self::$views_dir.'404.md'),
            'original_str'=>file_get_contents($_f),
            'markdown'=>true,
        ));
        $ctt .= $_txt;

        $params = array(
            'title'=>$this->trans('OOPS ! You can\'t access this page !!'),
            'content'=>$ctt,
            'sitemap_url'=>CarteBlanche::getContainer()->get('router')->buildUrl(array(
                'controller'=>'cms','action'=>'sitemap'
            )),
            'report_error'=>CarteBlanche::getContainer()->get('router')->buildUrl(array(
                'controller'=>'error','action'=>'report','code'=>'403'
            ))
        );
        $params['output'] = CarteBlanche::getContainer()->get('front_controller')
            ->view(self::$views_dir.'error', $params);
        return CarteBlanche::getContainer()->get('front_controller')->render($params);
    }

The "not found" error page

@return string The 403 forbidden error page view content


public function extractParameters(string $path): array
    {
        if ($this->routeParameters === []) {
            return [];
        }
        $parameters = [];
        $pathArray = explode('/', $path);
        array_shift($pathArray);
        foreach ($this->routeParameters as $index => $parameter) {
            $parameterAction = $this->routeParametersOptions[$parameter] ??
                function (string $parameter): string {
                    return $parameter;
                };
            $parameters[$parameter] = $parameterAction($pathArray[$index]);
        }
        return $parameters;
    }

public function extractParameters ( string $ path ) : array { if ( $ this -> routeParameters === [ ] ) { return [ ] ; } $ parameters = [ ] ; $ pathArray = explode ( '/' , $ path ) ; array_shift ( $ pathArray ) ; foreach ( $ this -> routeParameters as $ index => $ parameter ) { $ parameterAction = $ this -> routeParametersOptions [ $ parameter ] ?? function ( string $ parameter ) : string { return $ parameter ; } ; $ parameters [ $ parameter ] = $ parameterAction ( $ pathArray [ $ index ] ) ; } return $ parameters ; }

Extract parameters value from path

@param string $path Uri path that match to route without query

@return mixed[] Map parameter_name => value
@throws \Throwable If any route parameter option throw exception


public function getController()
    {
        $params         = $this->requestDataReader->getRequestData()->getParameters();
        $controllerName = $this->appConfig->getDefaultInteractor();

        if (isset($params['interactor'])) {
            $controllerName = $params['interactor'];
        };

        $controllerArrayKey = $controllerName.'Controller';

        if (!array_key_exists($controllerArrayKey, $this->controllerFactories)) {
            throw new ControllerNotFoundException('Controller \''.$controllerName.'\' not found.');
        }

        return $this->controllerFactories[$controllerArrayKey]->createInstance();
    }

public
function
getController
(
)
{
$
params
=
$
this
->
requestDataReader
->
getRequestData
(
)
->
getParameters
(
)
;
$
controllerName
=
$
this
->
appConfig
->
getDefaultInteractor
(
)
;
if
(
isset
(
$
params
[
'interactor'
]
)
)
{
$
controllerName
=
$
params
[
'interactor'
]
;
}
;
$
controllerArrayKey
=
$
controllerName
.
'Controller'
;
if
(
!
array_key_exists
(
$
controllerArrayKey
,
$
this
->
controllerFactories
)
)
{
throw
new
ControllerNotFoundException
(
'Controller \''
.
$
controllerName
.
'\' not found.'
)
;
}
return
$
this
->
controllerFactories
[
$
controllerArrayKey
]
->
createInstance
(
)
;
}

Gets controller instance.
Controller instance is produced with factory of name from request or default name from configuration.

@return IController Instance of produced controller.

@throws ControllerNotFoundException If factory with given name does not exists.

Gets controller instance . Controller instance is produced with factory of name from request or default name from configuration .


private function _getButtons($buttons, $row) {
        $html = '';
        foreach($buttons as $value) {
            if(isset($value['audit']) && $value['audit']($row) == 0) {
                continue;
            }
            $tmp='evaluateExpression($value['url'], array('data'=>$row));
            } elseif(isset($value['action'])) {
                $value['options']['class']='gridview-'.$value['action'];
                $tmp.=url().'/'.$this->controller->id.'/'.$value['action'].'?id='.$row['id'].'&from='.urlencode($_SERVER['REQUEST_URI']);
            }
            $tmp .= '"';
            if (isset($value['options']) && is_array($value['options']) && !empty($value['options'])) {
                $tmp.=$this->_getOptions($value['options']);
            }
            $tmp.='">'.$value['name'].'  ';

            $html.=$tmp;
        }

        return $html;
    }

private
function
_getButtons
(
$
buttons
,
$
row
)
{
$
html
=
''
;
foreach
(
$
buttons
as
$
value
)
{
if
(
isset
(
$
value
[
'audit'
]
)
&&
$
value
[
'audit'
]
(
$
row
)
==
0
)
{
continue
;
}
$
tmp
=
'
evaluateExpression
(
$
value
[
'url'
]
,
array
(
'data'
=>
$
row
)
)
;
}
elseif
(
isset
(
$
value
[
'action'
]
)
)
{
$
value
[
'options'
]
[
'class'
]
=
'gridview-'
.
$
value
[
'action'
]
;
$
tmp
.=
url
(
)
.
'/'
.
$
this
->
controller
->
id
.
'/'
.
$
value
[
'action'
]
.
'?id='
.
$
row
[
'id'
]
.
'&from='
.
urlencode
(
$
_SERVER
[
'REQUEST_URI'
]
)
;
}
$
tmp
.=
'"'
;
if
(
isset
(
$
value
[
'options'
]
)
&&
is_array
(
$
value
[
'options'
]
)
&&
!
empty
(
$
value
[
'options'
]
)
)
{
$
tmp
.=
$
this
->
_getOptions
(
$
value
[
'options'
]
)
;
}
$
tmp
.=
'">'
.
$
value
[
'name'
]
.
'  '
;
$
html
.=
$
tmp
;
}
return
$
html
;
}

get button html code
@param $buttons array the button array
@param $row array current row data
@return string the html code of button


private function _getOptions($options) {
        $optionsHtml='';
        if (!empty($options)) {
            if(is_array($options)) {
                foreach($options as $key => $value) {
                    $optionsHtml.=' '.$key.'="'.$value.'"';
                }
            } else {
                $optionsHtml=' class="'.$options.'"';
            }
        }
        return $optionsHtml;
    }

private
function
_getOptions
(
$
options
)
{
$
optionsHtml
=
''
;
if
(
!
empty
(
$
options
)
)
{
if
(
is_array
(
$
options
)
)
{
foreach
(
$
options
as
$
key
=>
$
value
)
{
$
optionsHtml
.=
' '
.
$
key
.
'="'
.
$
value
.
'"'
;
}
}
else
{
$
optionsHtml
=
' class="'
.
$
options
.
'"'
;
}
}
return
$
optionsHtml
;
}

get item option html code
@param $options array html options
@return string the html code of options


public function evaluateExpression($_expression_, $_data_) {
        // debug($_data_);
        // debug($_expression_);
        // die;
        if (is_string($_expression_)) {
            extract($_data_);
            return eval('return '.$_expression_.';');
        } else {
            $_data_[]=$this;
            return call_user_func_array($_expression_, $_data_);
        }
    }

public
function
evaluateExpression
(
$
_expression_
,
$
_data_
)
{
// debug($_data_);
// debug($_expression_);
// die;
if
(
is_string
(
$
_expression_
)
)
{
extract
(
$
_data_
)
;
return
eval
(
'return '
.
$
_expression_
.
';'
)
;
}
else
{
$
_data_
[
]
=
$
this
;
return
call_user_func_array
(
$
_expression_
,
$
_data_
)
;
}
}

Evaluates a PHP expression.

@param mixed $_expression_ a PHP expression or PHP callback to be evaluated.
@param array $_data_ additional parameters to be passed to the above expression/callback.
@return mixed the expression result


public function getZone(String $zone) {
        $this->path = "zone/"  . $zone;
        $response = $this->request();

        return new Zone($response);
    }

public function getZone ( String $ zone ) { $ this -> path = "zone/" . $ zone ; $ response = $ this -> request ( ) ; return new Zone ( $ response ) ; }

Get A Zone based on the Name
@param String $zone The Zone to be searched
@return Zone the Zone Object


public function addRecord(String $domain, int $ttl, String $recordType, String $value) {
        return $this->manage($domain, $ttl, $recordType, $value);
    }

public function addRecord ( String $ domain , int $ ttl , String $ recordType , String $ value ) { return $ this -> manage ( $ domain , $ ttl , $ recordType , $ value ) ; }

PUT OR POST
@param String $domain
@param int $ttl
@param String $recordType
@param String $value
@return bool


public function table($table_name)
    {
        if (!is_string($table_name)) {
            throw new Exception\InvalidArgumentException(__METHOD__ . ": Table name must be a string");
        }

        if (!$this->localTableCache->offsetExists($table_name)) {
            $tables = $this->metadata()->getTables();
            if (!in_array($table_name, $tables)) {
                throw new Exception\TableNotFoundException(__METHOD__ . ": Table $table_name is not found in database, if table exists please make sure cache is updated.");
            }
            $table = new Table($table_name, $this);
            $this->localTableCache->offsetSet($table_name, $table);
        }
        return $this->localTableCache->offsetGet($table_name);
    }

Return a synthetic table

@param string $table_name table name

@throws Exception\InvalidArgumentException if table name is not valid

@return Table


public function transaction()
    {
        if ($this->transaction === null) {
            $this->transaction = new Transaction($this->adapter);
        }
        return $this->transaction;
    }

public function transaction ( ) { if ( $ this -> transaction === null ) { $ this -> transaction = new Transaction ( $ this -> adapter ) ; } return $ this -> transaction ; }

Return a transaction object

@return Transaction


protected function loadDefaultMetadata()
    {
        $adapterName = $this->adapter->getPlatform()->getName();
        switch (strtolower($adapterName)) {
            case 'mysql':
                // supported
                break;
            default:
                throw new Exception\UnsupportedFeatureException(__METHOD__ . ":  Adapter '$adapterName' is not yet supported.");
        }
        $this->metadata = $this->driver->getMetadata();
    }

Return default metadata reader associated to an adapter

@throws Exception\UnsupportedFeatureException


public function setParentId($parentId)
    {
        $parentId = (int) $parentId;

        if ($this->parentId < 0) {
            throw new \UnderflowException('Value of "parentId" must be greater than 0');
        }

        if ($this->exists() && $this->parentId !== $parentId) {
            $this->updated['parentId'] = true;
        }

        $this->parentId = $parentId;

        return $this;
    }

Set value for field "category_parent_id"

@param  int $parentId
@return $this
@throws \UnderflowException


public function getBudgetCategory($isForceReload = false)
    {
        if ($isForceReload || null === $this->joinOneCacheBudgetCategory) {
            $mapper = new BudgetCategoryMapper($this->dependencyContainer->getDatabase('money'));
            $this->joinOneCacheBudgetCategory = $mapper->findByKeys(array(
                'category_id' => $this->getId(),
            ));
        }

        return $this->joinOneCacheBudgetCategory;
    }

public function getBudgetCategory ( $ isForceReload = false ) { if ( $ isForceReload || null === $ this -> joinOneCacheBudgetCategory ) { $ mapper = new BudgetCategoryMapper ( $ this -> dependencyContainer -> getDatabase ( 'money' ) ) ; $ this -> joinOneCacheBudgetCategory = $ mapper -> findByKeys ( array ( 'category_id' => $ this -> getId ( ) , ) ) ; } return $ this -> joinOneCacheBudgetCategory ; }

Get BudgetCategory data object.

@param  bool $isForceReload
@return BudgetCategory


public function getAllCategoryWord($isForceReload = false)
    {
        if ($isForceReload || null === $this->joinManyCacheCategoryWord) {
            $mapper = new CategoryWordMapper($this->dependencyContainer->getDatabase('money'));
            $mapper->addWhere('category_id', $this->getId());

            $this->joinManyCacheCategoryWord = $mapper->select();
        }

        return $this->joinManyCacheCategoryWord;
    }

public function getAllCategoryWord ( $ isForceReload = false ) { if ( $ isForceReload || null === $ this -> joinManyCacheCategoryWord ) { $ mapper = new CategoryWordMapper ( $ this -> dependencyContainer -> getDatabase ( 'money' ) ) ; $ mapper -> addWhere ( 'category_id' , $ this -> getId ( ) ) ; $ this -> joinManyCacheCategoryWord = $ mapper -> select ( ) ; } return $ this -> joinManyCacheCategoryWord ; }

Get list of CategoryWord data objects.

@param  bool $isForceReload
@return CategoryWord[]


public function flushCache()
    {
        foreach ($this->tags as $tag) {
            $this->_removeCacheDatas($tag);
        }

        $this->items = [];

        return $this;
    }

public function flushCache ( ) { foreach ( $ this -> tags as $ tag ) { $ this -> _removeCacheDatas ( $ tag ) ; } $ this -> items = [ ] ; return $ this ; }


public function add(string $key)
    {
        foreach ($this->items as  &$items) {
            array_push($items, $key);
        }

        return $this;
    }

public function add ( string $ key ) { foreach ( $ this -> items as & $ items ) { array_push ( $ items , $ key ) ; } return $ this ; }

Add cached key.

@param string $key 缓存的key

@return static


public function remove(string $key)
    {
        foreach ($this->items as  &$items) {
            if ($pos = array_search($key, $items)) {
                array_splice($items, $pos, 1);
            }
        }

        return $this;
    }

public function remove ( string $ key ) { foreach ( $ this -> items as & $ items ) { if ( $ pos = array_search ( $ key , $ items ) ) { array_splice ( $ items , $ pos , 1 ) ; } } return $ this ; }

Remove cached key.

@param string $key 缓存的key

@return static


private function _removeCacheDatas($tag)
    {
        // 删除缓存的数据
        $this->manager->deleteMultiple($this->items[$tag]);

        $key = $this->normalizeTagForKey($tag);
        // 删除缓存键
        $this->manager->delete($key);
        // 删除数据库存储的键
        try {
            Entity::where('key', '=', $key)->delete();
        } catch (\Exception $e) {
            if ($this->manager->debug()) {
                throw $e;
            } else {
                $logger = $this->manager->logger();
                if ($logger) {
                    $logger->warning($e->getMessage(), ['tag' => $tag, 'key' => $key]);
                }
            }
        }

        return $this;
    }

private
function
_removeCacheDatas
(
$
tag
)
{
// 删除缓存的数据
$
this
->
manager
->
deleteMultiple
(
$
this
->
items
[
$
tag
]
)
;
$
key
=
$
this
->
normalizeTagForKey
(
$
tag
)
;
// 删除缓存键
$
this
->
manager
->
delete
(
$
key
)
;
// 删除数据库存储的键
try
{
Entity
::
where
(
'key'
,
'='
,
$
key
)
->
delete
(
)
;
}
catch
(
\
Exception
$
e
)
{
if
(
$
this
->
manager
->
debug
(
)
)
{
throw
$
e
;
}
else
{
$
logger
=
$
this
->
manager
->
logger
(
)
;
if
(
$
logger
)
{
$
logger
->
warning
(
$
e
->
getMessage
(
)
,
[
'tag'
=>
$
tag
,
'key'
=>
$
key
]
)
;
}
}
}
return
$
this
;
}

Flush the cache data.

@param string $tag 标签

@return static


public function getBoolean($key, $default = null)
    {
        $value = $this->get($key, $default);
        if (is_numeric($value)) {
            $value = intval($value);
        } elseif (is_string($value)) {
            $value = strtolower($value) == 'true' ? true : false;
        }

        return $value ? true : false;
    }

public function getBoolean ( $ key , $ default = null ) { $ value = $ this -> get ( $ key , $ default ) ; if ( is_numeric ( $ value ) ) { $ value = intval ( $ value ) ; } elseif ( is_string ( $ value ) ) { $ value = strtolower ( $ value ) == 'true' ? true : false ; } return $ value ? true : false ; }

Additionally converts 1, "1", and "true" to true and 0, "0", and "false" to false
@param $key
@param  null $default
@return bool

Additionally converts 1 1 and true to true and 0 0 and false to false


public static function create($params = null, Request $request = null)
    {
        if ($params === null) {
            return new Params();
        } elseif (is_array($params)) {
            return new Params($params);
        } elseif ($params instanceof \Traversable) {
            return new Params(self::extractParamsFromCollection($params));
        } elseif ($params instanceof \Zend\Mvc\Controller\Plugin\Params) {
            $results = array();
            /* @var $r \Zend\Http\Request */
            foreach (array(
                         $params->fromQuery(),
                         $params->fromPost(),
                         self::getBodyData($request),
                         $params->fromRoute(),
                         $params->fromFiles(),
                     ) as $collection) {
                $results = array_merge($results, $collection);
            }

            return new Params($results);
        } elseif ($params instanceof Param) {
            return new Params($params->get());
        }
        throw new \InvalidArgumentException("Unrecognized parameter collection");
    }

public
static
function
create
(
$
params
=
,
Request
$
request
=
)
{
if
(
$
params
===
)
{
return
new
Params
(
)
;
}
elseif
(
is_array
(
$
params
)
)
{
return
new
Params
(
$
params
)
;
}
elseif
(
$
params
instanceof
\
Traversable
)
{
return
new
Params
(
self
::
extractParamsFromCollection
(
$
params
)
)
;
}
elseif
(
$
params
instanceof
\
Zend
\
Mvc
\
Controller
\
Plugin
\
Params
)
{
$
results
=
array
(
)
;
/* @var $r \Zend\Http\Request */
foreach
(
array
(
$
params
->
fromQuery
(
)
,
$
params
->
fromPost
(
)
,
self
::
getBodyData
(
$
request
)
,
$
params
->
fromRoute
(
)
,
$
params
->
fromFiles
(
)
,
)
as
$
collection
)
{
$
results
=
array_merge
(
$
results
,
$
collection
)
;
}
return
new
Params
(
$
results
)
;
}
elseif
(
$
params
instanceof
Param
)
{
return
new
Params
(
$
params
->
get
(
)
)
;
}
throw
new
\
InvalidArgumentException
(
"Unrecognized parameter collection"
)
;
}

Create a Param instance
@param  null                      $params
@param  null|Request              $request
@return Params
@throws \InvalidArgumentException


public static function extractParamsFromCollection($collection)
    {
        $result = array();
        foreach ($collection as $key => $value) {
            $result[$key] = $value;
        }

        return $result;
    }

public static function extractParamsFromCollection ( $ collection ) { $ result = array ( ) ; foreach ( $ collection as $ key => $ value ) { $ result [ $ key ] = $ value ; } return $ result ; }

Converts an iterable collection into a raw array
@param $collection
@return array


public function onConsoleCommandLoaded(ConsoleEvent $event)
    {
        $command = $event->getCommand();
        $command->getApplication()->getContainer()['monolog']->addInfo(
            sprintf(
                'Command \'%s\' Loaded as \'%s\'', get_class($command),
                $command->getName()
            )
        );
    }

public
function
onConsoleCommandLoaded
(
ConsoleEvent
$
event
)
{
$
command
=
$
event
->
getCommand
(
)
;
$
command
->
getApplication
(
)
->
getContainer
(
)
[
'monolog'
]
->
addInfo
(
sprintf
(
'Command \'%s\' Loaded as \'%s\''
,
get_class
(
$
command
)
,
$
command
->
getName
(
)
)
)
;
}

Fires when command is loaded into console application

@param ConsoleEvent $event ConsoleEvent instance

@return void


public function pushGroup($pattern, $callable)
    {
        $group = new Group($pattern, $callable);

        array_push($this->routeGroups, $group);

        return $group;
    }

public function pushGroup ( $ pattern , $ callable ) { $ group = new Group ( $ pattern , $ callable ) ; array_push ( $ this -> routeGroups , $ group ) ; return $ group ; }

Add a route group to the array

@param string   $pattern
@param callable $callable

@return GroupInterface


protected function getAllClassesAnnotationsByType(string $type, string ...$classes): array
    {
        $annotations = [];

        // Iterate through all the classes
        foreach ($classes as $class) {
            // Get all the annotations for each class and iterate through them
            /** @var \Valkyrja\Annotations\Annotation $annotation */
            foreach ($this->classAndMembersAnnotationsType(
                $type,
                $class
            ) as $annotation) {
                $this->setServiceProperties($annotation);

                // If this annotation is a service
                if ($type === $this->servicesAnnotationType) {
                    /* @var \Valkyrja\Container\Annotations\Service $annotation */
                    $annotations[] =
                        $this->getServiceFromAnnotation($annotation);

                    continue;
                }

                // If this annotation is a context service
                if ($type === $this->contextServicesAnnotationType) {
                    /* @var \Valkyrja\Container\Annotations\ServiceContext $annotation */
                    $annotations[] =
                        $this->getServiceContextFromAnnotation($annotation);

                    continue;
                }

                // Set the annotation in the annotations list
                $annotations[] = $annotation;
            }
        }

        return $annotations;
    }

Get all annotations for a class and its members by type.

@param string   $type       The type
@param string[] ...$classes The classes

@throws \ReflectionException

@return array

Get all annotations for a class and its members by type .


protected function setServiceProperties(Annotation $annotation): void
    {
        if (null === $annotation->getProperty()) {
            $parameters =
                $this->getMethodReflection(
                    $annotation->getClass(),
                    $annotation->getMethod() ?? '__construct'
                )
                     ->getParameters();

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

        $annotation->setMatches();
    }

protected
function
setServiceProperties
(
Annotation
$
annotation
)
:
void
{
if
(
===
$
annotation
->
getProperty
(
)
)
{
$
parameters
=
$
this
->
getMethodReflection
(
$
annotation
->
getClass
(
)
,
$
annotation
->
getMethod
(
)
??
'__construct'
)
->
getParameters
(
)
;
// Set the dependencies
$
annotation
->
setDependencies
(
$
this
->
getDependencies
(
...
$
parameters
)
)
;
}
$
annotation
->
setMatches
(
)
;
}

Set the properties for a service annotation.

@param Annotation $annotation

@throws \ReflectionException

@return void

Set the properties for a service annotation .


protected function getServiceFromAnnotation(Service $service): ContainerService
    {
        $containerService = new ContainerService();

        $containerService
            ->setDefaults($service->getDefaults())
            ->setSingleton($service->isSingleton())
            ->setId($service->getId())
            ->setName($service->getName())
            ->setClass($service->getClass())
            ->setProperty($service->getProperty())
            ->setMethod($service->getMethod())
            ->setStatic($service->isStatic())
            ->setFunction($service->getFunction())
            ->setMatches($service->getMatches())
            ->setDependencies($service->getDependencies())
            ->setArguments($service->getArguments());

        return $containerService;
    }

protected function getServiceFromAnnotation ( Service $ service ) : ContainerService { $ containerService = new ContainerService ( ) ; $ containerService -> setDefaults ( $ service -> getDefaults ( ) ) -> setSingleton ( $ service -> isSingleton ( ) ) -> setId ( $ service -> getId ( ) ) -> setName ( $ service -> getName ( ) ) -> setClass ( $ service -> getClass ( ) ) -> setProperty ( $ service -> getProperty ( ) ) -> setMethod ( $ service -> getMethod ( ) ) -> setStatic ( $ service -> isStatic ( ) ) -> setFunction ( $ service -> getFunction ( ) ) -> setMatches ( $ service -> getMatches ( ) ) -> setDependencies ( $ service -> getDependencies ( ) ) -> setArguments ( $ service -> getArguments ( ) ) ; return $ containerService ; }

Get a service from a service annotation.

@param Service $service The service annotation

@return \Valkyrja\Container\Service

Get a service from a service annotation .


protected function getServiceContextFromAnnotation(ServiceContext $service): ContainerContextService
    {
        $containerService = new ContainerContextService();

        $containerService
            ->setContextClass($service->getContextClass())
            ->setContextProperty($service->getContextProperty())
            ->setContextMethod($service->getContextMethod())
            ->setContextFunction($service->getContextFunction())
            ->setDefaults($service->getDefaults())
            ->setSingleton($service->isSingleton())
            ->setId($service->getId())
            ->setName($service->getName())
            ->setClass($service->getClass())
            ->setProperty($service->getProperty())
            ->setMethod($service->getMethod())
            ->setStatic($service->isStatic())
            ->setFunction($service->getFunction())
            ->setMatches($service->getMatches())
            ->setDependencies($service->getDependencies())
            ->setArguments($service->getArguments());

        return $containerService;
    }

protected function getServiceContextFromAnnotation ( ServiceContext $ service ) : ContainerContextService { $ containerService = new ContainerContextService ( ) ; $ containerService -> setContextClass ( $ service -> getContextClass ( ) ) -> setContextProperty ( $ service -> getContextProperty ( ) ) -> setContextMethod ( $ service -> getContextMethod ( ) ) -> setContextFunction ( $ service -> getContextFunction ( ) ) -> setDefaults ( $ service -> getDefaults ( ) ) -> setSingleton ( $ service -> isSingleton ( ) ) -> setId ( $ service -> getId ( ) ) -> setName ( $ service -> getName ( ) ) -> setClass ( $ service -> getClass ( ) ) -> setProperty ( $ service -> getProperty ( ) ) -> setMethod ( $ service -> getMethod ( ) ) -> setStatic ( $ service -> isStatic ( ) ) -> setFunction ( $ service -> getFunction ( ) ) -> setMatches ( $ service -> getMatches ( ) ) -> setDependencies ( $ service -> getDependencies ( ) ) -> setArguments ( $ service -> getArguments ( ) ) ; return $ containerService ; }

Get a service context from a service context annotation.

@param ServiceContext $service The service context annotation

@return \Valkyrja\Container\ServiceContext

Get a service context from a service context annotation .


public function getCache() {
        if (!isset($this->_cache) && isset($this->cacheComponent)) {
            if ($this->cacheComponent instanceof ExtendedCacheInterface) {
                $this->_cache = $this->cacheComponent;
            } else {
                $this->_cache = \Reaction::create($this->cacheComponent);
            }
        }
        return $this->_cache;
    }

public function getCache ( ) { if ( ! isset ( $ this -> _cache ) && isset ( $ this -> cacheComponent ) ) { if ( $ this -> cacheComponent instanceof ExtendedCacheInterface ) { $ this -> _cache = $ this -> cacheComponent ; } else { $ this -> _cache = \ Reaction :: create ( $ this -> cacheComponent ) ; } } return $ this -> _cache ; }

Get cache component
@return ExpiringCacheInterface|null


public function getQueryBuilder() {
        if (!isset($this->_queryBuilder)) {
            /** @var QueryBuilderInterface $queryBuilder */
            $queryBuilder = $this->createComponent(QueryBuilderInterface::class);
            $this->_queryBuilder = $queryBuilder;
        }
        return $this->_queryBuilder;
    }

Get query builder
@return QueryBuilderInterface


protected function createComponent($interface, $config = [], $injectDb = true) {
        if (!isset($this->componentsConfig[$interface])) {
            $message = sprintf('Suitable component for interface "%s" not configured in "%s"', $interface, __CLASS__);
            throw new InvalidConfigException($message);
        }
        $className = $this->componentsConfig[$interface];
        $_config = is_array($className) ? $className : ['class' => $className];
        $_config = ArrayHelper::merge($_config, $config);
        if ($injectDb) {
            $_config = ArrayHelper::merge(['db' => $this], $_config);
        }
        return \Reaction::create($_config);
    }

Create inner component
@param string $interface
@param array  $config
@param bool   $injectDb
@return QueryBuilderInterface|SchemaInterface|CommandInterface|ColumnSchemaInterface|ConnectionInterface|TransactionInterface
@throws null


public function getStatedClassNameToken(string $statedClassName, $removeProxyName = false): string
    {
        $statedClassNamePart = \explode('\\', $statedClassName);
        if (true === $removeProxyName) {
            \array_pop($statedClassNamePart);
        }

        return \strtolower(\implode('_', $statedClassNamePart));
    }

public function getStatedClassNameToken ( string $ statedClassName , $ removeProxyName = false ) : string { $ statedClassNamePart = \ explode ( '\\' , $ statedClassName ) ; if ( true === $ removeProxyName ) { \ array_pop ( $ statedClassNamePart ) ; } return \ strtolower ( \ implode ( '_' , $ statedClassNamePart ) ) ; }

To get the token from a stated class.

@param string $statedClassName
@param bool   $removeProxyName

@return string


public function getStatedClassInstanceToken(LifeCyclableInterface $object): string
    {
        $statedClassName = \get_class($object);

        return $this->getStatedClassNameToken($statedClassName, true);
    }

public function getStatedClassInstanceToken ( LifeCyclableInterface $ object ) : string { $ statedClassName = \ get_class ( $ object ) ; return $ this -> getStatedClassNameToken ( $ statedClassName , true ) ; }

To get the token from a stated class instance.

@param LifeCyclableInterface $object

@return string

To get the token from a stated class instance .


function listCategory($base, $category, $info = false, $channel = false)
    {
        if ($info == false) {
            $url = '%s'.'c/%s/packages.xml';
        } else {
            $url = '%s'.'c/%s/packagesinfo.xml';
        }
        $url = sprintf($url,
                    $base,
                    urlencode($category));

        // gives '404 Not Found' error when category doesn't exist
        $packagelist = $this->_rest->retrieveData($url, false, false, $channel);
        if (PEAR::isError($packagelist)) {
            return $packagelist;
        }
        if (!is_array($packagelist)) {
            return array();
        }

        if ($info == false) {
            if (!isset($packagelist['p'])) {
                return array();
            }
            if (!is_array($packagelist['p']) ||
                !isset($packagelist['p'][0])) { // only 1 pkg
                $packagelist = array($packagelist['p']);
            } else {
                $packagelist = $packagelist['p'];
            }
            return $packagelist;
        }

        // info == true
        if (!isset($packagelist['pi'])) {
            return array();
        }

        if (!is_array($packagelist['pi']) ||
            !isset($packagelist['pi'][0])) { // only 1 pkg
            $packagelist_pre = array($packagelist['pi']);
        } else {
            $packagelist_pre = $packagelist['pi'];
        }

        $packagelist = array();
        foreach ($packagelist_pre as $i => $item) {
            // compatibility with r/<latest.txt>.xml
            if (isset($item['a']['r'][0])) {
                // multiple releases
                $item['p']['v'] = $item['a']['r'][0]['v'];
                $item['p']['st'] = $item['a']['r'][0]['s'];
            } elseif (isset($item['a'])) {
                // first and only release
                $item['p']['v'] = $item['a']['r']['v'];
                $item['p']['st'] = $item['a']['r']['s'];
            }

            $packagelist[$i] = array('attribs' => $item['p']['r'],
                                     '_content' => $item['p']['n'],
                                     'info' => $item['p']);
        }

        return $packagelist;
    }

List packages in a category of a REST server

@param string $base base URL of the server
@param string $category name of the category
@param boolean $info also download full package info
@return array of packagenames


function betterStates($state, $include = false)
    {
        static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
        $i = array_search($state, $states);
        if ($i === false) {
            return false;
        }
        if ($include) {
            $i--;
        }
        return array_slice($states, $i + 1);
    }

function betterStates ( $ state , $ include = false ) { static $ states = array ( 'snapshot' , 'devel' , 'alpha' , 'beta' , 'stable' ) ; $ i = array_search ( $ state , $ states ) ; if ( $ i === false ) { return false ; } if ( $ include ) { $ i -- ; } return array_slice ( $ states , $ i + 1 ) ; }

Return an array containing all of the states that are more stable than
or equal to the passed in state

@param string Release state
@param boolean Determines whether to include $state in the list
@return false|array False if $state is not a valid release state


private function compileCommand()
    {
        $command = '';

        if ($this->sudo) {
            $command = 'sudo ';
        }
        $command .= escapeshellcmd($this->applicationPath) . $this->generateArguments();
        if ($this->stdError) {
            $command .= ' 2>&1';
        }
        return $command;
    }

private
function
compileCommand
(
)
{
$
command
=
''
;
if
(
$
this
->
sudo
)
{
$
command
=
'sudo '
;
}
$
command
.=
escapeshellcmd
(
$
this
->
applicationPath
)
.
$
this
->
generateArguments
(
)
;
if
(
$
this
->
stdError
)
{
$
command
.=
' 2>&1'
;
}
return
$
command
;
}

Compiles the command that will be executed

@return string


protected function generateArguments()
    {
        $arguments = '';
        if (!$this->applicationArguments->isEmpty()) {
            $arguments = ' ' . $this->applicationArguments->implode();
        }
        return $arguments;
    }

protected
function
generateArguments
(
)
{
$
arguments
=
''
;
if
(
!
$
this
->
applicationArguments
->
isEmpty
(
)
)
{
$
arguments
=
' '
.
$
this
->
applicationArguments
->
implode
(
)
;
}
return
$
arguments
;
}

Generates a list of arguments to be appended onto the executed path.

@return string The generated list of arguments.

Generates a list of arguments to be appended onto the executed path .


private function executeProcess()
    {
        $command = $this->compileCommand();
        exec($command, $result, $status);
        if ($status > 0) {
            throw new Exceptions\ExecutionException('Unknown error occurred when attempting to execute: ' . $command . PHP_EOL);
        }
        return $result;
    }

Executes the process.

@return array
@throws Exceptions\ExecutionException


private function save()
    {
        foreach ($this->stream as $key => $file) {
            $layer = ucwords($key);
            $namespace = Text::replace($this->namespace, '\\', '/');
            $root = Text::replace("{$this->directory}/{$namespace}/{$layer}", '//', '/');

            $success = true;
            if (!Directory::exists($root)) {
                $success = Directory::make($root);
            }
            if (!$success) {
                return false;
            }
            $class = $this->class . (($key !== 'model') ? $layer : '');

            $filename = "{$root}/{$class}.php";

            return !!File::write($filename, $file);
        }
        return false;
    }


private function replace()
    {
        foreach ($this->stream as &$content) {
            foreach ($this->replacements as $field) {
                $content = Text::replace($content, $field['field'], $field['value']);
            }
        }
        return $this->stream;
    }

private function replace ( ) { foreach ( $ this -> stream as & $ content ) { foreach ( $ this -> replacements as $ field ) { $ content = Text :: replace ( $ content , $ field [ 'field' ] , $ field [ 'value' ] ) ; } } return $ this -> stream ; }

Replace values on stream template
@return array


public function addRoute(Route $route): void
    {
        // Verify the dispatch
        $this->app->dispatcher()->verifyDispatch($route);

        // Set the path to the validated cleaned path (/some/path)
        $route->setPath($this->validatePath($route->getPath()));
        // Ensure the request methods are set
        $route->getRequestMethods();

        // If this is a dynamic route
        if ($route->isDynamic()) {
            // Set the dynamic route's properties through the path parser
            $this->setDynamicRoute($route);
        }

        // Set the route in the collection
        self::$collection->addRoute($route);
    }

Set a single route.

@param Route $route The route

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

@return void


public function get(Route $route): void
    {
        $route->setRequestMethods([RequestMethod::GET, RequestMethod::HEAD]);

        $this->addRoute($route);
    }

public function get ( Route $ route ) : void { $ route -> setRequestMethods ( [ RequestMethod :: GET , RequestMethod :: HEAD ] ) ; $ this -> addRoute ( $ route ) ; }

Helper function to set a GET addRoute.

@param Route $route The route

@throws \Exception

@return void


public function post(Route $route): void
    {
        $route->setRequestMethods([RequestMethod::POST]);

        $this->addRoute($route);
    }

public function post ( Route $ route ) : void { $ route -> setRequestMethods ( [ RequestMethod :: POST ] ) ; $ this -> addRoute ( $ route ) ; }

Helper function to set a POST addRoute.

@param Route $route The route

@throws \Exception

@return void

Helper function to set a POST addRoute .


public function put(Route $route): void
    {
        $route->setRequestMethods([RequestMethod::PUT]);

        $this->addRoute($route);
    }

public function put ( Route $ route ) : void { $ route -> setRequestMethods ( [ RequestMethod :: PUT ] ) ; $ this -> addRoute ( $ route ) ; }

Helper function to set a PUT addRoute.

@param Route $route The route

@throws \Exception

@return void


public function patch(Route $route): void
    {
        $route->setRequestMethods([RequestMethod::PATCH]);

        $this->addRoute($route);
    }

public function patch ( Route $ route ) : void { $ route -> setRequestMethods ( [ RequestMethod :: PATCH ] ) ; $ this -> addRoute ( $ route ) ; }

Helper function to set a PATCH addRoute.

@param Route $route The route

@throws \Exception

@return void

Helper function to set a PATCH addRoute .


public function delete(Route $route): void
    {
        $route->setRequestMethods([RequestMethod::DELETE]);

        $this->addRoute($route);
    }

public function delete ( Route $ route ) : void { $ route -> setRequestMethods ( [ RequestMethod :: DELETE ] ) ; $ this -> addRoute ( $ route ) ; }

Helper function to set a DELETE addRoute.

@param Route $route The route

@throws \Exception

@return void

Helper function to set a DELETE addRoute .


public function head(Route $route): void
    {
        $route->setRequestMethods([RequestMethod::HEAD]);

        $this->addRoute($route);
    }

public function head ( Route $ route ) : void { $ route -> setRequestMethods ( [ RequestMethod :: HEAD ] ) ; $ this -> addRoute ( $ route ) ; }

Helper function to set a HEAD addRoute.

@param Route $route The route

@throws \Exception

@return void

Helper function to set a HEAD addRoute .


public function route(string $name): Route
    {
        // If no route was found
        if (! $this->routeIsset($name)) {
            throw new InvalidRouteName($name);
        }

        return self::$collection->namedRoute($name);
    }

public
function
route
(
string
$
name
)
:
Route
{
// If no route was found
if
(
!
$
this
->
routeIsset
(
$
name
)
)
{
throw
new
InvalidRouteName
(
$
name
)
;
}
return
self
::
$
collection
->
namedRoute
(
$
name
)
;
}

Get a route by name.

@param string $name The name of the route to get

@throws \Valkyrja\Routing\Exceptions\InvalidRouteName

@return \Valkyrja\Routing\Route


public function routeUrl(string $name, array $data = null, bool $absolute = null): string
    {
        // Get the matching route
        $route = $this->route($name);
        // Set the host to use if this is an absolute url
        // or the config is set to always use absolute urls
        // or the route is secure (needs https:// appended)
        $host = $absolute
        || $this->app->config()['routing']['useAbsoluteUrls']
        || $route->isSecure()
            ? $this->routeHost($route)
            : '';
        // Get the path from the generator
        $path = $route->getSegments()
            ? $this->app->pathGenerator()->parse(
                $route->getSegments(),
                $data,
                $route->getParams()
            )
            : $route->getPath();

        return $host . $this->validateRouteUrl($path);
    }

Get a route url by name.

@param string $name     The name of the route to get
@param array  $data     [optional] The route data if dynamic
@param bool   $absolute [optional] Whether this url should be absolute

@throws \Valkyrja\Routing\Exceptions\InvalidRouteName

@return string


public function requestRoute(Request $request): ? Route
    {
        $requestMethod = $request->getMethod();
        // Decode the request uri
        $requestUri = rawurldecode($request->getPathOnly());

        return $this->matchRoute($requestUri, $requestMethod);
    }

public
function
requestRoute
(
Request
$
request
)
:
Route
{
$
requestMethod
=
$
request
->
getMethod
(
)
;
// Decode the request uri
$
requestUri
=
rawurldecode
(
$
request
->
getPathOnly
(
)
)
;
return
$
this
->
matchRoute
(
$
requestUri
,
$
requestMethod
)
;
}

Get a route from a request.

@param Request $request The request

@throws \InvalidArgumentException

@return null|Route
The route if found or null when no static route is
found for the path and method combination specified


public function matchRoute(string $path, string $method = null): ? Route
    {
        // Validate the path
        $path   = $this->validatePath($path);
        $method = $method ?? RequestMethod::GET;

        if (null !== $route = $this->matchStaticRoute($path, $method)) {
            return $route;
        }

        return $this->matchDynamicRoute($path, $method);
    }

public
function
matchRoute
(
string
$
path
,
string
$
method
=
)
:
Route
{
// Validate the path
$
path
=
$
this
->
validatePath
(
$
path
)
;
$
method
=
$
method
??
RequestMethod
::
GET
;
if
(
!==
$
route
=
$
this
->
matchStaticRoute
(
$
path
,
$
method
)
)
{
return
$
route
;
}
return
$
this
->
matchDynamicRoute
(
$
path
,
$
method
)
;
}

Get a route by path.

@param string $path   The path
@param string $method [optional] The method type of get

@throws \InvalidArgumentException

@return null|Route
The route if found or null when no static route is
found for the path and method combination specified


public function isInternalUri(string $uri): bool
    {
        // Replace the scheme if it exists
        $uri = str_replace(['http://', 'https://'], '', $uri);

        // Get the host of the uri
        $host = (string) substr($uri, 0, strpos($uri, '/'));

        // If the host does not match the current request uri's host
        if ($host && $host !== $this->app->request()->getHttpHost()) {
            // Return false immediately
            return false;
        }

        // Get only the path (full string from the first slash to the end
        // of the path)
        $uri = (string) substr($uri, strpos($uri, '/'), \count($uri));

        // Try to match the route
        $route = $this->matchRoute($uri);

        return $route instanceof Route;
    }

Determine if a uri is valid.

@param string $uri The uri to check

@throws \InvalidArgumentException

@return bool


public function dispatch(Request $request): Response
    {
        // Check the returned route
        if (null === $route = $this->requestRoute($request)) {
            // If it was null throw a not found exception
            throw new NotFoundHttpException();
        }

        // If the route is secure and the current request is not secure
        if ($route->isSecure() && ! $request->isSecure()) {
            // Throw the redirect to the secure path
            return $this->app->redirect()->secure($request->getPath());
        }

        // Dispatch the route's before request handled middleware
        $middlewareReturn = $this->routeRequestMiddleware($request, $route);

        // If the middleware returned a response
        if ($middlewareReturn instanceof Response) {
            // Return the response
            return $middlewareReturn;
        }

        // Trigger an event for route matched
        $this->app->events()->trigger(RouteMatched::class, [$route, $request]);
        // Set the found route in the service container
        $this->app->container()->singleton(Route::class, $route);

        // Attempt to dispatch the route using any one of the callable options
        $dispatch = $this->app->dispatcher()->dispatchCallable(
            $route,
            $route->getMatches()
        );

        // Get the response from the dispatch
        $response = $this->getResponseFromDispatch($dispatch);

        // Dispatch the route's before request handled middleware and return
        // the response
        $this->routeResponseMiddleware($request, $response, $route);

        return $response;
    }

Dispatch the route and find a match.

@param Request $request The request

@throws \InvalidArgumentException
@throws \Valkyrja\Http\Exceptions\NotFoundHttpException

@return \Valkyrja\Http\Response


public function setup(bool $force = false, bool $useCache = true): void
    {
        // If route's have already been setup, no need to do it again
        if (self::$setup && ! $force) {
            return;
        }

        self::$setup = true;

        // If the application should use the routes cache file
        if ($useCache && $this->app->config()['routing']['useCache']) {
            $this->setupFromCache();

            // Then return out of setup
            return;
        }

        self::$collection = new RouteCollection();

        // If annotations are enabled and routing should use annotations
        if (
            $this->app->config()['routing']['useAnnotations']
            && $this->app->config()['annotations']['enabled']
        ) {
            // Setup annotated routes
            $this->setupAnnotatedRoutes();

            // If only annotations should be used for routing
            if ($this->app->config()['routing']['useAnnotationsExclusively']) {
                // Return to avoid loading routes file
                return;
            }
        }

        // Include the routes file
        // NOTE: Included if annotations are set or not due to possibility of
        // routes being defined within the controllers as well as within the
        // routes file
        require $this->app->config()['routing']['filePath'];
    }

Setup routes.

@param bool $force    [optional] Whether to force setup
@param bool $useCache [optional] Whether to use cache

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

@return void


protected function setDynamicRoute(Route $route): void
    {
        // Parse the path
        $parsedRoute = $this->app->pathParser()->parse($route->getPath());

        // Set the properties
        $route->setRegex($parsedRoute['regex']);
        $route->setParams($parsedRoute['params']);
        $route->setSegments($parsedRoute['segments']);
    }

protected
function
setDynamicRoute
(
Route
$
route
)
:
void
{
// Parse the path
$
parsedRoute
=
$
this
->
app
->
pathParser
(
)
->
parse
(
$
route
->
getPath
(
)
)
;
// Set the properties
$
route
->
setRegex
(
$
parsedRoute
[
'regex'
]
)
;
$
route
->
setParams
(
$
parsedRoute
[
'params'
]
)
;
$
route
->
setSegments
(
$
parsedRoute
[
'segments'
]
)
;
}

Set a dynamic route's properties.

@param Route $route The route

@return void


protected function validateRouteUrl(string $path): string
    {
        // If the last character is not a slash and the config is set to
        // ensure trailing slash
        if (
            $path[-1] !== '/'
            && $this->app->config()['routing']['trailingSlash']
        ) {
            // add a trailing slash
            $path .= '/';
        }

        return $path;
    }

Validate the route url.

@param string $path The path

@return string


protected function matchStaticRoute(string $path, string $method): ? Route
    {
        $route = null;

        // Let's check if the route is set in the static routes
        if (self::$collection->issetStaticRoute($method, $path)) {
            $route = $this->getMatchedStaticRoute($path, $method);
        }

        if (null !== $route && $this->isValidMethod($route, $method)) {
            return $route;
        }

        return null;
    }

Try to match a static route by path and method.

@param string $path   The path
@param string $method The method

@return null|Route
The route if found or null when no static route is
found for the path and method combination specified

Try to match a static route by path and method .


protected function matchDynamicRoute(string $path, string $method): ? Route
    {
        // The route to return (null by default)
        $route = null;
        // The dynamic routes
        $dynamicRoutes = self::$collection->getDynamicRoutes($method);

        // Attempt to find a match using dynamic routes that are set
        foreach ($dynamicRoutes as $regex => $dynamicRoute) {
            // If the preg match is successful, we've found our route!
            /* @var array $matches */
            if (preg_match($regex, $path, $matches)) {
                $route = $this->getMatchedDynamicRoute($dynamicRoute, $matches, $method);

                break;
            }
        }

        // If the route was found and the method is valid
        if (null !== $route && $this->isValidMethod($route, $method)) {
            // Return the route
            return $route;
        }

        return null;
    }

Try to match a dynamic route by path and method.

@param string $path   The path
@param string $method The method

@return null|Route
The route if found or null when no static route is
found for the path and method combination specified

Try to match a dynamic route by path and method .


protected function getMatchedStaticRoute(string $path, string $method): Route
    {
        return clone self::$collection->staticRoute($method, $path);
    }

protected function getMatchedStaticRoute ( string $ path , string $ method ) : Route { return clone self :: $ collection -> staticRoute ( $ method , $ path ) ; }

Get a matched static route.

@param string $path   The path
@param string $method The method

@return \Valkyrja\Routing\Route


protected function getMatchedDynamicRoute(string $path, array $matches, string $method): Route
    {
        // Clone the route to avoid changing the one set in the master array
        $dynamicRoute = clone self::$collection->dynamicRoute($method, $path);
        // The first match is the path itself
        unset($matches[0]);

        // Iterate through the matches
        foreach ($matches as $key => $match) {
            // If there is no match (middle of regex optional group)
            if (! $match) {
                // Set the value to null so the controller's action
                // can use the default it sets
                $matches[$key] = null;
            }
        }

        // Set the matches
        $dynamicRoute->setMatches($matches);

        return $dynamicRoute;
    }

Get a matched dynamic route.

@param string $path    The path
@param array  $matches The regex matches
@param string $method  The request method

@return \Valkyrja\Routing\Route


protected function routeRequestMiddleware(Request $request, Route $route)
    {
        // If the route has no middleware
        if (null === $route->getMiddleware()) {
            // Return the request passed through
            return $request;
        }

        return $this->app->kernel()->requestMiddleware(
            $request,
            $route->getMiddleware()
        );
    }

protected
function
routeRequestMiddleware
(
Request
$
request
,
Route
$
route
)
{
// If the route has no middleware
if
(
===
$
route
->
getMiddleware
(
)
)
{
// Return the request passed through
return
$
request
;
}
return
$
this
->
app
->
kernel
(
)
->
requestMiddleware
(
$
request
,
$
route
->
getMiddleware
(
)
)
;
}

Dispatch a route's before request handled middleware.

@param Request $request The request
@param Route   $route   The route

@return mixed

Dispatch a route s before request handled middleware .


protected function routeResponseMiddleware(Request $request, Response $response, Route $route): void
    {
        // If the route has no middleware
        if (null === $route->getMiddleware()) {
            // Return the response passed through
            return;
        }

        $this->app->kernel()->responseMiddleware(
            $request,
            $response,
            $route->getMiddleware()
        );
    }

protected
function
routeResponseMiddleware
(
Request
$
request
,
Response
$
response
,
Route
$
route
)
:
void
{
// If the route has no middleware
if
(
===
$
route
->
getMiddleware
(
)
)
{
// Return the response passed through
return
;
}
$
this
->
app
->
kernel
(
)
->
responseMiddleware
(
$
request
,
$
response
,
$
route
->
getMiddleware
(
)
)
;
}

Dispatch a route's after request handled middleware.

@param Request  $request  The request
@param Response $response The response
@param Route    $route    The route

@return void

Dispatch a route s after request handled middleware .


protected function getResponseFromDispatch($dispatch): Response
    {
        // If the dispatch failed, 404
        if (! $dispatch) {
            $this->app->abort();
        }

        // If the dispatch is a Response then simply return it
        if ($dispatch instanceof Response) {
            return $dispatch;
        }

        // If the dispatch is a View, render it then wrap it in a new response
        // and return it
        if ($dispatch instanceof View) {
            return $this->app->response($dispatch->render());
        }

        // Otherwise its a string so wrap it in a new response and return it
        return $this->app->response((string) $dispatch);
    }

Get a response from a dispatch.

@param mixed $dispatch The dispatch

@return \Valkyrja\Http\Response


protected function setupFromCache(): void
    {
        // Set the application routes with said file
        $cache = $this->app->config()['cache']['routing']
            ?? require $this->app->config()['routing']['cacheFilePath'];

        self::$collection = unserialize(
            base64_decode($cache['collection'], true),
            [
                'allowed_classes' => [
                    RouteCollection::class,
                    Route::class,
                ],
            ]
        );
    }

Setup the router from cache.

@return void


protected function setupAnnotatedRoutes(): void
    {
        /** @var RouteAnnotations $routeAnnotations */
        $routeAnnotations = $this->app->container()->getSingleton(
            RouteAnnotations::class
        );

        // Get all the annotated routes from the list of controllers
        $routes = $routeAnnotations->getRoutes(
            ...$this->app->config()['routing']['controllers']
        );

        // Iterate through the routes
        foreach ($routes as $route) {
            // Set the route
            $this->addRoute($route);
        }
    }

Setup annotated routes.

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

@return void


protected function renderHeader()
    {
        $button = $this->renderCloseButton();
        if ($button !== null) {
            $this->header = $this->header . "\n" . $button;
        }
        if ($this->header !== null) {
            Html::addCssClass($this->headerOptions, ['widget' => 'modal-header']);
            return $this->htmlHlp->tag('div', "\n" . $this->header . "\n", $this->headerOptions);
        } else {
            return null;
        }
    }

protected function renderHeader ( ) { $ button = $ this -> renderCloseButton ( ) ; if ( $ button !== null ) { $ this -> header = $ this -> header . "\n" . $ button ; } if ( $ this -> header !== null ) { Html :: addCssClass ( $ this -> headerOptions , [ 'widget' => 'modal-header' ] ) ; return $ this -> htmlHlp -> tag ( 'div' , "\n" . $ this -> header . "\n" , $ this -> headerOptions ) ; } else { return null ; } }

Renders the header HTML markup of the modal
@return string the rendering result


protected function renderToggleButton()
    {
        if (($toggleButton = $this->toggleButton) !== false) {
            $tag = ArrayHelper::remove($toggleButton, 'tag', 'button');
            $label = ArrayHelper::remove($toggleButton, 'label', 'Show');
            if ($tag === 'button' && !isset($toggleButton['type'])) {
                $toggleButton['type'] = 'button';
            }

            return $this->htmlHlp->tag($tag, $label, $toggleButton);
        } else {
            return null;
        }
    }

protected function renderToggleButton ( ) { if ( ( $ toggleButton = $ this -> toggleButton ) !== false ) { $ tag = ArrayHelper :: remove ( $ toggleButton , 'tag' , 'button' ) ; $ label = ArrayHelper :: remove ( $ toggleButton , 'label' , 'Show' ) ; if ( $ tag === 'button' && ! isset ( $ toggleButton [ 'type' ] ) ) { $ toggleButton [ 'type' ] = 'button' ; } return $ this -> htmlHlp -> tag ( $ tag , $ label , $ toggleButton ) ; } else { return null ; } }

Renders the toggle button.
@return string the rendering result


protected function getGettextFile($messageFile)
    {
        if (isset($this->_gettextFiles[$messageFile])) {
            return $this->_gettextFiles[$messageFile];
        }
        if (!is_file($messageFile)) {
            return null;
        }
        if ($this->useMoFile) {
            $gettextFile = new GettextMoFile(['filePath' => $messageFile, 'useBigEndian' => $this->useBigEndian]);
        } else {
            $gettextFile = new GettextPoFile(['filePath' => $messageFile]);
        }
        return $this->_gettextFiles[$messageFile] = $gettextFile;
    }

protected function getGettextFile ( $ messageFile ) { if ( isset ( $ this -> _gettextFiles [ $ messageFile ] ) ) { return $ this -> _gettextFiles [ $ messageFile ] ; } if ( ! is_file ( $ messageFile ) ) { return null ; } if ( $ this -> useMoFile ) { $ gettextFile = new GettextMoFile ( [ 'filePath' => $ messageFile , 'useBigEndian' => $ this -> useBigEndian ] ) ; } else { $ gettextFile = new GettextPoFile ( [ 'filePath' => $ messageFile ] ) ; } return $ this -> _gettextFiles [ $ messageFile ] = $ gettextFile ; }

Get gettext file class
@param string $messageFile
@return GettextFile|null


protected function getQBResult(Params $params, Query $query)
    {
        $paginated = new Paginator($query);
        $paginated->setUseOutputWalkers(false);
        $this->setTotal($paginated->count());

        return $paginated;
    }

protected function getQBResult ( Params $ params , Query $ query ) { $ paginated = new Paginator ( $ query ) ; $ paginated -> setUseOutputWalkers ( false ) ; $ this -> setTotal ( $ paginated -> count ( ) ) ; return $ paginated ; }

Returns an array or other iterable object containing results
@param  Param           $params
@param  Query           $query
@return Paginator|array


protected function addFilters(Params $params, QueryBuilder $qb)
    {
        $this->filterByIdentifier($params, $qb)
            ->filterBySearch($params, $qb);

        return $this;
    }

protected function addFilters ( Params $ params , QueryBuilder $ qb ) { $ this -> filterByIdentifier ( $ params , $ qb ) -> filterBySearch ( $ params , $ qb ) ; return $ this ; }

Add where clauses to the query
@param  Param        $params
@param  QueryBuilder $qb
@return $this


protected function filterBySearch(Params $params, QueryBuilder $qb)
    {
        if ($query = $params->getWrapped('search')->get('value')) {
            $this->searchFilter($params, $qb, $query);
        }

        return $this;
    }

protected function filterBySearch ( Params $ params , QueryBuilder $ qb ) { if ( $ query = $ params -> getWrapped ( 'search' ) -> get ( 'value' ) ) { $ this -> searchFilter ( $ params , $ qb , $ query ) ; } return $ this ; }

Default search hook for datatables

@param Params       $params
@param QueryBuilder $qb

@return $this


protected function searchFilter(Params $params, QueryBuilder $qb, $search)
    {
        $qb->andWhere($this->alias('id').' LIKE :search')->setParameter('search', $search);

        return $this;
    }

protected
function
searchFilter
(
Params
$
params
,
QueryBuilder
$
qb
,
$
search
)
{
$
qb
->
andWhere
(
$
this
->
alias
(
'id'
)
.
' LIKE :search'
)
->
setParameter
(
'search'
,
$
search
)
;
return
$
this
;
}

This function is passed the datatables search query value
and should appropriately filter the query builder object
based on what makes sense for this entity.

@param Params       $params
@param QueryBuilder $qb
@param $search

@return $this

This function is passed the datatables search query value and should appropriately filter the query builder object based on what makes sense for this entity .


protected function addOrdering(Params $params, QueryBuilder $qb)
    {
        $orderDir = "ASC";
        if ($params->has('orderDir') && (strtoupper($params->get('orderDir')) == "DESC")) {
            $orderDir = "DESC";
        }
        if ($params->has('orderBy') && $params->get('orderBy') != "") {
            $qb->orderBy($this->alias($params->get('orderBy')), $orderDir);
        }

        return $this;
    }

protected function addOrdering ( Params $ params , QueryBuilder $ qb ) { $ orderDir = "ASC" ; if ( $ params -> has ( 'orderDir' ) && ( strtoupper ( $ params -> get ( 'orderDir' ) ) == "DESC" ) ) { $ orderDir = "DESC" ; } if ( $ params -> has ( 'orderBy' ) && $ params -> get ( 'orderBy' ) != "" ) { $ qb -> orderBy ( $ this -> alias ( $ params -> get ( 'orderBy' ) ) , $ orderDir ) ; } return $ this ; }

If there is some ordering that needs to be applied, do it here
@param  Param        $params
@param  QueryBuilder $qb
@return $this

If there is some ordering that needs to be applied do it here


protected function addOffset(Params $params, QueryBuilder $qb)
    {
        if ($this->getOffset() && $this->getOffset() > 0) {
            $qb->setFirstResult($this->getOffset());
        }

        return $this;
    }

protected function addOffset ( Params $ params , QueryBuilder $ qb ) { if ( $ this -> getOffset ( ) && $ this -> getOffset ( ) > 0 ) { $ qb -> setFirstResult ( $ this -> getOffset ( ) ) ; } return $ this ; }

Set the offset for the query results
@param  Param        $params
@param  QueryBuilder $qb
@return $this


protected function addLimit(Params $params, QueryBuilder $qb)
    {
        if ($this->getLimit() && $this->getLimit() > 0) {
            $qb->setMaxResults($this->getLimit());
        }

        return $this;
    }

protected function addLimit ( Params $ params , QueryBuilder $ qb ) { if ( $ this -> getLimit ( ) && $ this -> getLimit ( ) > 0 ) { $ qb -> setMaxResults ( $ this -> getLimit ( ) ) ; } return $ this ; }

Set the limit for the query results
@param  Param        $params
@param  QueryBuilder $qb
@return $this


public function find($id)
    {
        $params = Params::create(array($this->getIdParam() => $id, 'limit' => 1));
        $qb = $this->getCustomizedQueryBuilder($params);
        $results = $this->getQBResult($params, $this->queryHook($params, $qb));
        if ($results->count() != 1) {
            throw new NotFound("Unable to locate entity ".$this->getRepository()." with id ".$id);
        }
        /* @var $results \Doctrine\ORM\Tools\Pagination\Paginator */
        /**
         * Note: this is a paginator object so the only way to access result elements is by iterating
         */
        foreach ($results as $result) {
            // return the first (and only) result
            return $result;
        }
    }

Finds an element in this domain which has the specified ID

@param $id
@throws NotFound
@return \FzyCommon\Entity\BaseInterface


public function safeJoin(QueryBuilder $qb, $property, $joinedAlias, $autoAlias = true)
    {
        if ($autoAlias) {
            $property = $this->alias($property);
        }
        if (!isset($this->joinMap[$property])) {
            $qb->join($property, $joinedAlias);
            $this->joinMap[$property] = $joinedAlias;
        }

        return $this;
    }

public function safeJoin ( QueryBuilder $ qb , $ property , $ joinedAlias , $ autoAlias = true ) { if ( $ autoAlias ) { $ property = $ this -> alias ( $ property ) ; } if ( ! isset ( $ this -> joinMap [ $ property ] ) ) { $ qb -> join ( $ property , $ joinedAlias ) ; $ this -> joinMap [ $ property ] = $ joinedAlias ; } return $ this ; }

Allows you to track which tables you have already joined on this query

@param QueryBuilder $qb
@param $property
@param $joinedAlias
@param bool         $autoAlias

@return $this


protected function getDataTablesSortColumn(Params $params)
    {
        $column = $params->getWrapped('order')->getWrapped(0)->get('column', 0);

        return $params->getWrapped('columns')->getWrapped($column)->get('data');
    }

protected function getDataTablesSortColumn ( Params $ params ) { $ column = $ params -> getWrapped ( 'order' ) -> getWrapped ( 0 ) -> get ( 'column' , 0 ) ; return $ params -> getWrapped ( 'columns' ) -> getWrapped ( $ column ) -> get ( 'data' ) ; }

Returns the column name selected for the sort
@param  Params     $params
@return array|null


protected function orderByDataTablesParams(Params $params, QueryBuilder $qb)
    {
        $order = $this->getDataTablesSortOrder($params);
        $sort = $this->getDataTablesSortColumn($params);
        if ($sort) {
            $qb->addOrderBy($this->alias($sort), $order);
        }

        return $this;
    }

protected function orderByDataTablesParams ( Params $ params , QueryBuilder $ qb ) { $ order = $ this -> getDataTablesSortOrder ( $ params ) ; $ sort = $ this -> getDataTablesSortColumn ( $ params ) ; if ( $ sort ) { $ qb -> addOrderBy ( $ this -> alias ( $ sort ) , $ order ) ; } return $ this ; }

Uses datatables request paramters to determine the column name to order by
@param  Params       $params
@param  QueryBuilder $qb
@return $this


public function isValid($value, Constraint $constraint)
	{
		if (empty($value)) {
			return true;
		}

		$ret = $this->validateNumber($value, $constraint->format);

		if (!$ret) {
			$this->setMessage($constraint->message);
		}

		return $ret;
	}

public function isValid ( $ value , Constraint $ constraint ) { if ( empty ( $ value ) ) { return true ; } $ ret = $ this -> validateNumber ( $ value , $ constraint -> format ) ; if ( ! $ ret ) { $ this -> setMessage ( $ constraint -> message ) ; } return $ ret ; }

Check if a Phonenumber is valid

@param string $value
@param Constraint $constraint

@return bool


function replaceEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML,
        $encoding = 'ISO-8859-1')
    {
        switch ($replaceEntities) {
        case XML_UTIL_ENTITIES_XML:
            return strtr($string, array(
                '&'  => '&',
                '>'  => '>',
                '<'  => '<',
                '"'  => '"',
                '\'' => ''' ));
            break;
        case XML_UTIL_ENTITIES_XML_REQUIRED:
            return strtr($string, array(
                '&' => '&',
                '<' => '<',
                '"' => '"' ));
            break;
        case XML_UTIL_ENTITIES_HTML:
            return htmlentities($string, ENT_COMPAT, $encoding);
            break;
        }
        return $string;
    }

function replaceEntities ( $ string , $ replaceEntities = XML_UTIL_ENTITIES_XML , $ encoding = 'ISO-8859-1' ) { switch ( $ replaceEntities ) { case XML_UTIL_ENTITIES_XML : return strtr ( $ string , array ( '&' => '&' , '>' => '>' , '<' => '<' , '"' => '"' , '\'' => ''' ) ) ; break ; case XML_UTIL_ENTITIES_XML_REQUIRED : return strtr ( $ string , array ( '&' => '&' , '<' => '<' , '"' => '"' ) ) ; break ; case XML_UTIL_ENTITIES_HTML : return htmlentities ( $ string , ENT_COMPAT , $ encoding ) ; break ; } return $ string ; }

replace XML entities

With the optional second parameter, you may select, which
entities should be replaced.

require_once 'XML/Util.php';

// replace XML entites:
$string = XML_Util::replaceEntities('This string contains < & >.');

With the optional third parameter, you may pass the character encoding

require_once 'XML/Util.php';

// replace XML entites in UTF-8:
$string = XML_Util::replaceEntities(
'This string contains < & > as well as ä, ö, ß, à and ê',
XML_UTIL_ENTITIES_HTML,
'UTF-8'
);

@param string $string          string where XML special chars
should be replaced
@param int    $replaceEntities setting for entities in attribute values
(one of XML_UTIL_ENTITIES_XML,
XML_UTIL_ENTITIES_XML_REQUIRED,
XML_UTIL_ENTITIES_HTML)
@param string $encoding        encoding value (if any)...
must be a valid encoding as determined
by the htmlentities() function

@return string string with replaced chars
@access public
@static
@see reverseEntities()


function reverseEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML,
        $encoding = 'ISO-8859-1')
    {
        switch ($replaceEntities) {
        case XML_UTIL_ENTITIES_XML:
            return strtr($string, array(
                '&'  => '&',
                '>'   => '>',
                '<'   => '<',
                '"' => '"',
                ''' => '\'' ));
            break;
        case XML_UTIL_ENTITIES_XML_REQUIRED:
            return strtr($string, array(
                '&'  => '&',
                '<'   => '<',
                '"' => '"' ));
            break;
        case XML_UTIL_ENTITIES_HTML:
            return html_entity_decode($string, ENT_COMPAT, $encoding);
            break;
        }
        return $string;
    }

function reverseEntities ( $ string , $ replaceEntities = XML_UTIL_ENTITIES_XML , $ encoding = 'ISO-8859-1' ) { switch ( $ replaceEntities ) { case XML_UTIL_ENTITIES_XML : return strtr ( $ string , array ( '&' => '&' , '>' => '>' , '<' => '<' , '"' => '"' , ''' => '\'' ) ) ; break ; case XML_UTIL_ENTITIES_XML_REQUIRED : return strtr ( $ string , array ( '&' => '&' , '<' => '<' , '"' => '"' ) ) ; break ; case XML_UTIL_ENTITIES_HTML : return html_entity_decode ( $ string , ENT_COMPAT , $ encoding ) ; break ; } return $ string ; }

reverse XML entities

With the optional second parameter, you may select, which
entities should be reversed.

require_once 'XML/Util.php';

// reverse XML entites:
$string = XML_Util::reverseEntities('This string contains < & >.');

With the optional third parameter, you may pass the character encoding

require_once 'XML/Util.php';

// reverse XML entites in UTF-8:
$string = XML_Util::reverseEntities(
'This string contains < & > as well as'
. ' ä, ö, ß, à and ê',
XML_UTIL_ENTITIES_HTML,
'UTF-8'
);

@param string $string          string where XML special chars
should be replaced
@param int    $replaceEntities setting for entities in attribute values
(one of XML_UTIL_ENTITIES_XML,
XML_UTIL_ENTITIES_XML_REQUIRED,
XML_UTIL_ENTITIES_HTML)
@param string $encoding        encoding value (if any)...
must be a valid encoding as determined
by the html_entity_decode() function

@return string string with replaced chars
@access public
@static
@see replaceEntities()


function getXMLDeclaration($version = '1.0', $encoding = null,
        $standalone = null)
    {
        $attributes = array(
            'version' => $version,
        );
        // add encoding
        if ($encoding !== null) {
            $attributes['encoding'] = $encoding;
        }
        // add standalone, if specified
        if ($standalone !== null) {
            $attributes['standalone'] = $standalone ? 'yes' : 'no';
        }

        return sprintf('<?xml%s?>',
            XML_Util::attributesToString($attributes, false));
    }

function
getXMLDeclaration
(
$
version
=
'1.0'
,
$
encoding
=
,
$
standalone
=
)
{
$
attributes
=
array
(
'version'
=>
$
version
,
)
;
// add encoding
if
(
$
encoding
!==
)
{
$
attributes
[
'encoding'
]
=
$
encoding
;
}
// add standalone, if specified
if
(
$
standalone
!==
)
{
$
attributes
[
'standalone'
]
=
$
standalone
'yes'
:
'no'
;
}
return
sprintf
(
'<?xml%s?>'
,
XML_Util
::
attributesToString
(
$
attributes
,
false
)
)
;
}

build an xml declaration

<code>
require_once 'XML/Util.php';

// get an XML declaration:
$xmlDecl = XML_Util::getXMLDeclaration('1.0', 'UTF-8', true);
</code>

@param string $version    xml version
@param string $encoding   character encoding
@param bool   $standalone document is standalone (or not)

@return string xml declaration
@access public
@static
@uses attributesToString() to serialize the attributes of the XML declaration


function getDocTypeDeclaration($root, $uri = null, $internalDtd = null)
    {
        if (is_array($uri)) {
            $ref = sprintf(' PUBLIC "%s" "%s"', $uri['id'], $uri['uri']);
        } elseif (!empty($uri)) {
            $ref = sprintf(' SYSTEM "%s"', $uri);
        } else {
            $ref = '';
        }

        if (empty($internalDtd)) {
            return sprintf('<!DOCTYPE %s%s>', $root, $ref);
        } else {
            return sprintf("<!DOCTYPE %s%s [\n%s\n]>", $root, $ref, $internalDtd);
        }
    }

function
getDocTypeDeclaration
(
$
root
,
$
uri
=
,
$
internalDtd
=
)
{
if
(
is_array
(
$
uri
)
)
{
$
ref
=
sprintf
(
' PUBLIC "%s" "%s"'
,
$
uri
[
'id'
]
,
$
uri
[
'uri'
]
)
;
}
elseif
(
!
empty
(
$
uri
)
)
{
$
ref
=
sprintf
(
' SYSTEM "%s"'
,
$
uri
)
;
}
else
{
$
ref
=
''
;
}
if
(
empty
(
$
internalDtd
)
)
{
return
sprintf
(
'<!DOCTYPE %s%s>'
,
$
root
,
$
ref
)
;
}
else
{
return
sprintf
(
"<!DOCTYPE %s%s [\n%s\n]>"
,
$
root
,
$
ref
,
$
internalDtd
)
;
}
}

build a document type declaration

<code>
require_once 'XML/Util.php';

// get a doctype declaration:
$xmlDecl = XML_Util::getDocTypeDeclaration('rootTag','myDocType.dtd');
</code>

@param string $root        name of the root tag
@param string $uri         uri of the doctype definition
(or array with uri and public id)
@param string $internalDtd internal dtd entries

@return string doctype declaration
@access public
@static
@since 0.2


function attributesToString($attributes, $sort = true, $multiline = false,
        $indent = '    ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML)
    {
        /*
         * second parameter may be an array
         */
        if (is_array($sort)) {
            if (isset($sort['multiline'])) {
                $multiline = $sort['multiline'];
            }
            if (isset($sort['indent'])) {
                $indent = $sort['indent'];
            }
            if (isset($sort['linebreak'])) {
                $multiline = $sort['linebreak'];
            }
            if (isset($sort['entities'])) {
                $entities = $sort['entities'];
            }
            if (isset($sort['sort'])) {
                $sort = $sort['sort'];
            } else {
                $sort = true;
            }
        }
        $string = '';
        if (is_array($attributes) && !empty($attributes)) {
            if ($sort) {
                ksort($attributes);
            }
            if ( !$multiline || count($attributes) == 1) {
                foreach ($attributes as $key => $value) {
                    if ($entities != XML_UTIL_ENTITIES_NONE) {
                        if ($entities === XML_UTIL_CDATA_SECTION) {
                            $entities = XML_UTIL_ENTITIES_XML;
                        }
                        $value = XML_Util::replaceEntities($value, $entities);
                    }
                    $string .= ' ' . $key . '="' . $value . '"';
                }
            } else {
                $first = true;
                foreach ($attributes as $key => $value) {
                    if ($entities != XML_UTIL_ENTITIES_NONE) {
                        $value = XML_Util::replaceEntities($value, $entities);
                    }
                    if ($first) {
                        $string .= ' ' . $key . '="' . $value . '"';
                        $first   = false;
                    } else {
                        $string .= $linebreak . $indent . $key . '="' . $value . '"';
                    }
                }
            }
        }
        return $string;
    }

create string representation of an attribute list

<code>
require_once 'XML/Util.php';

// build an attribute string
$att = array(
'foo'   =>  'bar',
'argh'  =>  'tomato'
);

$attList = XML_Util::attributesToString($att);
</code>

@param array      $attributes attribute array
@param bool|array $sort       sort attribute list alphabetically,
may also be an assoc array containing
the keys 'sort', 'multiline', 'indent',
'linebreak' and 'entities'
@param bool       $multiline  use linebreaks, if more than
one attribute is given
@param string     $indent     string used for indentation of
multiline attributes
@param string     $linebreak  string used for linebreaks of
multiline attributes
@param int        $entities   setting for entities in attribute values
(one of XML_UTIL_ENTITIES_NONE,
XML_UTIL_ENTITIES_XML,
XML_UTIL_ENTITIES_XML_REQUIRED,
XML_UTIL_ENTITIES_HTML)

@return string string representation of the attributes
@access public
@static
@uses replaceEntities() to replace XML entities in attribute values
@todo allow sort also to be an options array


function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL)
    {
        if ($mode == XML_UTIL_COLLAPSE_XHTML_ONLY) {
            return preg_replace(
                '/<(area|base(?:font)?|br|col|frame|hr|img|input|isindex|link|meta|'
                . 'param)([^>]*)><\/\\1>/s',
                '<\\1\\2 />',
                $xml);
        } else {
            return preg_replace('/<(\w+)([^>]*)><\/\\1>/s', '<\\1\\2 />', $xml);
        }
    }

Collapses empty tags.

@param string $xml  XML
@param int    $mode Whether to collapse all empty tags (XML_UTIL_COLLAPSE_ALL)
or only XHTML (XML_UTIL_COLLAPSE_XHTML_ONLY) ones.

@return string XML
@access public
@static
@todo PEAR CS - unable to avoid "space after open parens" error
in the IF branch


function createTag($qname, $attributes = array(), $content = null,
        $namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
        $multiline = false, $indent = '_auto', $linebreak = "\n",
        $sortAttributes = true)
    {
        $tag = array(
            'qname'      => $qname,
            'attributes' => $attributes
        );

        // add tag content
        if ($content !== null) {
            $tag['content'] = $content;
        }

        // add namespace Uri
        if ($namespaceUri !== null) {
            $tag['namespaceUri'] = $namespaceUri;
        }

        return XML_Util::createTagFromArray($tag, $replaceEntities, $multiline,
            $indent, $linebreak, $sortAttributes);
    }

function
createTag
(
$
qname
,
$
attributes
=
array
(
)
,
$
content
=
,
$
namespaceUri
=
,
$
replaceEntities
=
XML_UTIL_REPLACE_ENTITIES
,
$
multiline
=
false
,
$
indent
=
'_auto'
,
$
linebreak
=
"\n"
,
$
sortAttributes
=
true
)
{
$
tag
=
array
(
'qname'
=>
$
qname
,
'attributes'
=>
$
attributes
)
;
// add tag content
if
(
$
content
!==
)
{
$
tag
[
'content'
]
=
$
content
;
}
// add namespace Uri
if
(
$
namespaceUri
!==
)
{
$
tag
[
'namespaceUri'
]
=
$
namespaceUri
;
}
return
XML_Util
::
createTagFromArray
(
$
tag
,
$
replaceEntities
,
$
multiline
,
$
indent
,
$
linebreak
,
$
sortAttributes
)
;
}

create a tag

This method will call XML_Util::createTagFromArray(), which
is more flexible.

<code>
require_once 'XML/Util.php';

// create an XML tag:
$tag = XML_Util::createTag('myNs:myTag',
array('foo' => 'bar'),
'This is inside the tag',
'http://www.w3c.org/myNs#');
</code>

@param string $qname           qualified tagname (including namespace)
@param array  $attributes      array containg attributes
@param mixed  $content         the content
@param string $namespaceUri    URI of the namespace
@param int    $replaceEntities whether to replace XML special chars in
content, embedd it in a CData section
or none of both
@param bool   $multiline       whether to create a multiline tag where
each attribute gets written to a single line
@param string $indent          string used to indent attributes
(_auto indents attributes so they start
at the same column)
@param string $linebreak       string used for linebreaks
@param bool   $sortAttributes  Whether to sort the attributes or not

@return string XML tag
@access public
@static
@see createTagFromArray()
@uses createTagFromArray() to create the tag


function createStartElement($qname, $attributes = array(), $namespaceUri = null,
        $multiline = false, $indent = '_auto', $linebreak = "\n",
        $sortAttributes = true)
    {
        // if no attributes hav been set, use empty attributes
        if (!isset($attributes) || !is_array($attributes)) {
            $attributes = array();
        }

        if ($namespaceUri != null) {
            $parts = XML_Util::splitQualifiedName($qname);
        }

        // check for multiline attributes
        if ($multiline === true) {
            if ($indent === '_auto') {
                $indent = str_repeat(' ', (strlen($qname)+2));
            }
        }

        if ($namespaceUri != null) {
            // is a namespace given
            if (isset($parts['namespace']) && !empty($parts['namespace'])) {
                $attributes['xmlns:' . $parts['namespace']] = $namespaceUri;
            } else {
                // define this Uri as the default namespace
                $attributes['xmlns'] = $namespaceUri;
            }
        }

        // create attribute list
        $attList = XML_Util::attributesToString($attributes, $sortAttributes,
            $multiline, $indent, $linebreak);
        $element = sprintf('<%s%s>', $qname, $attList);
        return  $element;
    }

create a start element

<code>
require_once 'XML/Util.php';

// create an XML start element:
$tag = XML_Util::createStartElement('myNs:myTag',
array('foo' => 'bar') ,'http://www.w3c.org/myNs#');
</code>

@param string $qname          qualified tagname (including namespace)
@param array  $attributes     array containg attributes
@param string $namespaceUri   URI of the namespace
@param bool   $multiline      whether to create a multiline tag where each
attribute gets written to a single line
@param string $indent         string used to indent attributes (_auto indents
attributes so they start at the same column)
@param string $linebreak      string used for linebreaks
@param bool   $sortAttributes Whether to sort the attributes or not

@return string XML start element
@access public
@static
@see createEndElement(), createTag()


function splitQualifiedName($qname, $defaultNs = null)
    {
        if (strstr($qname, ':')) {
            $tmp = explode(':', $qname);
            return array(
                'namespace' => $tmp[0],
                'localPart' => $tmp[1]
            );
        }
        return array(
            'namespace' => $defaultNs,
            'localPart' => $qname
        );
    }

function splitQualifiedName ( $ qname , $ defaultNs = null ) { if ( strstr ( $ qname , ':' ) ) { $ tmp = explode ( ':' , $ qname ) ; return array ( 'namespace' => $ tmp [ 0 ] , 'localPart' => $ tmp [ 1 ] ) ; } return array ( 'namespace' => $ defaultNs , 'localPart' => $ qname ) ; }

split qualified name and return namespace and local part

require_once 'XML/Util.php';

// split qualified tag
$parts = XML_Util::splitQualifiedName('xslt:stylesheet');

the returned array will contain two elements:

array(
'namespace' => 'xslt',
'localPart' => 'stylesheet'
);

@param string $qname     qualified tag name
@param string $defaultNs default namespace (optional)

@return array array containing namespace and local part
@access public
@static


function isValidName($string)
    {
        // check for invalid chars
        if (!preg_match('/^[[:alpha:]_]$/', $string{0})) {
            return XML_Util::raiseError('XML names may only start with letter '
                . 'or underscore', XML_UTIL_ERROR_INVALID_START);
        }

        // check for invalid chars
        if (!preg_match('/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?[[:alpha:]_]([[:alnum:]\_\-\.]+)?$/',
            $string)
        ) {
            return XML_Util::raiseError('XML names may only contain alphanumeric '
                . 'chars, period, hyphen, colon and underscores',
                XML_UTIL_ERROR_INVALID_CHARS);
        }
        // XML name is valid
        return true;
    }

check, whether string is valid XML name

XML names are used for tagname, attribute names and various
other, lesser known entities.

An XML name may only consist of alphanumeric characters,
dashes, undescores and periods, and has to start with a letter
or an underscore.

require_once 'XML/Util.php';

// verify tag name
$result = XML_Util::isValidName('invalidTag?');
if (is_a($result, 'PEAR_Error')) {
print 'Invalid XML name: ' . $result->getMessage();
}

@param string $string string that should be checked

@return mixed true, if string is a valid XML name, PEAR error otherwise
@access public
@static
@todo support for other charsets
@todo PEAR CS - unable to avoid 85-char limit on second preg_match


public static function dispatch(ICallable $object)
    {
        $params = $object->getParams();
        $call = $object->getCallable();

        if (!is_callable($call)) {
            throw new CallException("Non callable object found");
        }

        if ($call instanceof Closure) {
            return call_user_func_array($call, $params);
        }

        $class = explode('::', $call);

        $reflection = new ReflectionClass($class[0]);
        $method = $reflection->getMethod($class[1]);

        if ($method->isStatic()) {
            return call_user_func_array($call, $params);
        }

        return call_user_func_array(array(new $class[0], $class[1]), $params);
    }

public
static
function
dispatch
(
ICallable
$
object
)
{
$
params
=
$
object
->
getParams
(
)
;
$
call
=
$
object
->
getCallable
(
)
;
if
(
!
is_callable
(
$
call
)
)
{
throw
new
CallException
(
"Non callable object found"
)
;
}
if
(
$
call
instanceof
Closure
)
{
return
call_user_func_array
(
$
call
,
$
params
)
;
}
$
class
=
explode
(
'::'
,
$
call
)
;
$
reflection
=
new
ReflectionClass
(
$
class
[
0
]
)
;
$
method
=
$
reflection
->
getMethod
(
$
class
[
1
]
)
;
if
(
$
method
->
isStatic
(
)
)
{
return
call_user_func_array
(
$
call
,
$
params
)
;
}
return
call_user_func_array
(
array
(
new
$
class
[
0
]
,
$
class
[
1
]
)
,
$
params
)
;
}

Dispatch callable object

@param Txiki\Callback\ICallable $object

@return mixed


public function onTagResponse(HttpCacheEvent $event)
    {
        $tags = $event->getData();

        if (empty($tags)) {
            return;
        }

        $this->tagManager->addTags($tags);
    }

public function onTagResponse ( HttpCacheEvent $ event ) { $ tags = $ event -> getData ( ) ; if ( empty ( $ tags ) ) { return ; } $ this -> tagManager -> addTags ( $ tags ) ; }

Tag response event handler.

@param HttpCacheEvent $event


public function onInvalidateTag(HttpCacheEvent $event)
    {
        $tags = $event->getData();

        if (empty($tags)) {
            return;
        }

        $this->tagManager->invalidateTags($tags);
    }

public function onInvalidateTag ( HttpCacheEvent $ event ) { $ tags = $ event -> getData ( ) ; if ( empty ( $ tags ) ) { return ; } $ this -> tagManager -> invalidateTags ( $ tags ) ; }

Invalidate tags event handler.

@param HttpCacheEvent $event


protected function validate(LifecycleEventArgs $args) {
        $entity = $args->getEntity();
        $metadata = $args->getEntityManager()->getClassMetadata(get_class($entity));
        if($this->shouldBeValidated($entity)) {
            $rules = $entity->getValidationRules();
            $fields = $metadata->getFieldNames();
            $data = [];
            foreach($fields as $field) {
                $data[$field] = $metadata->getFieldValue($entity, $field);
            }

            $this->validator->with($data, $rules);
            if(!$this->validator->passes()) {
                throw new InvalidEntityException($entity, $this->validator->errors());
            }
        }
    }

protected function validate ( LifecycleEventArgs $ args ) { $ entity = $ args -> getEntity ( ) ; $ metadata = $ args -> getEntityManager ( ) -> getClassMetadata ( get_class ( $ entity ) ) ; if ( $ this -> shouldBeValidated ( $ entity ) ) { $ rules = $ entity -> getValidationRules ( ) ; $ fields = $ metadata -> getFieldNames ( ) ; $ data = [ ] ; foreach ( $ fields as $ field ) { $ data [ $ field ] = $ metadata -> getFieldValue ( $ entity , $ field ) ; } $ this -> validator -> with ( $ data , $ rules ) ; if ( ! $ this -> validator -> passes ( ) ) { throw new InvalidEntityException ( $ entity , $ this -> validator -> errors ( ) ) ; } } }

Performs validation before the entity is persisted.

@param LifecycleEventArgs $args
@throws InvalidEntityException if the entity is invalid
@return boolean

Performs validation before the entity is persisted .


protected function interpolateMessage($message, array $context)//@codingStandardsIgnoreLine Ignore missing type hint
    {
        $context = array_filter(
            $context,
            function ($value) {
                return (is_scalar($value) || (is_object($value) && method_exists($value, '__toString')));
            }
        );

        $search = [];
        $replace = [];
        foreach ($context as $key => $value) {
            $search[] = "{{$key}}";
            $replace[] = (string)$value;
        }

        return str_replace($search, $replace, $message);
    }

Interpolates context values into the message placeholders.

@link https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#12-message

@param string $message The string containing the placeholders.
@param array  $context The key/value array of replacement values.

@return string

Interpolates context values into the message placeholders .


public static function areSameSpace(PointInterface $point1, PointInterface $point2)
    {
        return (bool) (
            ($point1->is1D() && $point2->is1d()) ||
            ($point1->is2D() && $point2->is2d()) ||
            ($point1->is3D() && $point2->is3d())
        );
    }

public static function areSameSpace ( PointInterface $ point1 , PointInterface $ point2 ) { return ( bool ) ( ( $ point1 -> is1D ( ) && $ point2 -> is1d ( ) ) || ( $ point1 -> is2D ( ) && $ point2 -> is2d ( ) ) || ( $ point1 -> is3D ( ) && $ point2 -> is3d ( ) ) ) ; }

Test if two points are in the same space type

@param   \Maths\PointInterface $point1
@param   \Maths\PointInterface $point2
@return  bool


public static function areSamePoint(PointInterface $point1, PointInterface $point2)
    {
        if (self::areSameSpace($point1, $point2)) {
            if ($point1->is1D()) {
                return (bool) ($point1->getAbscissa()==$point2->getAbscissa());
            } elseif ($point1->is2D()) {
                return (bool) (
                    ($point1->getAbscissa()==$point2->getAbscissa()) &&
                    ($point1->getOrdinate()==$point2->getOrdinate())
                );
            } elseif ($point1->is3D()) {
                return (bool) (
                    ($point1->getAbscissa()==$point2->getAbscissa()) &&
                    ($point1->getOrdinate()==$point2->getOrdinate()) &&
                    ($point1->getApplicate()==$point2->getApplicate())
                );
            }
        } else {
            throw new \InvalidArgumentException(
                "Can not compare positions of two points of different space types"
            );
        }
    }

Test if two points are in the same position

@param   \Maths\PointInterface $point1
@param   \Maths\PointInterface $point2
@return  bool
@throws  \InvalidArgumentException if the two points are not in the same space type