phpstan, phpcs, phpunit fixes

This commit is contained in:
Dennis Eichhorn 2023-01-27 22:12:09 +01:00
parent 790a5f8695
commit 50b71930f1
20 changed files with 590 additions and 141 deletions

View File

@ -17,44 +17,44 @@ class DefaultPdf extends TCPDF
//Page header
public function Header() {
if ($this->header_xobjid === false) {
$this->header_xobjid = $this->startTemplate($this->w, 0);
if ($this->header_xobjid === false) {
$this->header_xobjid = $this->startTemplate($this->w, 0);
// Set Logo
$image_file = __DIR__ . '/../Web/Backend/img/logo.png';
$this->Image($image_file, 15, 15, 15, 15, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
// Set Logo
$image_file = __DIR__ . '/../Web/Backend/img/logo.png';
$this->Image($image_file, 15, 15, 15, 15, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
// Set Title
$this->SetFont('helvetica', 'B', 20);
$this->setX(15 + 15 + 3);
$this->Cell(0, 14, $this->header_title, 0, false, 'L', 0, '', 0, false, 'T', 'M');
// Set Title
$this->SetFont('helvetica', 'B', 20);
$this->setX(15 + 15 + 3);
$this->Cell(0, 14, $this->header_title, 0, false, 'L', 0, '', 0, false, 'T', 'M');
$this->SetFont('helvetica', '', 10);
$this->setX(15 + 15 + 3);
$this->Cell(0, 26, $this->header_string, 0, false, 'L', 0, '', 0, false, 'T', 'M');
$this->SetFont('helvetica', '', 10);
$this->setX(15 + 15 + 3);
$this->Cell(0, 26, $this->header_string, 0, false, 'L', 0, '', 0, false, 'T', 'M');
$this->endTemplate();
}
$this->endTemplate();
}
$x = 0;
$dx = 0;
$x = 0;
$dx = 0;
if (!$this->header_xobj_autoreset AND $this->booklet AND (($this->page % 2) == 0)) {
// adjust margins for booklet mode
$dx = ($this->original_lMargin - $this->original_rMargin);
}
if (!$this->header_xobj_autoreset AND $this->booklet AND (($this->page % 2) == 0)) {
// adjust margins for booklet mode
$dx = ($this->original_lMargin - $this->original_rMargin);
}
if ($this->rtl) {
$x = $this->w + $dx;
} else {
$x = 0 + $dx;
}
if ($this->rtl) {
$x = $this->w + $dx;
} else {
$x = 0 + $dx;
}
$this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false);
if ($this->header_xobj_autoreset) {
// reset header xobject template at each page
$this->header_xobjid = false;
}
$this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false);
if ($this->header_xobj_autoreset) {
// reset header xobject template at each page
$this->header_xobjid = false;
}
}
// Page footer

View File

