september update 1

This commit is contained in:
Dennis Eichhorn 2021-09-19 19:50:15 +02:00
parent 420c34aec2
commit 99df0e971e
16 changed files with 331 additions and 218 deletions

View File

@ -206,6 +206,26 @@ class Account implements \JsonSerializable, ArrayableInterface
$this->groups[] = $group;
}
/**
* User has group.
*
* @param int $group Group id
*
* @return void
*
* @since 1.0.0
*/
public function hasGroup(int $id) : bool
{
foreach ($this->groups as $group) {
if ($group->getId() === $id) {
return true;
}
}
return false;
}
/**
* Get email.
*

View File

@ -222,4 +222,16 @@ final class ApplicationInfo
{
return $this->info['version'] ?? '';
}
/**
* Get info data.
*
* @return array<string, string>
*
* @since 1.0.0
*/
public function getProviding() : array
{
return $this->info['providing'] ?? [];
}
}

View File

@ -16,7 +16,6 @@ declare(strict_types=1);
namespace phpOMS\Application;
use phpOMS\Module\ModuleManager;
use phpOMS\System\File\Local\Directory;
use phpOMS\System\File\PathException;
@ -32,14 +31,6 @@ use phpOMS\System\File\PathException;
*/
final class ApplicationManager
{
/**
* Module manager
*
* @var ModuleManager
* @since 1.0.0
*/
private ModuleManager $moduleManager;
/**
* Applications
*
@ -51,13 +42,10 @@ final class ApplicationManager
/**
* Constructor.
*
* @param ModuleManager $moduleManager Module manager
*
* @since. 1.0.0
*/
public function __construct(ModuleManager $moduleManager)
public function __construct()
{
$this->moduleManager = $moduleManager;
}
/**
@ -106,7 +94,6 @@ final class ApplicationManager
$this->installFiles($source, $destination);
$this->installTheme($destination, $theme);
$this->installFromModules($app);
$files = Directory::list($destination, '*', true);
foreach ($files as $file) {
@ -173,21 +160,4 @@ final class ApplicationManager
);
}
}
/**
* Install routes and hooks from modules for application
*
* @param ApplicationInfo $info Application info
*
* @return void
*
* @since 1.0.0
*/
public function installFromModules(ApplicationInfo $info) : void
{
$installed = $this->moduleManager->getInstalledModules();
foreach ($installed as $module => $moduleInfo) {
$this->moduleManager->reInit($module, $info);
}
}
}

View File

