mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 09:48:40 +00:00
september update 1
This commit is contained in:
parent
420c34aec2
commit
99df0e971e
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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'] ?? [];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'])
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
],
|
||||
]],
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user