@ -735,11 +735,6 @@
"primary": true,
"autoincrement": true
},
"account_id_temp": {
"name": "account_id_temp",
"type": "VARCHAR(65)",
"null": false
},
"account_status": {
"name": "account_status",
"type": "TINYINT",
@ -807,14 +802,6 @@
"gdpr": true
}
},
"account_email_temp": {
"name": "account_email_temp",
"type": "VARCHAR(70)",
"null": false,
"annotations": {
"gdpr": true
}
},
"account_tries": {
"name": "account_tries",
"type": "TINYINT",
@ -842,40 +829,6 @@
}
}
},
"account_address_rel": {
"name": "account_address_rel",
"fields": {
"account_address_rel_id": {
"name": "account_address_rel_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"account_address_rel_contact": {
"name": "account_address_rel_contact",
"type": "INT",
"null": false,
"foreignTable": "profile_contact",
"foreignKey": "profile_contact_id"
},
"account_address_rel_module": {
"name": "account_address_rel_module",
"type": "INT",
"null": true,
"default": null,
"foreignTable": "module",
"foreignKey": "module_id"
},
"account_address_rel_address": {
"name": "account_address_rel_address",
"type": "INT",
"null": false,
"foreignTable": "address",
"foreignKey": "address_id"
}
}
},
"account_contact": {
"name": "account_contact",
"fields": {
@ -908,7 +861,7 @@
},
"account_contact_module": {
"name": "account_contact_module",
"type": "INT",
"type": "VARCHAR(190)",
"null": true,
"default": null,
"foreignTable": "module",
@ -923,6 +876,40 @@
}
}
},
"account_address_rel": {
"name": "account_address_rel",
"fields": {
"account_address_rel_id": {
"name": "account_address_rel_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"account_address_account": {
"name": "account_address_account",
"type": "INT",
"null": false,
"foreignTable": "account",
"foreignKey": "account_id"
},
"account_address_rel_module": {
"name": "account_address_rel_module",
"type": "VARCHAR(190)",
"null": true,
"default": null,
"foreignTable": "module",
"foreignKey": "module_id"
},
"account_address_rel_address": {
"name": "account_address_rel_address",
"type": "INT",
"null": false,
"foreignTable": "address",
"foreignKey": "address_id"
}
}
},
"account_account_rel": {
"description": "Accounts can belong to other accounts. E.g. a user can belong to a company account",
"name": "account_account_rel",

View File

@ -23,6 +23,9 @@ use Modules\Admin\Models\AccountPermission;
use Modules\Admin\Models\AccountPermissionMapper;
use Modules\Admin\Models\App;
use Modules\Admin\Models\AppMapper;
use Modules\Admin\Models\ContactMapper;
use Modules\Admin\Models\DataChange;
use Modules\Admin\Models\DataChangeMapper;
use Modules\Admin\Models\Group;
use Modules\Admin\Models\GroupMapper;
use Modules\Admin\Models\GroupPermission;
@ -32,17 +35,12 @@ use Modules\Admin\Models\Module;
use Modules\Admin\Models\ModuleMapper;
use Modules\Admin\Models\ModuleStatusUpdateType;
use Modules\Admin\Models\NullAccount;
use Modules\Admin\Models\NullDataChange;
use Modules\Admin\Models\PermissionCategory;
use Modules\Admin\Models\SettingsEnum;
use Modules\Media\Models\Collection;
use Modules\Media\Models\CollectionMapper;
use Modules\Media\Models\UploadFile;
use Modules\Admin\Models\App;
use phpOMS\Application\ApplicationType;
use Modules\Admin\Models\AppMapper;
use Modules\Admin\Models\DataChange;
use Modules\Admin\Models\NullDataChange;
use Modules\Admin\Models\DataChangeMapper;
use phpOMS\Account\AccountStatus;
use phpOMS\Account\AccountType;
use phpOMS\Account\GroupStatus;
@ -487,18 +485,19 @@ final class ApiController extends Controller
$id = isset($data['id']) ? (int) $data['id'] : null;
$name = $data['name'] ?? null;
$content = $data['content'] ?? null;
$unit = $data['unit'] ?? null;
$unit = $data['unit'] ?? null;
$app = $data['app'] ?? null;
$module = $data['module'] ?? null;
$group = isset($data['group']) ? (int) $data['group'] : null;
$account = isset($data['account']) ? (int) $data['account'] : null;
/** @var \Model\Setting $old */
$old = $this->app->appSettings->get($id, $name, $unit, $app, $module, $group, $account);
$new = clone $old;
$new->name = $name ?? $new->name;
$new->content = $content ?? $new->content;
$new->unit = $unit ?? $new->unit;
$new->unit = $unit ?? $new->unit;
$new->app = $app ?? $new->app;
$new->module = $module ?? $new->module;
$new->group = $group ?? $new->group;
@ -506,10 +505,10 @@ final class ApiController extends Controller
$this->app->appSettings->set([
[
'id' => $new->id,
'id' => $new->getId(),
'name' => $new->name,
'content' => $new->content,
'unit' => $new->unit,
'unit' => $new->unit,
'app' => $new->app,
'module' => $new->module,
'group' => $new->group,
@ -556,12 +555,15 @@ final class ApiController extends Controller
return;
}
/** @var Account $account */
$account = AccountMapper::get()
->where('id', $requestAccount)
->execute();
// test old password is correct
if (AccountMapper::login($account->login, (string) $request->getData('oldpass')) !== $requestAccount) {
if ($account->login === null
|| AccountMapper::login($account->login, (string) $request->getData('oldpass')) !== $requestAccount
) {
$this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []);
$response->header->status = RequestStatusCode::R_403;
@ -577,6 +579,7 @@ final class ApiController extends Controller
}
// test password complexity
/** @var \Model\Setting $complexity */
$complexity = $this->app->appSettings->get(names: [SettingsEnum::PASSWORD_PATTERN], module: 'Admin');
if (\preg_match($complexity->content, (string) $request->getData('newpass')) !== 1) {
$this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []);
@ -825,6 +828,16 @@ final class ApiController extends Controller
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Application', 'Application successfully created', $app);
}
/**
* Create default settings for new app
*
* @param App $app Application to create new settings for
* @param RequestAbstract $request Request used to create the app
*
* @return void
*
* @since 1.0.0
*/
private function createDefaultAppSettings(App $app, RequestAbstract $request) : void
{
$settings = [];
@ -1281,21 +1294,24 @@ final class ApiController extends Controller
$defaultGroupIds = [];
if ($request->hasData('app')) {
/** @var \Model\Setting $defaultGroupSettings */
$defaultGroupSettings = $this->app->appSettings->get(
names: SettingsEnum::APP_DEFAULT_GROUPS,
app: (int) $request->getData('app'),
module: 'Admin'
);
$defaultGroups = \array_merge($defaultGroups, \json_decode($defaultGroupSettings->content, true));
}
if ($request->hasData('unit')) {
/** @var \Model\Setting $defaultGroupSettings */
$defaultGroupSettings = $this->app->appSettings->get(
names: SettingsEnum::UNIT_DEFAULT_GROUPS,
unit: (int) $request->getData('unit'),
module: 'Admin'
);
$defaultGroups = \array_merge($defaultGroups, \json_decode($defaultGroupSettings->content, true));
}
@ -1304,7 +1320,15 @@ final class ApiController extends Controller
}
if (!empty($defaultGroupIds)) {
$this->createModelRelation($account->getId(), $account->getId(), $defaultGroupIds, AccountMapper::class, 'groups', 'account', $request->getOrigin());
$this->createModelRelation(
$account->getId(),
$account->getId(),
$defaultGroupIds,
AccountMapper::class,
'groups',
'account',
$request->getOrigin()
);
}
$this->fillJsonResponse(
@ -1319,6 +1343,19 @@ final class ApiController extends Controller
);
}
/**
* Api method to register an account
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiAccountRegister(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void
{
if (!empty($val = $this->validateRegistration($request))) {
@ -1328,6 +1365,7 @@ final class ApiController extends Controller
return;
}
/** @var \Model\Setting $allowed */
$allowed = $this->app->appSettings->get(
names: [SettingsEnum::REGISTRATION_ALLOWED],
app: (int) $request->getData('app'),
@ -1341,6 +1379,7 @@ final class ApiController extends Controller
return;
}
/** @var \Model\Setting $complexity */
$complexity = $this->app->appSettings->get(names: [SettingsEnum::PASSWORD_PATTERN], module: 'Admin');
if ($request->hasData('password')
&& \preg_match($complexity->content, (string) $request->getData('password')) !== 1
@ -1363,6 +1402,7 @@ final class ApiController extends Controller
// email already in use
if (!($emailAccount instanceof NullAccount)
&& $emailAccount->login !== null
&& AccountMapper::login($emailAccount->login, (string) $request->getData('password')) !== LoginReturnType::OK
) {
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Registration', 'Email already in use, use your login details to login or activate your account also for this service.', []);
@ -1384,6 +1424,7 @@ final class ApiController extends Controller
return;
} elseif ($account === null
&& !($loginAccount instanceof NullAccount)
&& $loginAccount->login !== null
&& AccountMapper::login($loginAccount->login, (string) $request->getData('password')) !== LoginReturnType::OK
) {
$account = $loginAccount;
@ -1392,18 +1433,22 @@ final class ApiController extends Controller
$defaultGroups = [];
$defaultGroupIds = [];
/** @var \Model\Setting $defaultGroupSettings */
$defaultGroupSettings = $this->app->appSettings->get(
names: SettingsEnum::APP_DEFAULT_GROUPS,
app: (int) $request->getData('app'),
module: 'Admin'
);
$defaultGroups = \array_merge($defaultGroups, \json_decode($defaultGroupSettings->content, true));
/** @var \Model\Setting $defaultGroupSettings */
$defaultGroupSettings = $this->app->appSettings->get(
names: SettingsEnum::UNIT_DEFAULT_GROUPS,
unit: (int) $request->getData('unit'),
module: 'Admin'
);
$defaultGroups = \array_merge($defaultGroups, \json_decode($defaultGroupSettings->content, true));
foreach ($defaultGroups as $group) {
@ -1412,6 +1457,7 @@ final class ApiController extends Controller
// Already registered
if ($account !== null) {
/** @var Account $account */
$account = AccountMapper::get()
->with('groups')
->where('id', $account->getId())
@ -1454,8 +1500,8 @@ final class ApiController extends Controller
$account = $response->get($request->uri->__toString())['response'];
// Create confirmation pending entry
$dataChange = new DataChange();
$dataChange->type = 'account';
$dataChange = new DataChange();
$dataChange->type = 'account';
$dataChange->createdBy = $account->getId();
$dataChange->data = \json_encode([
@ -1468,7 +1514,7 @@ final class ApiController extends Controller
$this->createModel($account->getId(), $dataChange, DataChangeMapper::class, 'datachange', $request->getOrigin());
++$tries;
} while($dataChange->getId() === 0 && $tries < 5);
} while ($dataChange->getId() === 0 && $tries < 5);
}
// Create confirmation email
@ -1501,7 +1547,20 @@ final class ApiController extends Controller
return [];
}
// @todo: maybe move to job/workflow??? This feels very much like a job/event especially if we make the 'type' an event-trigger
/**
* Api method to perform a pending model change
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
* @todo: maybe move to job/workflow??? This feels very much like a job/event especially if we make the 'type' an event-trigger
*
* @since 1.0.0
*/
public function apiDataChange(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void
{
if (!empty($val = $this->validateDataChange($request))) {
@ -1521,6 +1580,7 @@ final class ApiController extends Controller
switch ($dataChange->type) {
case 'account':
/** @var Account $old */
$old = AccountMapper::get()->where('id', $dataChange->createdBy)->execute();
$new = clone $old;
@ -1614,13 +1674,13 @@ final class ApiController extends Controller
*/
private function createAccountFromRequest(RequestAbstract $request) : Account
{
$account = new Account();
$account->setStatus((int) ($request->getData('status') ?? AccountStatus::INACTIVE));
$account->setType((int) ($request->getData('type') ?? AccountType::USER));
$account = new Account();
$account->login = (string) ($request->getData('login') ?? '');
$account->name1 = (string) ($request->getData('name1') ?? '');
$account->name2 = (string) ($request->getData('name2') ?? '');
$account->name3 = (string) ($request->getData('name3') ?? '');
$account->setStatus((int) ($request->getData('status') ?? AccountStatus::INACTIVE));
$account->setType((int) ($request->getData('type') ?? AccountType::USER));
$account->setEmail((string) ($request->getData('email') ?? ''));
$account->generatePassword((string) ($request->getData('password') ?? ''));
@ -2541,4 +2601,82 @@ final class ApiController extends Controller
}
}
}
/**
* Routing end-point for application behaviour.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiContactCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void
{
if (!empty($val = $this->validateContactCreate($request))) {
$response->set('contact_create', new FormValidation($val));
$response->header->status = RequestStatusCode::R_400;
return;
}
$contact = $this->createContactFromRequest($request);
$this->createModel($request->header->account, $contact, ContactMapper::class, 'account_contact', $request->getOrigin());
$this->createModelRelation(
$request->header->account,
(int) $request->getData('account'),
$contact->getId(),
AccountMapper::class, 'contacts', '', $request->getOrigin()
);
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Contact', 'Contact successfully created', $contact);
}
/**
* Validate contact element create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
public function validateContactCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['account'] = empty($request->getData('account')))
|| ($val['type'] = !\is_numeric($request->getData('type')))
|| ($val['content'] = empty($request->getData('content')))
) {
return $val;
}
return [];
}
/**
* Method to create a account element from request.
*
* @param RequestAbstract $request Request
*
* @return ContactElement
*
* @since 1.0.0
*/
public function createContactFromRequest(RequestAbstract $request) : ContactElement
{
/** @var ContactElement $element */
$element = new ContactElement();
$element->setType((int) ($request->getData('type') ?? 0));
$element->setSubtype((int) ($request->getData('subtype') ?? 0));
$element->content = (string) ($request->getData('content') ?? '');
$element->account = (int) ($request->getData('account') ?? 0);
return $element;
}
}

View File

@ -155,11 +155,7 @@ final class BackendController extends Controller
/** @var \Model\Setting[] $exportTemplates */
$exportTemplates = $this->app->appSettings->get(
names: [
SettingsEnum::DEFAULT_PDF_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_EXCEL_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_CSV_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_WORD_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_EMAIL_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_LIST_EXPORTS,
],
module: 'Admin'
);
@ -335,11 +331,7 @@ final class BackendController extends Controller
/** @var \Model\Setting[] $exportTemplates */
$exportTemplates = $this->app->appSettings->get(
names: [
SettingsEnum::DEFAULT_PDF_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_EXCEL_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_CSV_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_WORD_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_EMAIL_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_LIST_EXPORTS,
],
module: 'Admin'
);
@ -472,11 +464,7 @@ final class BackendController extends Controller
/** @var \Model\Setting[] $exportTemplates */
$exportTemplates = $this->app->appSettings->get(
names: [
SettingsEnum::DEFAULT_PDF_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_EXCEL_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_CSV_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_WORD_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_EMAIL_EXPORT_TEMPLATE,
SettingsEnum::DEFAULT_LIST_EXPORTS,
],
module: 'Admin'
);

View File

@ -14,6 +14,8 @@ declare(strict_types=1);
namespace Modules\Admin\Models;
use phpOMS\Stdlib\Base\Location;
/**
* Account class.
*
@ -55,4 +57,72 @@ class Account extends \phpOMS\Account\Account
* @since 1.0.0
*/
public ?\DateTimeImmutable $tempPasswordLimit = null;
/**
* Location data.
*
* @var Location[]
* @since 1.0.0
*/
protected array $locations = [];
/**
* Contact data.
*
* @var Contact[]
* @since 1.0.0
*/
protected array $contacts = [];
/**
* Get account locations.
*
* @return Location[]
*
* @since 1.0.0
*/
public function getLocations() : array
{
return $this->locations;
}
/**
* Add location.
*
* @param Location $location Location
*
* @return void
*
* @since 1.0.0
*/
public function addLocation(Location $location) : void
{
$this->locations[] = $location;
}
/**
* Get account contact element.
*
* @return Contact[]
*
* @since 1.0.0
*/
public function getContacts() : array
{
return $this->contacts;
}
/**
* Add contact element.
*
* @param Contact $contact Contact Element
*
* @return void
*
* @since 1.0.0
*/
public function addContact(Contact $contact) : void
{
$this->contacts[] = $contact;
}
}

View File

@ -51,7 +51,7 @@ final class AccountCredentialMapper extends AccountMapper
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = Account::class;

View File

@ -53,7 +53,7 @@ class AccountMapper extends DataMapperFactory
/**
* Has one relation.
*
* @var array<string, array{mapper:string, external:string, by?:string, column?:string, conditional?:bool}>
* @var array<string, array{mapper:class-string, external:string, by?:string, column?:string, conditional?:bool}>
* @since 1.0.0
*/
public const OWNS_ONE = [
@ -66,7 +66,7 @@ class AccountMapper extends DataMapperFactory
/**
* Has many relation.
*
* @var array<string, array{mapper:string, table:string, self?:?string, external?:?string, column?:string}>
* @var array<string, array{mapper:class-string, table:string, self?:?string, external?:?string, column?:string}>
* @since 1.0.0
*/
public const HAS_MANY = [
@ -82,12 +82,24 @@ class AccountMapper extends DataMapperFactory
'external' => 'account_account_rel_root',
'self' => 'account_account_rel_child',
],
'locations' => [
'mapper' => AddressMapper::class,
'table' => 'account_address_rel',
'external' => 'account_address_rel_address',
'self' => 'account_address_rel_account',
],
'contacts' => [
'mapper' => ContactMapper::class,
'table' => 'account_contact',
'self' => 'account_contact_account',
'external' => null,
],
];
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = Account::class;

View File

@ -52,7 +52,7 @@ final class AccountPermissionMapper extends DataMapperFactory
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = AccountPermission::class;

View File

@ -48,7 +48,7 @@ final class AddressMapper extends DataMapperFactory
/**
* Has one relation.
*
* @var array<string, array{mapper:string, external:string, by?:string, column?:string, conditional?:bool}>
* @var array<string, array{mapper:class-string, external:string, by?:string, column?:string, conditional?:bool}>
* @since 1.0.0
*/
public const OWNS_ONE = [

View File

@ -17,14 +17,14 @@ namespace Modules\Admin\Models;
use phpOMS\Account\AccountStatus;
/**
* Account class.
* Api key class.
*
* @package Modules\Admin\Models
* @license OMS License 1.0
* @link https://jingga.app
* @since 1.0.0
*/
class Account
class ApiKey
{
/**
* Id.
@ -43,7 +43,7 @@ class Account
public string $key = '';
/**
* Account status.
* Api key status.
*
* @var int
* @since 1.0.0
@ -73,7 +73,7 @@ class Account
*/
public function __construct()
{
$this->key = \random_bytes(128);
$this->key = \random_bytes(128);
$this->createdAt = new \DateTimeImmutable('now');
}
}

View File

@ -36,17 +36,17 @@ class ApiKeyMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'account_api_id' => ['name' => 'account_api_id', 'type' => 'int', 'internal' => 'id'],
'account_api_key' => ['name' => 'account_api_key', 'type' => 'string', 'internal' => 'key'],
'account_api_status' => ['name' => 'account_api_status', 'type' => 'int', 'internal' => 'status'],
'account_api_account' => ['name' => 'account_api_account', 'type' => 'int', 'internal' => 'account'],
'account_api_created_at' => ['name' => 'account_api_created_at', 'type' => 'DateTime', 'internal' => 'createdAt'],
'account_api_id' => ['name' => 'account_api_id', 'type' => 'int', 'internal' => 'id'],
'account_api_key' => ['name' => 'account_api_key', 'type' => 'string', 'internal' => 'key'],
'account_api_status' => ['name' => 'account_api_status', 'type' => 'int', 'internal' => 'status'],
'account_api_account' => ['name' => 'account_api_account', 'type' => 'int', 'internal' => 'account'],
'account_api_created_at' => ['name' => 'account_api_created_at', 'type' => 'DateTime', 'internal' => 'createdAt'],
];
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = ApiKey::class;
@ -75,6 +75,15 @@ class ApiKeyMapper extends DataMapperFactory
*/
public const CREATED_AT = 'account_api_created_at';
/**
* Authenticates a user based on an api key
*
* @param string $api Api key
*
* @return int
*
* @since 1.0.0
*/
public static function authenticateApiKey(string $api) : int
{
if (empty($api)) {
@ -107,11 +116,11 @@ class ApiKeyMapper extends DataMapperFactory
}
$query->update('account')
->set([
'account_lactive' => new \DateTime('now'),
])
->where('account_id', '=', (int) $result['account_id'])
->execute();
->set([
'account_lactive' => new \DateTime('now'),
])
->where('account_id', '=', (int) $result['account_id'])
->execute();
return (int) $result['account_id'];
} catch (\Exception $e) {

View File

@ -43,7 +43,7 @@ final class AppMapper extends DataMapperFactory
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = App::class;

138
Models/Contact.php Normal file
View File

@ -0,0 +1,138 @@
<?php
/**
* Karaka
*
* PHP Version 8.1
*
* @package Modules\Admin\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Admin\Models;
/**
* Contact element class.
*
* Information such as phone number, email, ...
*
* @package Modules\Admin\Models
* @license OMS License 1.0
* @link https://jingga.app
* @since 1.0.0
*/
class Contact
{
/**
* ID.
*
* @var int
* @since 1.0.0
*/
protected int $id = 0;
/**
* Contact element type.
*
* @var int
* @since 1.0.0
*/
private int $type = 0;
/**
* Contact element subtype.
*
* @var int
* @since 1.0.0
*/
private int $subtype = 0;
/**
* Content.
*
* @var string
* @since 1.0.0
*/
public string $content = '';
/**
* Order.
*
* @var int
* @since 1.0.0
*/
public int $order = 0;
public int $contact = 0;
public int $account = 0;
public string $module = '';
/**
* Get id.
*
* @return int Model id
*
* @since 1.0.0
*/
public function getId() : int
{
return $this->id;
}
/**
* Set type
*
* @param int $type Type
*
* @return void
*
* @since 1.0.0
*/
public function setType(int $type) : void
{
$this->type = $type;
}
/**
* Get type
*
* @return int
*
* @since 1.0.0
*/
public function getType() : int
{
return $this->type;
}
/**
* Set subtype
*
* @param int $subtype Subtype
*
* @return void
*
* @since 1.0.0
*/
public function setSubtype(int $subtype) : void
{
$this->subtype = $subtype;
}
/**
* Get subtype
*
* @return int
*
* @since 1.0.0
*/
public function getSubtype() : int
{
return $this->subtype;
}
}

60
Models/ContactMapper.php Normal file
View File

@ -0,0 +1,60 @@
<?php
/**
* Karaka
*
* PHP Version 8.1
*
* @package Modules\Admin\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Admin\Models;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* Contact mapper class.
*
* @package Modules\Admin\Models
* @license OMS License 1.0
* @link https://jingga.app
* @since 1.0.0
*/
final class ContactMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'account_contact_id' => ['name' => 'account_contact_id', 'type' => 'int', 'internal' => 'id'],
'account_contact_type' => ['name' => 'account_contact_type', 'type' => 'int', 'internal' => 'type'],
'account_contact_subtype' => ['name' => 'account_contact_subtype', 'type' => 'int', 'internal' => 'subtype'],
'account_contact_order' => ['name' => 'account_contact_order', 'type' => 'int', 'internal' => 'order'],
'account_contact_content' => ['name' => 'account_contact_content', 'type' => 'string', 'internal' => 'content'],
'account_contact_module' => ['name' => 'account_contact_module', 'type' => 'string', 'internal' => 'module'],
'account_contact_account' => ['name' => 'account_contact_account', 'type' => 'int', 'internal' => 'account'],
];
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'account_contact';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD ='account_contact_id';
}

View File

@ -40,12 +40,36 @@ class DataChange
*/
protected string $hash = '';
/**
* Data for the change
*
* @var string
* @since 1.0.0
*/
public string $data = '';
/**
* Change type
*
* @var string
* @since 1.0.0
*/
public string $type = '';
/**
* Created by account
*
* @var int
* @since 1.0.0
*/
public int $createdBy = 0;
/**
* Created at
*
* @var \DateTimeImmutable
* @since 1.0.0
*/
public \DateTimeImmutable $createdAt;
/**
@ -71,6 +95,13 @@ class DataChange
return $this->id;
}
/**
* Create hash for data change as identifier
*
* @return void
*
* @since 1.0.0
*/
public function reHash() : void
{
$this->hash = \random_bytes(64);

View File

@ -44,7 +44,7 @@ final class DataChangeMapper extends DataMapperFactory
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = DataChange::class;

View File

@ -45,7 +45,7 @@ final class GroupMapper extends DataMapperFactory
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = Group::class;
@ -77,7 +77,7 @@ final class GroupMapper extends DataMapperFactory
/**
* Has many relation.
*
* @var array<string, array{mapper:string, table:string, self?:?string, external?:?string, column?:string}>
* @var array<string, array{mapper:class-string, table:string, self?:?string, external?:?string, column?:string}>
* @since 1.0.0
*/
public const HAS_MANY = [

View File

@ -52,7 +52,7 @@ final class GroupPermissionMapper extends DataMapperFactory
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = GroupPermission::class;

View File

@ -92,7 +92,7 @@ final class LocalizationMapper extends DataMapperFactory
/**
* Has one relation.
*
* @var array<string, array{mapper:string, external:string, by?:string, column?:string, conditional?:bool}>
* @var array<string, array{mapper:class-string, external:string, by?:string, column?:string, conditional?:bool}>
* @since 1.0.0
*/
public const OWNS_ONE = [
@ -135,7 +135,7 @@ final class LocalizationMapper extends DataMapperFactory
/**
* Model to use by the mapper.
*
* @var string
* @var class-string
* @since 1.0.0
*/
public const MODEL = Localization::class;

View File

@ -0,0 +1,16 @@
<?php
/**
* Karaka
*
* PHP Version 8.1
*
* @package Modules\Admin
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
return ['Admin' => [
]];