@ -33,6 +33,7 @@ interface SettingsInterface extends OptionsInterface
*
* @param null|int|int[]|string|string[] $ids Ids
* @param null|string|string[] $names Setting name
* @param null|int $app Application
* @param null|string $module Module name
* @param null|int $group Group id
* @param null|int $account Account id
@ -44,6 +45,7 @@ interface SettingsInterface extends OptionsInterface
public function get(
mixed $ids = null,
string | array $names = null,
int $app = null,
string $module = null,
int $group = null,
int $account = null

View File

@ -121,14 +121,6 @@ class DataMapperAbstract implements DataMapperInterface
*/
protected static string $createdAt = '';
/**
* Language
*
* @var string
* @since 1.0.0
*/
protected static string $languageField = '';
/**
* Columns.
*
@ -246,6 +238,14 @@ class DataMapperAbstract implements DataMapperInterface
*/
protected static array $lastQueryData = [];
/**
* Fields to sort by.
*
* @var array[]
* @since 1.0.0
*/
protected static array $sortFields = [];
/**
* Constructor.
*
@ -342,6 +342,34 @@ class DataMapperAbstract implements DataMapperInterface
'ignore' => $models === null, // don't load this model
];
// @todo: ignore seems to be a bug, models === null is true VERY often because i usually omit the models definition. Why is it still working, or is it?
/** @var string */
return static::class;
}
/**
* Create a conditional value
*
* @param string $by Name of the variable to sort by
* @param string $order ASC or DESC
* @param string[] $models Models to apply the sort on
*
* @return string
*
* @since 1.0.0
*/
public static function sortBy(
string $by,
string $order = 'DESC',
?array $models = [],
) : string
{
self::$sortFields[$by] = [
'order' => $order,
'models' => $models === [] ? null : $models,
];
/** @var string */
return static::class;
}
@ -364,6 +392,7 @@ class DataMapperAbstract implements DataMapperInterface
self::$parentMapper = null;
self::$withFields = [];
self::$sortFields = [];
self::$relations = RelationType::ALL;
}
@ -750,6 +779,31 @@ class DataMapperAbstract implements DataMapperInterface
return true;
}
/**
* Delete relation
*
* This is only possible for hasMany objects which are stored in a relation table
*
* @param string $member Member name of the relation
* @param mixed $id1 Id of the primary object
* @param mixed $id2 Id of the secondary object
*
* @return bool
*
* @since 1.0.0
*/
public static function delteRelation(string $member, mixed $id1, mixed $id2) : bool
{
if (!isset(static::$hasMany[$member]) || !isset(static::$hasMany[$member]['external'])) {
return false;
}
self::removeInitialized(static::class, $id1);
self::deleteRelationTable($member, \is_array($id2) ? $id2 : [$id2], $id1);
return true;
}
/**
* Create has many
*
@ -1329,7 +1383,7 @@ class DataMapperAbstract implements DataMapperInterface
* Delete relation table entry
*
* @param string $propertyName Property name to initialize
* @param array $objsIds Object ids to insert
* @param array $objsIds Object ids to delete
* @param mixed $objId Model to reference
*
* @return void
@ -2585,7 +2639,6 @@ class DataMapperAbstract implements DataMapperInterface
* @param mixed $pivot Pivot
* @param string $column Sort column/pivot column
* @param int $limit Result limit
* @param string $order Order of the elements
* @param int $relations Load relations
* @param int $depth Relation depth
* @param Builder $query Query
@ -2598,16 +2651,13 @@ class DataMapperAbstract implements DataMapperInterface
mixed $pivot,
string $column = null,
int $limit = 50,
string $order = 'ASC',
int $relations = RelationType::ALL,
int $depth = 3,
Builder $query = null
) : array
{
$query ??= self::getQuery(depth: $depth);
$query->where(static::$table . '_d' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), '>', $pivot)
->orderBy(static::$table . '_d' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), $order)
->limit($limit);
$query->where(static::$table . '_d' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), '>', $pivot);
return self::getAllByQuery($query, $relations, $depth);
}
@ -2618,7 +2668,6 @@ class DataMapperAbstract implements DataMapperInterface
* @param mixed $pivot Pivot
* @param string $column Sort column/pivot column
* @param int $limit Result limit
* @param string $order Order of the elements
* @param int $relations Load relations
* @param int $depth Relation depth
* @param Builder $query Query
@ -2635,7 +2684,6 @@ class DataMapperAbstract implements DataMapperInterface
mixed $pivot,
string $column = null,
int $limit = 50,
string $order = 'ASC',
int $relations = RelationType::ALL,
int $depth = 3,
Builder $query = null
@ -2643,7 +2691,6 @@ class DataMapperAbstract implements DataMapperInterface
{
$query ??= self::getQuery(depth: $depth);
$query->where(static::$table . '_d' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), '<', $pivot)
->orderBy(static::$table . '_d' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), $order)
->limit($limit);
return self::getAllByQuery($query, $relations, $depth);
@ -3205,69 +3252,73 @@ class DataMapperAbstract implements DataMapperInterface
foreach (static::$hasMany as $member => $value) {
if ($value['writeonly'] ?? false === true
|| self::$relations !== RelationType::ALL
|| (isset(self::$withFields[$member]['ignore']) && self::$withFields[$member]['ignore']) // should not be loaded
) {
continue;
}
if (!isset($cachedTables[$value['table']])) {
$query = new Builder(self::$db);
if (isset($cachedTables[$value['table']])) {
$result[$member] = $cachedTables[$value['table']];
if (self::$relations === RelationType::ALL) {
$src = $value['external'] ?? $value['mapper']::$primaryField;
continue;
}
// @todo: what if a specific column name is defined instead of primaryField for the join? Fix, it should be stored in 'column'
$query->select($value['table'] . '.' . $src)
->from($value['table'])
->where($value['table'] . '.' . $value['self'], '=', $primaryKey);
$query = new Builder(self::$db);
$src = $value['external'] ?? $value['mapper']::$primaryField;
if ($value['mapper']::getTable() !== $value['table']) {
$query->leftJoin($value['mapper']::getTable())
->on($value['table'] . '.' . $src, '=', $value['mapper']::getTable() . '.' . $value['mapper']::getPrimaryField());
}
// @todo: what if a specific column name is defined instead of primaryField for the join? Fix, it should be stored in 'column'
$query->select($value['table'] . '.' . $src)
->from($value['table'])
->where($value['table'] . '.' . $value['self'], '=', $primaryKey);
// @todo: here the relation table should probably join the the model table for better ::with() handling
if ($value['mapper']::getTable() !== $value['table']) {
$query->leftJoin($value['mapper']::getTable())
->on($value['table'] . '.' . $src, '=', $value['mapper']::getTable() . '.' . $value['mapper']::getPrimaryField());
}
if (isset(self::$withFields[$member]) && self::$withFields[$member]['orderBy'] !== null) {
$query->orderBy($value['mapper']::getTable() . '.' . $value['mapper']::getColumnByMember(self::$withFields[$member]['orderBy']), self::$withFields[$member]['sortOrder']);
}
$modelName = $value['mapper']::getModelName();
if (isset(self::$withFields[$member]) && self::$withFields[$member]['limit'] !== null) {
$query->limit(self::$withFields[$member]['limit']);
}
// @todo: here the relation table should probably join the the model table for better ::with() handling
$modelName = $value['mapper']::getModelName();
foreach (self::$withFields as $condKey => $condValue) {
if (($column = $value['mapper']::getColumnByMember($condKey)) === null
|| ($condValue['models'] !== null && !\in_array($modelName, $condValue['models']))
|| ($value['conditional'] ?? false) === false
|| $condValue['ignore']
) {
continue;
}
if (isset(self::$sortFields[$member])
&& ($column = $value['mapper']::getColumnByMember($member)) !== null
&& (self::$sortFields[$member]['models'] === null || \in_array($modelName, self::$sortFields[$member]['models']))
) {
$query->orderBy($value['mapper']::getTable() . '.' . $column, self::$sortFields[$member]['order']);
} elseif (isset($value['sort'])) {
$query->orderBy($value['mapper']::getTable() . '.' . $value['mapper']::getColumnByMember($value['sort']['orderBy']), $value['sort']['sortOrder']);
}
if ($condValue['value'] !== null) {
$query->andWhere($value['mapper']::getTable() . '.' . $column, $condValue['comparison'], $condValue['value']);
}
if (isset(self::$withFields[$member]) && self::$withFields[$member]['limit'] !== null) {
$query->limit(self::$withFields[$member]['limit']);
}
if ($condValue['orderBy'] !== null) {
$query->orderBy($value['mapper']::getTable() . '.' . $column . '.' . $value['mapper']::getColumnByMember($condValue['orderBy']), $condValue['sortOrder']);
}
// @todo: like the foreach loop below, I probably also need to loop all sortFields to check if ther is a sortField defined which is part of the hasMany definition?!
if ($condValue['limit'] !== null) {
$query->limit($condValue['limit']);
}
}
foreach (self::$withFields as $condKey => $condValue) {
if (($column = $value['mapper']::getColumnByMember($condKey)) === null
|| ($condValue['models'] !== null && !\in_array($modelName, $condValue['models']))
|| ($value['conditional'] ?? false) === false
|| $condValue['ignore']
) {
continue;
}
$sth = self::$db->con->prepare($query->toSql());
if ($sth !== false) {
$sth->execute();
$cachedTables[$value['table']] = $sth->fetchAll(\PDO::FETCH_COLUMN);
if ($condValue['value'] !== null) {
$query->andWhere($value['mapper']::getTable() . '.' . $column, $condValue['comparison'], $condValue['value']);
}
if ($condValue['limit'] !== null) {
$query->limit($condValue['limit']);
}
}
$result[$member] = $cachedTables[$value['table']];
$sth = self::$db->con->prepare($query->toSql());
if ($sth !== false) {
$sth->execute();
$result[$member] = $cachedTables[$value['table']] = $sth->fetchAll(\PDO::FETCH_COLUMN);
}
}
// @todo: this returns IDs it should return the database data here in order to reduce the requests.
@ -3306,8 +3357,19 @@ class DataMapperAbstract implements DataMapperInterface
$query->fromAs(static::$table, static::$table . '_d' . $depth);
}
// handle conditional
// handle sort, the column name order is very important. Therefore it cannot be done in the foreach loop above!
$modelName = self::getModelName();
foreach (self::$sortFields as $member => $sort) {
if (($column = self::getColumnByMember($member)) === null
|| ($sort['models'] !== null && !\in_array($modelName, $sort['models']))
) {
continue;
}
$query->orderBy(static::$table . '_d' . $depth . '.' . $column, $sort['order']);
}
// handle conditional
foreach (self::$withFields as $condKey => $condValue) {
if (($column = self::getColumnByMember($condKey)) === null
|| ($condValue['models'] !== null && !\in_array($modelName, $condValue['models']))
@ -3382,7 +3444,7 @@ class DataMapperAbstract implements DataMapperInterface
// get HasManyQuery (but only for elements which have a 'column' defined)
if ($depth > 1 && self::$relations === RelationType::ALL) {
foreach (static::$hasMany as $key => $rel) {
// @todo: impl. conditiona/with handling, sort, limit, filter or is this not required here?
// @todo: impl. conditional/with handling, sort, limit, filter or is this not required here?
if (isset($rel['external']) || !isset($rel['column']) // @todo: conflict with getHasMany()???!?!?!?!
|| (isset(self::$withFields[$key]) && self::$withFields[$key]['ignore'])
) {

View File

@ -724,7 +724,7 @@ class Builder extends BuilderAbstract
}
/**
* Order by oldest.
* Order by.
*
* @param string|array $columns Columns
* @param string|string[] $order Orders
@ -736,19 +736,13 @@ class Builder extends BuilderAbstract
public function orderBy(string | array $columns, string | array $order = 'DESC') : self
{
if (\is_string($columns)) {
if (!\is_string($order)) {
throw new \InvalidArgumentException();
}
$columns = [$columns];
}
if (!isset($this->orders[$order])) {
$this->orders[$order] = [];
}
foreach ($columns as $key => $column) {
$tOrder = \is_string($order) ? $order : $order[$key];
$this->orders[$order][] = $columns;
} else {
foreach ($columns as $key => $column) {
$this->orders[\is_string($order) ? $order : $order[$key]][] = $column;
}
$this->orders[$column] = $tOrder;
}
return $this;

View File

@ -535,23 +535,19 @@ class Grammar extends GrammarAbstract
*/
protected function compileOrders(Builder $query, array $orders) : string
{
$expression = '';
$expression = '';
$lastOrderType = '';
foreach ($orders as $key => $order) {
foreach ($order as $column) {
$expression .= $this->compileSystem($column) . ', ';
}
$expression = \rtrim($expression, ', ');
$expression .= ' ' . $key . ', ';
foreach ($orders as $column => $order) {
$expression .= $this->compileSystem($column) . ' ' . $order . ', ';
}
$expression = \rtrim($expression, ', ');
if ($expression === '') {
return '';
}
$expression = \rtrim($expression, ', ');
return 'ORDER BY ' . $expression;
}

View File

@ -120,6 +120,18 @@ final class EventManager implements \Countable
return true;
}
/**
* Clear all events
*
* @return void
* @since 1.0.0
*/
public function clear() : bool
{
$this->groups = [];
$this->callbacks = [];
}
/**
* Attach new event
*

View File

@ -263,15 +263,17 @@ abstract class ModuleAbstract
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $obj);
$id = $mapper::create($obj);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', [
$account,
null, $obj,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
(string) $id,
'',
$ip,
]);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '',
[
$account,
null, $obj,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
(string) $id,
'',
$ip,
]
);
}
/**
@ -294,15 +296,17 @@ abstract class ModuleAbstract
foreach ($objs as $obj) {
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $obj);
$id = $mapper::create($obj);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', [
$account,
null, $obj,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
(string) $id,
'',
$ip,
]);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '',
[
$account,
null, $obj,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
(string) $id,
'',
$ip,
]
);
}
}
@ -331,15 +335,17 @@ abstract class ModuleAbstract
$mapper();
}
$this->app->eventManager->triggerSimilar('POST:Module:' . static::MODULE_NAME . '-' . $trigger . '-update', '', [
$account,
$old, $new,
StringUtils::intHash(\is_string($mapper) ? $mapper : \get_class($mapper)), $trigger,
static::MODULE_NAME,
(string) $id,
'',
$ip,
]);
$this->app->eventManager->triggerSimilar('POST:Module:' . static::MODULE_NAME . '-' . $trigger . '-update', '',
[
$account,
$old, $new,
StringUtils::intHash(\is_string($mapper) ? $mapper : \get_class($mapper)), $trigger,
static::MODULE_NAME,
(string) $id,
'',
$ip,
]
);
}
/**
@ -361,15 +367,17 @@ abstract class ModuleAbstract
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $obj);
$id = $mapper::delete($obj);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', [
$account,
$obj, null,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
(string) $id,
'',
$ip,
]);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '',
[
$account,
$obj, null,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
(string) $id,
'',
$ip,
]
);
}
/**
@ -389,18 +397,54 @@ abstract class ModuleAbstract
*/
protected function createModelRelation(int $account, mixed $rel1, mixed $rel2, string $mapper, string $field, string $trigger, string $ip) : void
{
$trigger = static::MODULE_NAME . '-' . $trigger . '-relation';
$trigger = static::MODULE_NAME . '-' . $trigger . '-relation-create';
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $rel1);
$mapper::createRelation($field, $rel1, $rel2);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', [
$account,
$rel1, $rel2,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
'0',
'',
$ip,
]);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '',
[
$account,
$rel1, $rel2,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
'0',
'',
$ip,
]
);
}
/**
* Create a model relation
*
* @param int $account Account id
* @param mixed $rel1 Object relation1
* @param mixed $rel2 Object relation2
* @param string $mapper Object mapper
* @param string $field Relation field
* @param string $trigger Trigger for the event manager
* @param string $ip Ip
*
* @return void
*
* @since 1.0.0
*/
protected function deleteModelRelation(int $account, mixed $rel1, mixed $rel2, string $mapper, string $field, string $trigger, string $ip) : void
{
$trigger = static::MODULE_NAME . '-' . $trigger . '-relation-delete';
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $rel1);
$mapper::deleteRelation($field, $rel1, $rel2);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '',
[
$account,
$rel1, $rel2,
StringUtils::intHash($mapper), $trigger,
static::MODULE_NAME,
'0',
'',
$ip,
]
);
}
}

View File

@ -61,14 +61,6 @@ final class ModuleManager
*/
private ApplicationAbstract $app;
/**
* Application manager.
*
* @var ApplicationManager
* @since 1.0.0
*/
private ApplicationManager $appManager;
/**
* Installed modules.
*
@ -511,18 +503,15 @@ final class ModuleManager
$providing = $info->getProviding();
foreach ($providing as $key => $version) {
if (isset($installed[$key])) {
$this->installProviding($module, $key);
$this->installProviding('/Modules/' . $module, $key);
}
}
/* Install receiving and applications */
foreach ($this->installed as $key => $value) {
$this->installProviding($key, $module);
$this->installProviding('/Modules/' . $key, $module);
}
$this->appManager = new ApplicationManager($this);
$this->installApplications($module);
return true;
} catch (\Throwable $t) {
return false; // @codeCoverageIgnore
@ -630,7 +619,7 @@ final class ModuleManager
*
* Installing additional functionality for another module
*
* @param string $from From module
* @param string $from From path
* @param string $for For module
*
* @return void
@ -639,45 +628,16 @@ final class ModuleManager
*/
public function installProviding(string $from, string $for) : void
{
if (!\is_file($this->modulePath . $from . '/Admin/Install/' . $for . '.php')) {
if (!\is_file(__DIR__ . '/../..' . $from . '/Admin/Install/' . $for . '.php')) {
return;
}
$class = '\\Modules\\' . $from . '\\Admin\\Install\\' . $for;
$from = \str_replace('/', '\\', $from);
$class = $from . '\\Admin\\Install\\' . $for;
$class::install($this->modulePath, $this->app);
}
/**
* Install applications.
*
* Installing additional functionality for another module
*
* @param string $from From module
*
* @return void
*
* @since 1.0.0
*/
public function installApplications(string $from) : void
{
if (!\is_dir($this->modulePath . $from . '/Admin/Install/Application')) {
return;
}
$dirs = \scandir($this->modulePath . $from . '/Admin/Install/Application');
if ($dirs === false) {
return;
}
foreach ($dirs as $dir) {
if ($dir === '.' || $dir === '..') {
continue;
}
$this->appManager->install($dir, __DIR__ . '/../../Web/' . \basename($dir));
}
}
/**
* Get module instance.
*

View File

@ -228,7 +228,7 @@ abstract class StatusAbstract
{
$query = new Builder($dbPool->get('update'));
$query->update('module')
->sets('module.module_active', 1)
->sets('module.module_active', ModuleStatus::ACTIVE)
->where('module.module_id', '=', $info->getInternalName())
->execute();
}
@ -416,7 +416,7 @@ abstract class StatusAbstract
{
$query = new Builder($dbPool->get('update'));
$query->update('module')
->sets('module.module_active', 0)
->sets('module.module_active', ModuleStatus::INACTIVE)
->where('module.module_id', '=', $info->getInternalName())
->execute();
}

View File

@ -34,4 +34,12 @@ interface RouterInterface
* @since 1.0.0
*/
public function importFromFile(string $path) : bool;
/**
* Clear routes
*
* @return void
* @since 1.0.0
*/
public function clear() : void;
}

View File

@ -69,6 +69,17 @@ final class SocketRouter implements RouterInterface
return true;
}
/**
* Clear routes
*
* @return void
* @since 1.0.0
*/
public function clear() : void
{
$this->routes = [];
}
/**
* Add route.
*

View File

@ -71,6 +71,17 @@ final class WebRouter implements RouterInterface
return true;
}
/**
* Clear routes
*
* @return void
* @since 1.0.0
*/
public function clear() : void
{
$this->routes = [];
}
/**
* Add route.
*
@ -144,25 +155,35 @@ final class WebRouter implements RouterInterface
) {
// if csrf is required but not set
if (isset($d['csrf']) && $d['csrf'] && $csrf === null) {
return $app !== null ? $this->route('/' . \strtolower($app) . '/e403', $csrf, $verb) : $this->route('/e403', $csrf, $verb);
return $app !== null
? $this->route('/' . \strtolower($app) . '/e403', $csrf, $verb)
: $this->route('/e403', $csrf, $verb);
}
// if permission check is invalid
if ((isset($d['permission']) && $account === null)
|| (isset($d['permission'])
&& !$account?->hasPermission(
$d['permission']['type'] ?? 0, $d['permission']['unit'] ?? $orgId, $app, $d['permission']['module'] ?? null, $d['permission']['state'] ?? null
$d['permission']['type'] ?? 0,
$d['permission']['unit'] ?? $orgId,
$app,
$d['permission']['module'] ?? null,
$d['permission']['state'] ?? null
)
)
) {
return $app !== null ? $this->route('/' . \strtolower($app) . '/e403', $csrf, $verb) : $this->route('/e403', $csrf, $verb);
return $app !== null
? $this->route('/' . \strtolower($app) . '/e403', $csrf, $verb)
: $this->route('/e403', $csrf, $verb);
}
// if validation check is invalid
if (isset($d['validation'])) {
foreach ($d['validation'] as $name => $pattern) {
if (!isset($data[$name]) || \preg_match($pattern, $data[$name]) !== 1) {
return $app !== null ? $this->route('/' . \strtolower($app) . '/e403', $csrf, $verb) : $this->route('/e403', $csrf, $verb);
foreach ($d['validation'] as $name => $validation) {
if (!isset($data[$name]) || \preg_match($validation, $data[$name]) !== 1) {
return $app !== null
? $this->route('/' . \strtolower($app) . '/e403', $csrf, $verb)
: $this->route('/e403', $csrf, $verb);
}
}
}

View File

@ -69,7 +69,7 @@ class ApplicationManagerTest extends \PHPUnit\Framework\TestCase
$app->moduleManager = new ModuleManager($app, __DIR__ . '/../../../Modules/');
$this->appManager = new ApplicationManager($app->moduleManager);
$this->appManager = new ApplicationManager();
}
/**

View File

@ -349,7 +349,7 @@ class WebRouterTest extends \PHPUnit\Framework\TestCase
RouteVerb::GET | RouteVerb::SET,
false,
[],
'/^.*?(something)=(\d*).*?$/'
'/^.*?(something)=(?<name>\d*).*?$/'
);
self::assertEquals(
@ -358,6 +358,7 @@ class WebRouterTest extends \PHPUnit\Framework\TestCase
'data' => [
'/backends/admin?something=123&sd=asdf',
'something',
'name' => '123',
'123',
],
]],