mirror of
https://github.com/Karaka-Management/oms-Admin.git
synced 2026-01-11 21:38:40 +00:00
4089 lines
141 KiB
PHP
Executable File
4089 lines
141 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Jingga
|
|
*
|
|
* PHP Version 8.2
|
|
*
|
|
* @package Modules\Admin
|
|
* @copyright Dennis Eichhorn
|
|
* @license OMS License 2.2
|
|
* @version 1.0.0
|
|
* @link https://jingga.app
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace Modules\Admin\Controller;
|
|
|
|
use Model\Setting;
|
|
use Model\SettingMapper;
|
|
use Modules\Admin\Models\Account;
|
|
use Modules\Admin\Models\AccountCredentialMapper;
|
|
use Modules\Admin\Models\AccountMapper;
|
|
use Modules\Admin\Models\AccountPermission;
|
|
use Modules\Admin\Models\AccountPermissionMapper;
|
|
use Modules\Admin\Models\AddressMapper;
|
|
use Modules\Admin\Models\App;
|
|
use Modules\Admin\Models\AppMapper;
|
|
use Modules\Admin\Models\Contact;
|
|
use Modules\Admin\Models\ContactMapper;
|
|
use Modules\Admin\Models\ContactType;
|
|
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;
|
|
use Modules\Admin\Models\GroupPermissionMapper;
|
|
use Modules\Admin\Models\LocalizationMapper;
|
|
use Modules\Admin\Models\Module;
|
|
use Modules\Admin\Models\ModuleMapper;
|
|
use Modules\Admin\Models\ModuleStatusUpdateType;
|
|
use Modules\Admin\Models\NullAccount;
|
|
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\Messages\Models\EmailMapper;
|
|
use Modules\Messages\Models\SettingsEnum as SettingsEnumMessages;
|
|
use phpOMS\Account\AccountStatus;
|
|
use phpOMS\Account\AccountType;
|
|
use phpOMS\Account\GroupStatus;
|
|
use phpOMS\Account\PermissionAbstract;
|
|
use phpOMS\Account\PermissionOwner;
|
|
use phpOMS\Account\PermissionType;
|
|
use phpOMS\Api\Geocoding\Nominatim;
|
|
use phpOMS\Application\ApplicationInfo;
|
|
use phpOMS\Application\ApplicationManager;
|
|
use phpOMS\Application\ApplicationType;
|
|
use phpOMS\Auth\LoginReturnType;
|
|
use phpOMS\DataStorage\Database\Query\Builder;
|
|
use phpOMS\Localization\ISO3166TwoEnum;
|
|
use phpOMS\Localization\Localization;
|
|
use phpOMS\Message\Http\HttpRequest;
|
|
use phpOMS\Message\Http\HttpResponse;
|
|
use phpOMS\Message\Http\RequestMethod;
|
|
use phpOMS\Message\Http\RequestStatusCode;
|
|
use phpOMS\Message\Http\Rest;
|
|
use phpOMS\Message\Mail\DsnNotificationType;
|
|
use phpOMS\Message\Mail\MailHandler;
|
|
use phpOMS\Message\Mail\Smtp;
|
|
use phpOMS\Message\Mail\SubmitType;
|
|
use phpOMS\Message\NotificationLevel;
|
|
use phpOMS\Message\RequestAbstract;
|
|
use phpOMS\Message\ResponseAbstract;
|
|
use phpOMS\Model\Message\FormValidation;
|
|
use phpOMS\Module\ModuleInfo;
|
|
use phpOMS\Module\ModuleStatus;
|
|
use phpOMS\Security\EncryptionHelper;
|
|
use phpOMS\Stdlib\Base\Address;
|
|
use phpOMS\Stdlib\Base\AddressType;
|
|
use phpOMS\System\File\Local\File;
|
|
use phpOMS\System\MimeType;
|
|
use phpOMS\Uri\HttpUri;
|
|
use phpOMS\Uri\UriFactory;
|
|
use phpOMS\Utils\ArrayUtils;
|
|
use phpOMS\Utils\Parser\Markdown\Markdown;
|
|
use phpOMS\Utils\Parser\Php\ArrayParser;
|
|
use phpOMS\Utils\RnG\StringUtils as StringRng;
|
|
use phpOMS\Utils\StringUtils;
|
|
use phpOMS\Validation\Network\Email as EmailValidator;
|
|
|
|
/**
|
|
* Admin controller class.
|
|
*
|
|
* This class is responsible for the basic admin activities such as managing accounts, groups, permissions and modules.
|
|
*
|
|
* @package Modules\Admin
|
|
* @license OMS License 2.2
|
|
* @link https://jingga.app
|
|
* @since 1.0.0
|
|
*
|
|
* @todo Create a view where it's possible to create/activate, change and delete/deactivate hooks for events.
|
|
* https://github.com/Karaka-Management/oms-Admin/issues/12
|
|
*
|
|
* @todo Split up the ApiController, it is doing way to much in one file.
|
|
* Consider to create one for: accounts+groups+permissions and one for general stuff like address+settings etc.
|
|
*
|
|
* @todo Create api key/token permissions for api interactions through tokens
|
|
* Maybe we need to assign tokens to users but sometimes users want to give tokens limited permissions
|
|
* https://github.com/Karaka-Management/oms-Admin/issues/24
|
|
* https://github.com/Karaka-Management/oms-Admin/issues/25
|
|
* https://github.com/Karaka-Management/oms-Admin/issues/26
|
|
*/
|
|
final class ApiController extends Controller
|
|
{
|
|
/**
|
|
* Api method to login
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiLogin(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
|
|
|
|
$login = AccountMapper::login(
|
|
$request->getDataString('user') ?? '',
|
|
$request->getDataString('pass') ?? ''
|
|
);
|
|
|
|
if ($login > LoginReturnType::OK) {
|
|
$this->app->sessionManager->sessionStart();
|
|
$this->app->sessionManager->set('UID', $login, true);
|
|
$response->set($request->uri->__toString(), new \phpOMS\Model\Message\Redirect());
|
|
} elseif ($login === LoginReturnType::NOT_ACTIVATED) {
|
|
$response->header->status = RequestStatusCode::R_401;
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::WARNING,
|
|
'',
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'NOT_ACTIVATED'),
|
|
null
|
|
);
|
|
} elseif ($login === LoginReturnType::WRONG_INPUT_EXCEEDED) {
|
|
$response->header->status = RequestStatusCode::R_401;
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::WARNING,
|
|
'',
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'WRONG_INPUT_EXCEEDED'),
|
|
null
|
|
);
|
|
} else {
|
|
$response->header->status = RequestStatusCode::R_401;
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::WARNING,
|
|
'',
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'LOGIN_ERROR'),
|
|
null
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Api method to login
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiLogout(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
|
|
|
|
$this->app->sessionManager->sessionStart();
|
|
$this->app->sessionManager->remove('UID');
|
|
$this->app->sessionManager->save();
|
|
|
|
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
|
|
$response->set($request->uri->__toString(), [
|
|
'status' => NotificationLevel::OK,
|
|
'title' => $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'LogoutSuccessfulTitle'),
|
|
'message' => $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'LogoutSuccessfulMsg'),
|
|
'response' => null,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Create basic server mail handler
|
|
*
|
|
* @return MailHandler
|
|
*
|
|
* @since 1.0.0
|
|
**/
|
|
public function setUpServerMailHandler() : MailHandler
|
|
{
|
|
/** @var \Model\Setting[] $emailSettings */
|
|
$emailSettings = $this->app->appSettings->get(
|
|
names: [
|
|
SettingsEnum::MAIL_SERVER_OUT,
|
|
SettingsEnum::MAIL_SERVER_PORT_OUT,
|
|
SettingsEnum::MAIL_SERVER_TYPE,
|
|
SettingsEnum::MAIL_SERVER_USER,
|
|
SettingsEnum::MAIL_SERVER_PASS,
|
|
SettingsEnum::MAIL_SERVER_TLS,
|
|
],
|
|
module: 'Admin'
|
|
);
|
|
|
|
if (empty($emailSettings)) {
|
|
/** @var \Model\Setting[] $emailSettings */
|
|
$emailSettings = $this->app->appSettings->get(
|
|
names: [
|
|
SettingsEnum::MAIL_SERVER_OUT,
|
|
SettingsEnum::MAIL_SERVER_PORT_OUT,
|
|
SettingsEnum::MAIL_SERVER_TYPE,
|
|
SettingsEnum::MAIL_SERVER_USER,
|
|
SettingsEnum::MAIL_SERVER_PASS,
|
|
SettingsEnum::MAIL_SERVER_TLS,
|
|
],
|
|
module: 'Admin'
|
|
);
|
|
}
|
|
|
|
$handler = new MailHandler();
|
|
$handler->setMailer($emailSettings[SettingsEnum::MAIL_SERVER_TYPE]->content ?? SubmitType::MAIL);
|
|
$handler->useAutoTLS = (bool) ($emailSettings[SettingsEnum::MAIL_SERVER_TLS]->content ?? false);
|
|
|
|
if (($emailSettings[SettingsEnum::MAIL_SERVER_TYPE]->content ?? SubmitType::MAIL) === SubmitType::SMTP) {
|
|
$smtp = new Smtp();
|
|
$handler->smtp = $smtp;
|
|
}
|
|
|
|
if (!empty($port = $emailSettings[SettingsEnum::MAIL_SERVER_PORT_OUT]->content)) {
|
|
$handler->port = (int) $port;
|
|
}
|
|
|
|
$handler->host = $emailSettings[SettingsEnum::MAIL_SERVER_OUT]->content ?? 'localhost';
|
|
$handler->hostname = $emailSettings[SettingsEnum::MAIL_SERVER_OUT]->content ?? '';
|
|
$handler->username = $emailSettings[SettingsEnum::MAIL_SERVER_USER]->content ?? '';
|
|
$handler->password = $emailSettings[SettingsEnum::MAIL_SERVER_PASS]->isEncrypted && !empty($_SERVER['OMS_PRIVATE_KEY_I'] ?? '')
|
|
? (EncryptionHelper::decryptShared($emailSettings[SettingsEnum::MAIL_SERVER_PASS]->content ?? '', $_SERVER['OMS_PRIVATE_KEY_I']))
|
|
: ($emailSettings[SettingsEnum::MAIL_SERVER_PASS]->content ?? '');
|
|
|
|
$handler->dsn = DsnNotificationType::FAILURE;
|
|
|
|
return $handler;
|
|
}
|
|
|
|
/**
|
|
* Setup default values for emails (incl. basic templating)
|
|
*
|
|
* @param \Modules\Messages\Models\Email $mail Email
|
|
* @param string $language Email language (e.g. 'en', 'de')
|
|
*
|
|
* @return bool
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function setupEmailDefaults(\Modules\Messages\Models\Email $mail, string $language = '') : bool
|
|
{
|
|
/** @var \Model\Setting[] $emailSettings */
|
|
$emailSettings = $this->app->appSettings->get(
|
|
names: [SettingsEnum::MAIL_SERVER_ADDR],
|
|
module: 'Admin'
|
|
);
|
|
|
|
if (empty($emailSettings[SettingsEnum::MAIL_SERVER_ADDR]->content)) {
|
|
return false;
|
|
}
|
|
|
|
$mail->setFrom($emailSettings[SettingsEnum::MAIL_SERVER_ADDR]->content);
|
|
|
|
// @todo Implement a model reading system which allows to define alternative conditions/wheres
|
|
// https://github.com/Karaka-Management/phpOMS/issues/365
|
|
if ($language !== '') {
|
|
$mailL11n = $mail->getL11nByLanguage($language);
|
|
$mail->subject = $mailL11n->subject;
|
|
$mail->body = $mailL11n->body;
|
|
$mail->bodyAlt = $mailL11n->bodyAlt;
|
|
}
|
|
|
|
/** @var \Model\Setting[] $templateSettings */
|
|
$templateSettings = $this->app->appSettings->get(
|
|
names: [SettingsEnumMessages::HEADER_TEMPLATE, SettingsEnumMessages::FOOTER_TEMPLATE],
|
|
module: 'Messages',
|
|
unit: $this->app->unitId
|
|
);
|
|
|
|
if (empty($templateSettings)) {
|
|
/** @var \Model\Setting[] $templateSettings */
|
|
$templateSettings = $this->app->appSettings->get(
|
|
names: [SettingsEnumMessages::HEADER_TEMPLATE, SettingsEnumMessages::FOOTER_TEMPLATE],
|
|
module: 'Messages',
|
|
);
|
|
}
|
|
|
|
$headerTemplate = $mail = EmailMapper::get()
|
|
->with('l11n')
|
|
->where('id', (int) $templateSettings[SettingsEnumMessages::HEADER_TEMPLATE]->content)
|
|
->where('l11n/language', $language)
|
|
->execute();
|
|
|
|
$header = $headerTemplate->getL11nByLanguage($language);
|
|
|
|
$footerTemplate = $mail = EmailMapper::get()
|
|
->with('l11n')
|
|
->where('id', (int) $templateSettings[SettingsEnumMessages::HEADER_TEMPLATE]->content)
|
|
->where('l11n/language', $language)
|
|
->execute();
|
|
|
|
$footer = $footerTemplate->getL11nByLanguage($language);
|
|
|
|
$mail->template = \array_merge(
|
|
$mail->template,
|
|
[
|
|
'{header_template}' => $header->body,
|
|
'{header_template_alt}' => $header->bodyAlt,
|
|
'{footer_template}' => $footer->body,
|
|
'{footer_template_alt}' => $footer->bodyAlt,
|
|
]
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Api method to send forgotten password email
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiForgot(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var \Modules\Admin\Models\Account $account */
|
|
$account = $request->hasData('user')
|
|
? AccountMapper::get()->where('login', (string) $request->getData('user'))->execute()
|
|
: AccountMapper::get()->where('email', (string) $request->getData('email'))->execute();
|
|
|
|
/** @var \Model\Setting[] $forgotten */
|
|
$forgotten = $this->app->appSettings->get(
|
|
names: [SettingsEnum::LOGIN_FORGOTTEN_DATE, SettingsEnum::LOGIN_FORGOTTEN_COUNT],
|
|
module: 'Admin',
|
|
account: $account->id
|
|
);
|
|
|
|
if ((int) $forgotten[SettingsEnum::LOGIN_FORGOTTEN_COUNT]->content > 3) {
|
|
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
|
|
$response->set($request->uri->__toString(), [
|
|
'status' => NotificationLevel::ERROR,
|
|
'title' => $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'PasswordResetTitle'),
|
|
'message' => $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'PasswordResetMsg'),
|
|
'response' => null,
|
|
]);
|
|
}
|
|
|
|
$token = (string) \bin2hex(\random_bytes(32));
|
|
$handler = $this->setUpServerMailHandler();
|
|
$resetLink = UriFactory::build('{/base}/reset?user=' . $account->id . '&token=' . $token);
|
|
|
|
/** @var \Model\Setting[] $emailSettings */
|
|
$emailSettings = $this->app->appSettings->get(
|
|
names: [SettingsEnum::LOGIN_MAIL_FORGOT_PASSWORD_TEMPLATE],
|
|
module: 'Admin'
|
|
);
|
|
|
|
/** @var \Modules\Messages\Models\Email $mail */
|
|
$mail = EmailMapper::get()
|
|
->with('l11n')
|
|
->where('id', (int) $emailSettings[SettingsEnum::LOGIN_MAIL_FORGOT_PASSWORD_TEMPLATE]->content)
|
|
->where('l11n/language', $response->header->l11n->language)
|
|
->execute();
|
|
|
|
$status = false;
|
|
if ($mail->id !== 0) {
|
|
$status = $this->setupEmailDefaults($mail, $response->header->l11n->language);
|
|
}
|
|
|
|
$mail->addTo($account->email);
|
|
|
|
$mail->template = \array_merge(
|
|
$mail->template,
|
|
[
|
|
'{reset_link}' => $resetLink,
|
|
'{user_name}' => (string) $account->login,
|
|
]
|
|
);
|
|
|
|
if ($status) {
|
|
$status = $handler->send($mail);
|
|
}
|
|
|
|
if (!$status) {
|
|
\phpOMS\Log\FileLogger::getInstance()->error(
|
|
\phpOMS\Log\FileLogger::MSG_FULL, [
|
|
'message' => 'Couldn\'t send mail: ' . $mail->id,
|
|
'line' => __LINE__,
|
|
'file' => self::class,
|
|
]
|
|
);
|
|
}
|
|
|
|
$this->app->appSettings->set([
|
|
[
|
|
'name' => SettingsEnum::LOGIN_FORGOTTEN_DATE,
|
|
'module' => self::NAME,
|
|
'account' => $account->id,
|
|
'content' => (string) \time(),
|
|
],
|
|
[
|
|
'name' => SettingsEnum::LOGIN_FORGOTTEN_COUNT,
|
|
'module' => self::NAME,
|
|
'account' => $account->id,
|
|
'content' => (string) (((int) $forgotten[SettingsEnum::LOGIN_FORGOTTEN_COUNT]->content) + 1),
|
|
],
|
|
[
|
|
'name' => SettingsEnum::LOGIN_FORGOTTEN_TOKEN,
|
|
'module' => self::NAME,
|
|
'account' => $account->id,
|
|
'content' => $token,
|
|
],
|
|
], true);
|
|
|
|
/*
|
|
if (!empty($emailSettings[SettingsEnum::MAIL_SERVER_CERT]->content)
|
|
&& !empty($emailSettings[SettingsEnum::MAIL_SERVER_KEY]->content)
|
|
) {
|
|
$mail->sign(
|
|
$emailSettings[SettingsEnum::MAIL_SERVER_CERT]->content,
|
|
$emailSettings[SettingsEnum::MAIL_SERVER_KEY]->content,
|
|
$emailSettings[SettingsEnum::MAIL_SERVER_KEYPASS]->content
|
|
);
|
|
}
|
|
*/
|
|
|
|
// $handler->send($mail);
|
|
|
|
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
|
|
$response->set($request->uri->__toString(), [
|
|
'status' => NotificationLevel::OK,
|
|
'title' => $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'PasswordResetTitle'),
|
|
'message' => $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'PasswordResetEmailMsg'),
|
|
'response' => null,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Api method to reset the password
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiResetPassword(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var \Model\Setting[] $forgotten */
|
|
$forgotten = $this->app->appSettings->get(
|
|
names: [SettingsEnum::LOGIN_FORGOTTEN_DATE, SettingsEnum::LOGIN_FORGOTTEN_TOKEN],
|
|
module: self::NAME,
|
|
account: (int) $request->getData('user')
|
|
);
|
|
|
|
$date = new \DateTime($forgotten[SettingsEnum::LOGIN_FORGOTTEN_DATE]->content);
|
|
$token = $forgotten[SettingsEnum::LOGIN_FORGOTTEN_TOKEN]->content;
|
|
|
|
if ($date->getTimestamp() < \time() - 60 * 10
|
|
|| !$request->hasData('token')
|
|
|| $request->getData('token') !== $token
|
|
) {
|
|
$response->header->status = RequestStatusCode::R_405;
|
|
$response->set($request->uri->__toString(), [
|
|
'status' => NotificationLevel::OK,
|
|
'title' => $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'PasswordResetTitle'),
|
|
'message' => $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'PasswordResetInvalidMsg'),
|
|
'response' => null,
|
|
]);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\Account $account */
|
|
$account = AccountMapper::get()->where('id', (int) $request->getData('user'))->execute();
|
|
|
|
$account->generatePassword($pass = StringRng::generateString(10, 14, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+=/\\{}<>?'));
|
|
|
|
AccountMapper::update()->execute($account);
|
|
|
|
$handler = $this->setUpServerMailHandler();
|
|
|
|
/** @var \Model\Setting[] $emailSettings */
|
|
$emailSettings = $this->app->appSettings->get(
|
|
names: [SettingsEnum::LOGIN_MAIL_FORGOT_PASSWORD_TEMPLATE],
|
|
module: 'Admin'
|
|
);
|
|
|
|
/** @var \Modules\Messages\Models\Email $mail */
|
|
$mail = EmailMapper::get()
|
|
->with('l11n')
|
|
->where('id', (int) $emailSettings[SettingsEnum::LOGIN_MAIL_FORGOT_PASSWORD_TEMPLATE]->content)
|
|
->where('l11n/language', $response->header->l11n->language)
|
|
->execute();
|
|
|
|
$status = false;
|
|
if ($mail->id !== 0) {
|
|
$status = $this->setupEmailDefaults($mail, $response->header->l11n->language);
|
|
}
|
|
|
|
$mail->addTo($account->email);
|
|
|
|
$mail->template = \array_merge(
|
|
$mail->template,
|
|
[
|
|
'{new_password}' => $pass,
|
|
'{user_name}' => (string) $account->login,
|
|
]
|
|
);
|
|
|
|
$this->app->appSettings->set([
|
|
[
|
|
'name' => SettingsEnum::LOGIN_FORGOTTEN_COUNT,
|
|
'module' => self::NAME,
|
|
'account' => $account->id,
|
|
'content' => '0',
|
|
],
|
|
[
|
|
'name' => SettingsEnum::LOGIN_FORGOTTEN_TOKEN,
|
|
'module' => self::NAME,
|
|
'account' => $account->id,
|
|
'content' => '',
|
|
],
|
|
], true);
|
|
|
|
if (!empty($emailSettings[SettingsEnum::MAIL_SERVER_CERT]->content)
|
|
&& !empty($emailSettings[SettingsEnum::MAIL_SERVER_KEY]->content)
|
|
) {
|
|
$mail->sign(
|
|
$emailSettings[SettingsEnum::MAIL_SERVER_CERT]->content,
|
|
$emailSettings[SettingsEnum::MAIL_SERVER_KEY]->content,
|
|
$emailSettings[SettingsEnum::MAIL_SERVER_KEYPASS]->content
|
|
);
|
|
}
|
|
|
|
if ($status) {
|
|
$status = $handler->send($mail);
|
|
}
|
|
|
|
if (!$status) {
|
|
\phpOMS\Log\FileLogger::getInstance()->error(
|
|
\phpOMS\Log\FileLogger::MSG_FULL, [
|
|
'message' => 'Couldn\'t send mail: ' . $mail->id,
|
|
'line' => __LINE__,
|
|
'file' => self::class,
|
|
]
|
|
);
|
|
}
|
|
|
|
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
|
|
$response->set($request->uri->__toString(), [
|
|
'status' => NotificationLevel::OK,
|
|
'title' => 'Password Reset',
|
|
'message' => 'You received a new password.',
|
|
'response' => null,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Api method to get settings
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiSettingsGet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$response->set(
|
|
$request->uri->__toString(),
|
|
[
|
|
'response' => $this->app->appSettings->get(
|
|
$request->getDataInt('id'),
|
|
$request->getDataString('name'),
|
|
$request->getDataInt('unit'),
|
|
$request->getDataInt('app'),
|
|
$request->getDataString('module'),
|
|
$request->getDataInt('group'),
|
|
$request->getDataInt('account')
|
|
),
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Set app config
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAppConfigSet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$dataSettings = $request->getDataJson('settings');
|
|
|
|
$config = include __DIR__ . '/../../../config.php';
|
|
|
|
foreach ($dataSettings as $data) {
|
|
$config = ArrayUtils::setArray($data['path'], $config, $data['value'], '/', true);
|
|
}
|
|
|
|
\file_put_contents(__DIR__ . '/../../../config.php', "<?php\ndeclare(strict_types=1);\nreturn " . ArrayParser::serializeArray($config) . ';');
|
|
|
|
$this->createStandardUpdateResponse($request, $response, $dataSettings);
|
|
}
|
|
|
|
/**
|
|
* Api method for modifying settings
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiSettingsSet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$dataSettings = $request->getDataJson('settings');
|
|
if (empty($dataSettings)) {
|
|
$tmp = $request->getLike('settings_(.*)');
|
|
foreach ($tmp as $idx => $value) {
|
|
$name = \substr($idx, 9);
|
|
$dataSettings[$name] = [
|
|
'name' => $name,
|
|
'content' => $value,
|
|
'app' => $request->getDataInt('app'),
|
|
'unit' => $request->getDataInt('unit'),
|
|
];
|
|
}
|
|
}
|
|
|
|
foreach ($dataSettings as $data) {
|
|
$id = isset($data['id']) && !empty($data['id']) ? (int) $data['id'] : null;
|
|
$name = $data['name'] ?? null;
|
|
$content = $data['content'] ?? null;
|
|
$unit = $data['unit'] ?? null;
|
|
$app = $data['app'] ?? null;
|
|
$module = $data['module'] ?? null;
|
|
$pattern = $data['pattern'] ?? '';
|
|
$encrypted = $data['encrypted'] ?? 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);
|
|
if ($old === false || $old->id === 0) {
|
|
continue;
|
|
/*
|
|
// @todo There might be situations where we want to create the setting if it doesn't exist?!
|
|
// Maybe we should require a flag in the request in such a case?!
|
|
$internalResponse = new HttpResponse();
|
|
$internalRequest = new HttpRequest($request->uri);
|
|
|
|
$internalRequest->header->account = $request->header->account;
|
|
$internalRequest->setData('id', $id);
|
|
$internalRequest->setData('name', $name);
|
|
$internalRequest->setData('content', $content);
|
|
$internalRequest->setData('pattern', $pattern);
|
|
$internalRequest->setData('unit', $unit);
|
|
$internalRequest->setData('app', $app);
|
|
$internalRequest->setData('module', $module);
|
|
$internalRequest->setData('group', $group);
|
|
$internalRequest->setData('account', $account);
|
|
$internalRequest->setData('encrypted', $encrypted);
|
|
|
|
$this->apiSettingsCreate($internalRequest, $internalResponse, $data);
|
|
|
|
continue;
|
|
*/
|
|
}
|
|
|
|
$new = clone $old;
|
|
|
|
$new->name = $name ?? $new->name;
|
|
|
|
// @question Do we want to allow changes in encryption?!
|
|
$new->isEncrypted = $encrypted ?? $new->isEncrypted;
|
|
$new->content = $new->isEncrypted && !empty($content) && !empty($_SERVER['OMS_PRIVATE_KEY_I'] ?? '')
|
|
? EncryptionHelper::encryptShared($content, $_SERVER['OMS_PRIVATE_KEY_I'])
|
|
: ($content ?? $new->content);
|
|
$new->unit = $unit ?? $new->unit;
|
|
$new->app = $app ?? $new->app;
|
|
$new->module = $module ?? $new->module;
|
|
$new->group = $group ?? $new->group;
|
|
$new->account = $account ?? $new->account;
|
|
|
|
$this->app->appSettings->set([$new], false);
|
|
|
|
$this->updateModel($request->header->account, $old, $new, SettingMapper::class, 'settings', $request->getOrigin());
|
|
}
|
|
|
|
$this->createStandardUpdateResponse($request, $response, $dataSettings);
|
|
}
|
|
|
|
/**
|
|
* Api method for modifying settings
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiSettingsCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateSettingsCreate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$setting = $this->createSettingFromRequest($request);
|
|
$this->createModel($request->header->account, $setting, SettingMapper::class, 'setting', $request->getOrigin());
|
|
$this->createStandardCreateResponse($request, $response, $setting);
|
|
}
|
|
|
|
/**
|
|
* Validate password update request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateSettingsCreate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['name'] = !$request->hasData('name'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Method to create group from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return Setting
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function createSettingFromRequest(RequestAbstract $request) : Setting
|
|
{
|
|
return new Setting(
|
|
id: $request->getDataInt('id') ?? 0,
|
|
name: $request->getDataString('name') ?? '',
|
|
content: $request->getDataString('content') ?? '',
|
|
pattern: $request->getDataString('pattern') ?? '',
|
|
unit: $request->getDataInt('unit'),
|
|
app: $request->getDataInt('app'),
|
|
module: $request->getDataString('module'),
|
|
group: $request->getDataInt('group'),
|
|
account: $request->getDataInt('account'),
|
|
isEncrypted: $request->getDataBool('encrypted') ?? false
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Api method for modifying account password
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiSettingsAccountPasswordSet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
// has required data
|
|
if (!empty($val = $this->validatePasswordUpdate($request))) {
|
|
$response->data['password_update'] = new FormValidation($val);
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
return;
|
|
}
|
|
|
|
$requestAccount = $request->header->account;
|
|
|
|
// request account is valid
|
|
if ($requestAccount <= 0) {
|
|
$this->fillJsonResponse($request, $response, NotificationLevel::ERROR, '', 'Invalid account', []);
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var Account $account */
|
|
$account = AccountMapper::get()
|
|
->where('id', $requestAccount)
|
|
->execute();
|
|
|
|
// test old password is correct
|
|
if ($account->login === null
|
|
|| AccountMapper::login($account->login, (string) $request->getData('oldpass')) !== $requestAccount
|
|
) {
|
|
$this->fillJsonResponse($request, $response, NotificationLevel::ERROR, '', 'Invalid old password', []);
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
// test password repetition
|
|
if (((string) $request->getData('newpass')) !== ((string) $request->getData('reppass'))) {
|
|
$this->fillJsonResponse($request, $response, NotificationLevel::ERROR, '', 'Invalid password repetition', []);
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
// 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::ERROR, '', 'Invalid password complexity', []);
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
$account->generatePassword((string) $request->getData('newpass'));
|
|
|
|
AccountMapper::update()->execute($account);
|
|
|
|
$this->createStandardUpdateResponse($request, $response, $account);
|
|
}
|
|
|
|
/**
|
|
* Validate password update request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validatePasswordUpdate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['oldpass'] = !$request->hasData('oldpass'))
|
|
|| ($val['newpass'] = !$request->hasData('newpass'))
|
|
|| ($val['reppass'] = !$request->hasData('reppass'))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Validate password update request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateLocalizationUpdate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method for modifying account localization
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiSettingsAccountLocalizationSet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateLocalizationUpdate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidUpdateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\Account $account */
|
|
$account = AccountMapper::get()
|
|
->with('l11n')
|
|
->where('l11n/id', (int) $request->getData('id'))
|
|
->execute();
|
|
|
|
$requestAccount = $request->header->account;
|
|
if ($account->id !== 0
|
|
&& $requestAccount !== $account->id
|
|
&& !$this->app->accountManager->get($requestAccount)->hasPermission(
|
|
PermissionType::MODIFY,
|
|
$this->app->unitId,
|
|
$this->app->appId,
|
|
self::NAME,
|
|
PermissionCategory::ACCOUNT_SETTINGS,
|
|
$account->id
|
|
)
|
|
) {
|
|
$this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []);
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
if ($account->id === 0
|
|
&& !$this->app->accountManager->get($requestAccount)->hasPermission(
|
|
PermissionType::MODIFY,
|
|
$this->app->unitId,
|
|
$this->app->appId,
|
|
self::NAME,
|
|
PermissionCategory::SETTINGS
|
|
)
|
|
) {
|
|
$this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []);
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
if ($account->l11n->id === 0) {
|
|
$l11n = LocalizationMapper::get()
|
|
->where('id', (int) $request->getData('id'))
|
|
->execute();
|
|
} else {
|
|
$l11n = $account->l11n;
|
|
}
|
|
|
|
if (($request->getDataString('localization_load') ?? '-1') !== '-1') {
|
|
$locale = \explode('_', $request->getDataString('localization_load') ?? '');
|
|
$old = clone $l11n;
|
|
|
|
$l11n->loadFromLanguage($locale[0], $locale[1]);
|
|
|
|
$this->updateModel($request->header->account, $old, $l11n, LocalizationMapper::class, 'l11n', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $l11n);
|
|
|
|
return;
|
|
}
|
|
|
|
$old = clone $l11n;
|
|
|
|
$dataSettings = $request->getLike('settings_(.*)');
|
|
|
|
$l11n->setCountry($dataSettings['settings_country'] ?? $l11n->country);
|
|
$l11n->language = $dataSettings['settings_language'] ?? $l11n->language;
|
|
$l11n->setTemperature($dataSettings['settings_temperature'] ?? $l11n->temperature);
|
|
|
|
$l11n->setTimezone($dataSettings['settings_timezone'] ?? $l11n->timezone);
|
|
|
|
if (isset($dataSettings['settings_timeformat_vs'])) {
|
|
$l11n->setDatetime(
|
|
[
|
|
'very_short' => $dataSettings['settings_timeformat_vs'],
|
|
'short' => $dataSettings['settings_timeformat_s'],
|
|
'medium' => $dataSettings['settings_timeformat_m'],
|
|
'long' => $dataSettings['settings_timeformat_l'],
|
|
'very_long' => $dataSettings['settings_timeformat_vl'],
|
|
]
|
|
);
|
|
}
|
|
|
|
$l11n->currency = $dataSettings['settings_currency'] ?? $l11n->currency;
|
|
$l11n->setCurrencyFormat($dataSettings['settings_currencyformat'] ?? $l11n->currencyFormat);
|
|
|
|
$l11n->setDecimal($dataSettings['settings_decimal'] ?? $l11n->decimal);
|
|
$l11n->setThousands($dataSettings['settings_thousands'] ?? $l11n->thousands);
|
|
|
|
if (isset($dataSettings['settings_precision_vs'])) {
|
|
$l11n->setPrecision(
|
|
[
|
|
'very_short' => $dataSettings['settings_precision_vs'],
|
|
'short' => $dataSettings['settings_precision_s'],
|
|
'medium' => $dataSettings['settings_precision_m'],
|
|
'long' => $dataSettings['settings_precision_l'],
|
|
'very_long' => $dataSettings['settings_precision_vl'],
|
|
]
|
|
);
|
|
}
|
|
|
|
if (isset($dataSettings['settings_weight_vl'])) {
|
|
$l11n->setWeight(
|
|
[
|
|
'very_light' => $dataSettings['settings_weight_vl'],
|
|
'light' => $dataSettings['settings_weight_l'],
|
|
'medium' => $dataSettings['settings_weight_m'],
|
|
'heavy' => $dataSettings['settings_weight_h'],
|
|
'very_heavy' => $dataSettings['settings_weight_vh'],
|
|
]
|
|
);
|
|
}
|
|
|
|
if (isset($dataSettings['settings_speed_vs'])) {
|
|
$l11n->setSpeed(
|
|
[
|
|
'very_slow' => $dataSettings['settings_speed_vs'],
|
|
'slow' => $dataSettings['settings_speed_s'],
|
|
'medium' => $dataSettings['settings_speed_m'],
|
|
'fast' => $dataSettings['settings_speed_f'],
|
|
'very_fast' => $dataSettings['settings_speed_vf'],
|
|
'sea' => $dataSettings['settings_speed_sea'],
|
|
]
|
|
);
|
|
}
|
|
|
|
if (isset($dataSettings['settings_length_vs'])) {
|
|
$l11n->setLength(
|
|
[
|
|
'very_short' => $dataSettings['settings_length_vs'],
|
|
'short' => $dataSettings['settings_length_s'],
|
|
'medium' => $dataSettings['settings_length_m'],
|
|
'long' => $dataSettings['settings_length_l'],
|
|
'very_long' => $dataSettings['settings_length_vl'],
|
|
'sea' => $dataSettings['settings_length_sea'],
|
|
]
|
|
);
|
|
}
|
|
|
|
if (isset($dataSettings['settings_area_vs'])) {
|
|
$l11n->setArea(
|
|
[
|
|
'very_small' => $dataSettings['settings_area_vs'],
|
|
'small' => $dataSettings['settings_area_s'],
|
|
'medium' => $dataSettings['settings_area_m'],
|
|
'large' => $dataSettings['settings_area_l'],
|
|
'very_large' => $dataSettings['settings_area_vl'],
|
|
]
|
|
);
|
|
}
|
|
|
|
if (isset($dataSettings['settings_volume_vs'])) {
|
|
$l11n->setVolume(
|
|
[
|
|
'very_small' => $dataSettings['settings_volume_vs'],
|
|
'small' => $dataSettings['settings_volume_s'],
|
|
'medium' => $dataSettings['settings_volume_m'],
|
|
'large' => $dataSettings['settings_volume_l'],
|
|
'very_large' => $dataSettings['settings_volume_vl'],
|
|
'tablespoon' => $dataSettings['settings_volume_tablespoon'],
|
|
'teaspoon' => $dataSettings['settings_volume_teaspoon'],
|
|
'glass' => $dataSettings['settings_volume_glass'],
|
|
]
|
|
);
|
|
}
|
|
|
|
$this->updateModel($request->header->account, $old, $l11n, LocalizationMapper::class, 'l11n', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $l11n);
|
|
}
|
|
|
|
/**
|
|
* Routing end-point for application behavior.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @todo This should happen in the CMS module since we are modifying a CMS app
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiSettingsDesignSet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (empty($request->files)) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
$this->createInvalidUpdateResponse($request, $response, []);
|
|
return;
|
|
}
|
|
|
|
$upload = new UploadFile();
|
|
$upload->preserveFileName = false;
|
|
$upload->outputDir = __DIR__ . '/../../../Web/Backend/img';
|
|
|
|
$status = $upload->upload($request->files, ['logo.png'], true);
|
|
if ($status[0]['status'] !== \Modules\Media\Models\UploadStatus::OK) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
$this->createInvalidUpdateResponse($request, $response, []);
|
|
return;
|
|
}
|
|
|
|
$this->createStandardUpdateResponse($request, $response, []);
|
|
}
|
|
|
|
/**
|
|
* Api method to install a application
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiApplicationCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateApplicationCreate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$app = $this->createApplicationFromRequest($request);
|
|
$this->createModel($request->header->account, $app, AppMapper::class, 'application', $request->getOrigin());
|
|
|
|
$this->createDefaultAppSettings($app, $request);
|
|
|
|
/** @var \Model\Setting $setting */
|
|
$setting = $this->app->appSettings->get(null, SettingsEnum::GROUP_GENERATE_AUTOMATICALLY_APP);
|
|
if ($setting->content === '1') {
|
|
$newRequest = new HttpRequest();
|
|
$newRequest->header->account = $request->header->account;
|
|
$newRequest->setData('name', 'app:' . \strtolower($app->name));
|
|
$newRequest->setData('status', GroupStatus::ACTIVE);
|
|
$this->apiGroupCreate($newRequest, $response, $data);
|
|
}
|
|
|
|
$this->createStandardCreateResponse($request, $response, $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 = [];
|
|
$settings[] = new Setting(0, SettingsEnum::REGISTRATION_ALLOWED, '0', '\\d+', app: $app->id, module: 'Admin');
|
|
$settings[] = new Setting(0, SettingsEnum::APP_DEFAULT_GROUPS, '[]', app: $app->id, module: 'Admin');
|
|
|
|
foreach ($settings as $setting) {
|
|
$this->createModel($request->header->account, $setting, SettingMapper::class, 'setting', $request->getOrigin());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate app create request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateApplicationCreate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['name'] = !$request->hasData('name'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Method to create task from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return App Returns the created application from the request
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function createApplicationFromRequest(RequestAbstract $request) : App
|
|
{
|
|
$app = new App();
|
|
$app->name = $request->getDataString('name') ?? '';
|
|
$app->type = ApplicationType::tryFromValue($request->getDataInt('type')) ?? ApplicationType::WEB;
|
|
$app->defaultUnit = $request->getDataInt('default_unit');
|
|
|
|
return $app;
|
|
}
|
|
|
|
/**
|
|
* Api method to install a application
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiInstallApplication(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$appManager = new ApplicationManager($this->app);
|
|
|
|
$app = \rtrim($request->getDataString('appSrc') ?? '', '/\\ ');
|
|
if (!\is_dir(__DIR__ . '/../../../' . $app)) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
return;
|
|
}
|
|
|
|
$appInfo = new ApplicationInfo(__DIR__ . '/../../../' . $app . '/info.json');
|
|
$appInfo->load();
|
|
|
|
// handle dependencies
|
|
$dependencies = $appInfo->getDependencies();
|
|
$installed = $this->app->moduleManager->getInstalledModules();
|
|
|
|
foreach ($dependencies as $key => $version) {
|
|
if (!isset($installed[$key])) {
|
|
$this->app->moduleManager->install($key);
|
|
}
|
|
}
|
|
|
|
// handle app installation
|
|
$result = $appManager->install(
|
|
__DIR__ . '/../../../' . $app,
|
|
__DIR__ . '/../../../' . ($request->getDataString('appDest') ?? ''),
|
|
$request->getDataString('theme') ?? 'Default'
|
|
);
|
|
|
|
// handle providing
|
|
if ($result) {
|
|
$providing = $appInfo->getProviding();
|
|
|
|
foreach ($providing as $key => $version) {
|
|
if (isset($installed[$key])) {
|
|
$this->app->moduleManager->installProviding($app, $key);
|
|
}
|
|
}
|
|
}
|
|
|
|
// handle Routes of already installed modules
|
|
foreach ($installed as $module => $_) {
|
|
$class = '\Modules\\' . $module . '\Admin\Status';
|
|
|
|
$moduleInfo = new ModuleInfo(__DIR__ . '/../../../Modules/' . $module . '/info.json');
|
|
$moduleInfo->load();
|
|
|
|
$class::activateRoutes($moduleInfo, $appInfo);
|
|
$class::activateHooks($moduleInfo, $appInfo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Api method to get a group
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiGroupGet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var \Modules\Admin\Models\Group $group */
|
|
$group = GroupMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->createStandardReturnResponse($request, $response, $group);
|
|
}
|
|
|
|
/**
|
|
* Api method for modifying a group
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiGroupUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var \Modules\Admin\Models\Group $old */
|
|
$old = GroupMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$new = $this->updateGroupFromRequest($request, clone $old);
|
|
|
|
$this->updateModel($request->header->account, $old, $new, GroupMapper::class, 'group', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $new);
|
|
}
|
|
|
|
/**
|
|
* Method to update group from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return Group
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function updateGroupFromRequest(RequestAbstract $request, Group $group) : Group
|
|
{
|
|
$group->name = $request->getDataString('name') ?? $group->name;
|
|
$group->status = GroupStatus::tryFromValue($request->getDataInt('status')) ?? $group->status;
|
|
$group->description = Markdown::parse($request->getDataString('description') ?? $group->descriptionRaw);
|
|
$group->descriptionRaw = $request->getDataString('description') ?? $group->descriptionRaw;
|
|
|
|
return $group;
|
|
}
|
|
|
|
/**
|
|
* Validate group create request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateGroupCreate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['name'] = !$request->hasData('name'))
|
|
|| ($val['status'] = !GroupStatus::isValidValue((int) $request->getData('status')))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to create a group
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiGroupCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateGroupCreate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$group = $this->createGroupFromRequest($request);
|
|
$this->createModel($request->header->account, $group, GroupMapper::class, 'group', $request->getOrigin());
|
|
$this->createStandardCreateResponse($request, $response, $group);
|
|
}
|
|
|
|
/**
|
|
* Method to create group from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return Group
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function createGroupFromRequest(RequestAbstract $request) : Group
|
|
{
|
|
$group = new Group();
|
|
$group->createdBy = new NullAccount($request->header->account);
|
|
$group->name = $request->getDataString('name') ?? '';
|
|
$group->status = GroupStatus::tryFromValue($request->getDataInt('status')) ?? GroupStatus::INACTIVE;
|
|
$group->description = Markdown::parse($request->getDataString('description') ?? '');
|
|
$group->descriptionRaw = $request->getDataString('description') ?? '';
|
|
|
|
return $group;
|
|
}
|
|
|
|
/**
|
|
* Api method to delete a group
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiGroupDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateGroupDelete($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidDeleteResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
if (((int) $request->getData('id')) === 3) {
|
|
// admin group cannot be deleted
|
|
$this->createInvalidDeleteResponse($request, $response, []);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\Group $group */
|
|
$group = GroupMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->deleteModel($request->header->account, $group, GroupMapper::class, 'group', $request->getOrigin());
|
|
$this->createStandardDeleteResponse($request, $response, $group);
|
|
}
|
|
|
|
/**
|
|
* Validate Group delete request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateGroupDelete(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to find groups
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiGroupFind(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var \Modules\Admin\Models\Group[] $groups */
|
|
$groups = GroupMapper::getAll()
|
|
->where('name', '%' . ($request->getDataString('group') ?? '') . '%', 'LIKE')
|
|
->limit($request->getDataInt('limit') ?? 50)
|
|
->executeGetArray();
|
|
|
|
$response->header->set('Content-Type', MimeType::M_JSON, true);
|
|
$response->set(
|
|
$request->uri->__toString(),
|
|
\array_values($groups)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Api method to get an account
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountGet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var Account $account */
|
|
$account = AccountMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->createStandardReturnResponse($request, $response, $account);
|
|
}
|
|
|
|
/**
|
|
* Api method to find accounts
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountFind(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$fullName = $request->getDataString('search') ?? '';
|
|
$names = \explode(' ', $fullName);
|
|
|
|
$limit = $request->getDataInt('limit') ?? 50;
|
|
|
|
/** @var \Modules\Admin\Models\Account[] $accounts */
|
|
$accounts = AccountMapper::getAll()
|
|
->where('login', '%' . $fullName . '%', 'LIKE')
|
|
->where('email', '%' . $fullName . '%', 'LIKE', 'OR')
|
|
->where('name1', '%' . $fullName . '%', 'LIKE', 'OR')
|
|
->where('name2', '%' . $fullName . '%', 'LIKE', 'OR')
|
|
->where('name3', '%' . $fullName . '%', 'LIKE', 'OR')
|
|
->limit($limit)
|
|
->executeGetArray();
|
|
|
|
if (($count = \count($accounts)) < $limit) {
|
|
$mapper = AccountMapper::getAll();
|
|
foreach ($names as $name) {
|
|
$mapper->where('login', '%' . $name . '%', 'LIKE', 'OR')
|
|
->where('email', '%' . $name . '%', 'LIKE', 'OR')
|
|
->where('name1', '%' . $name . '%', 'LIKE', 'OR')
|
|
->where('name2', '%' . $name . '%', 'LIKE', 'OR')
|
|
->where('name3', '%' . $name . '%', 'LIKE', 'OR');
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\Account[] $parts */
|
|
$parts = $mapper->limit($limit - $count)
|
|
->executeGetArray();
|
|
|
|
$accounts += $parts;
|
|
}
|
|
|
|
$response->header->set('Content-Type', MimeType::M_JSON, true);
|
|
$response->set(
|
|
$request->uri->__toString(),
|
|
\array_values($accounts)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Api method to find accounts and or groups
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountGroupFind(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var Account[] $accounts */
|
|
$accounts = AccountMapper::getAll()
|
|
->where('login', '%' . ($request->getDataString('search') ?? '') . '%', 'LIKE')
|
|
->where('email', '%' . ($request->getDataString('search') ?? '') . '%', 'LIKE', 'OR')
|
|
->where('name1', '%' . ($request->getDataString('search') ?? '') . '%', 'LIKE', 'OR')
|
|
->where('name2', '%' . ($request->getDataString('search') ?? '') . '%', 'LIKE', 'OR')
|
|
->where('name3', '%' . ($request->getDataString('search') ?? '') . '%', 'LIKE', 'OR')
|
|
->executeGetArray();
|
|
|
|
$data = [];
|
|
|
|
foreach ($accounts as $account) {
|
|
/** @var array $temp */
|
|
$temp = $account->jsonSerialize();
|
|
$temp['type_prefix'] = 'a';
|
|
$temp['type_name'] = 'Account';
|
|
|
|
$data[] = $temp;
|
|
}
|
|
|
|
/** @var Group[] $groups */
|
|
$groups = GroupMapper::getAll()
|
|
->where('name', '%' . ($request->getDataString('search') ?? '') . '%', 'LIKE')
|
|
->executeGetArray();
|
|
|
|
foreach ($groups as $group) {
|
|
/** @var array $temp */
|
|
$temp = $group->jsonSerialize();
|
|
$temp['name'] = [$temp['name']];
|
|
$temp['email'] = '---';
|
|
$temp['type_prefix'] = 'g';
|
|
$temp['type_name'] = 'Group';
|
|
|
|
$data[] = $temp;
|
|
}
|
|
|
|
$response->header->set('Content-Type', MimeType::M_JSON, true);
|
|
$response->set($request->uri->__toString(), $data);
|
|
}
|
|
|
|
/**
|
|
* Method to validate account creation from request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateAccountCreate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['user'] = !$request->hasData('user'))
|
|
|| ($val['name1'] = !$request->hasData('name1'))
|
|
|| ($val['type'] = !AccountType::isValidValue((int) $request->getData('type')))
|
|
|| ($val['status'] = !AccountStatus::isValidValue((int) $request->getData('status')))
|
|
|| ($val['email'] = $request->hasData('email') && !EmailValidator::isValid((string) $request->getData('email')))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to create an account
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateAccountCreate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$account = $this->createAccountFromRequest($request);
|
|
$this->createModel($request->header->account, $account, AccountCredentialMapper::class, 'account', $request->getOrigin());
|
|
|
|
if ($request->hasData('create_profile')) {
|
|
$this->createProfileForAccount($account, $request);
|
|
}
|
|
|
|
$collection = $this->createMediaDirForAccount($account->id, $account->login ?? '', $request->header->account);
|
|
$this->createModel($request->header->account, $collection, CollectionMapper::class, 'collection', $request->getOrigin());
|
|
|
|
// find default groups and create them
|
|
$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'
|
|
);
|
|
|
|
if (!empty($defaultGroupSettings)) {
|
|
$temp = \json_decode($defaultGroupSettings->content, true);
|
|
if (!\is_array($temp)) {
|
|
$temp = [];
|
|
}
|
|
|
|
$defaultGroupIds = \array_merge($defaultGroupIds, $temp);
|
|
}
|
|
}
|
|
|
|
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'
|
|
);
|
|
|
|
if (!empty($defaultGroupSettings)) {
|
|
$temp = \json_decode($defaultGroupSettings->content, true);
|
|
if (!\is_array($temp)) {
|
|
$temp = [];
|
|
}
|
|
|
|
$defaultGroupIds = \array_merge($defaultGroupIds, $temp);
|
|
}
|
|
}
|
|
|
|
if (!empty($defaultGroupIds)) {
|
|
$this->createModelRelation(
|
|
$account->id,
|
|
$account->id,
|
|
$defaultGroupIds,
|
|
AccountMapper::class,
|
|
'groups',
|
|
'account',
|
|
$request->getOrigin()
|
|
);
|
|
}
|
|
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::OK,
|
|
'',
|
|
\str_replace(
|
|
'{url}',
|
|
UriFactory::build('{/base}/admin/account/view?{?}&id=' . $account->id),
|
|
$this->app->l11nManager->getText($response->header->l11n->language, '0', '0', 'SuccessfulCreate'
|
|
)),
|
|
$account
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Api method to register an account
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountRegister(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if ($request->header->account === 0) {
|
|
$request->header->account = 1;
|
|
}
|
|
|
|
if (!empty($val = $this->validateRegistration($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::ERROR,
|
|
'',
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'FormDataInvalid'),
|
|
$val
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\App */
|
|
$app = AppMapper::get()
|
|
->where('id', (int) $request->getData('app'))
|
|
->execute();
|
|
|
|
/** @var \Model\Setting $allowed */
|
|
$allowed = $this->app->appSettings->get(
|
|
names: SettingsEnum::REGISTRATION_ALLOWED,
|
|
app: (int) $request->getData('app'),
|
|
module: 'Admin'
|
|
);
|
|
|
|
if ($allowed->content !== '1') {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::ERROR,
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationTitle'),
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationNotAllowed'),
|
|
[]
|
|
);
|
|
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
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
|
|
) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::ERROR,
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationTitle'),
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationInvalidPasswordFormat'),
|
|
[]
|
|
);
|
|
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
// Check if account already exists
|
|
/** @var Account $emailAccount */
|
|
$emailAccount = AccountMapper::get()
|
|
->where('email', (string) $request->getData('email'))
|
|
->execute();
|
|
|
|
/** @var Account $loginAccount */
|
|
$loginAccount = AccountMapper::get()
|
|
->where('login', (string) ($request->getData('user') ?? $request->getData('email')))
|
|
->execute();
|
|
|
|
/** @var null|Account $account */
|
|
$account = null;
|
|
|
|
// email already in use
|
|
if ($emailAccount->id > 0
|
|
&& $emailAccount->login !== null
|
|
&& AccountMapper::login($emailAccount->login, (string) $request->getData('password')) !== LoginReturnType::OK
|
|
) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::OK,
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationTitle'),
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationEmailInUse'),
|
|
[]
|
|
);
|
|
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
return;
|
|
} elseif ($emailAccount->id > 0) {
|
|
$account = $emailAccount;
|
|
}
|
|
|
|
// login already in use by different email
|
|
if ($account === null
|
|
&& $loginAccount->id > 0
|
|
&& $loginAccount->getEmail() !== $request->getData('email')
|
|
) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::ERROR,
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationTitle'),
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationLoginInUse'),
|
|
[]
|
|
);
|
|
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
return;
|
|
} elseif ($account === null
|
|
&& $loginAccount->id > 0
|
|
&& $loginAccount->login !== null
|
|
&& AccountMapper::login($loginAccount->login, (string) $request->getData('password')) !== LoginReturnType::OK
|
|
) {
|
|
$account = $loginAccount;
|
|
}
|
|
|
|
// Already registered
|
|
if ($account !== null) {
|
|
/** @var Account $account */
|
|
$account = AccountMapper::get()
|
|
->with('groups')
|
|
->where('id', $account->id)
|
|
->execute();
|
|
|
|
$defaultGroupIds = [];
|
|
|
|
if ($request->hasData('app')) {
|
|
/** @var \Model\Setting $defaultGroupSettings */
|
|
$defaultGroupSettings = $this->app->appSettings->get(
|
|
names: SettingsEnum::APP_DEFAULT_GROUPS,
|
|
app: (int) $request->getDataInt('app'),
|
|
module: 'Admin'
|
|
);
|
|
|
|
if (!empty($defaultGroupSettings)) {
|
|
$temp = \json_decode($defaultGroupSettings->content, true);
|
|
if (!\is_array($temp)) {
|
|
$temp = [];
|
|
}
|
|
|
|
$defaultGroupIds = \array_merge(
|
|
$defaultGroupIds,
|
|
$temp
|
|
);
|
|
}
|
|
}
|
|
|
|
if ($request->hasData('unit')) {
|
|
/** @var \Model\Setting $defaultGroupSettings */
|
|
$defaultGroupSettings = $this->app->appSettings->get(
|
|
names: SettingsEnum::UNIT_DEFAULT_GROUPS,
|
|
app: (int) $request->getDataInt('unit'),
|
|
module: 'Admin'
|
|
);
|
|
|
|
if (!empty($defaultGroupSettings)) {
|
|
$temp = \json_decode($defaultGroupSettings->content, true);
|
|
if (!\is_array($temp)) {
|
|
$temp = [];
|
|
}
|
|
|
|
$defaultGroupIds = \array_merge(
|
|
$defaultGroupIds,
|
|
$temp
|
|
);
|
|
}
|
|
}
|
|
|
|
foreach ($defaultGroupIds as $index => $id) {
|
|
if ($account->hasGroup($id)) {
|
|
unset($defaultGroupIds[$index]);
|
|
}
|
|
}
|
|
|
|
if (empty($defaultGroupIds)
|
|
&& $account->status === AccountStatus::INACTIVE
|
|
) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
// Account not active
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::ERROR,
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationTitle'),
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationNotActivated'),
|
|
[]
|
|
);
|
|
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
if (!empty($defaultGroupIds)) {
|
|
// Create missing account / group relationships
|
|
$this->createModelRelation(
|
|
$account->id,
|
|
$account->id,
|
|
$defaultGroupIds,
|
|
AccountMapper::class,
|
|
'groups',
|
|
'registration',
|
|
$request->getOrigin()
|
|
);
|
|
}
|
|
} else {
|
|
// New account
|
|
$request->setData('status', AccountStatus::INACTIVE, true);
|
|
$request->setData('type', AccountType::USER, true);
|
|
$request->setData('create_profile', (string) true);
|
|
$request->setData('name1', $request->hasData('name1')
|
|
? ($request->getDataString('name1')
|
|
)
|
|
: ($request->hasData('user')
|
|
? $request->getDataString('user')
|
|
: \explode('@', $request->getDataString('email') ?? '')[0])
|
|
, true);
|
|
|
|
$request->setData('user', $request->hasData('user')
|
|
? $request->getDataString('user')
|
|
: $request->getDataString('email')
|
|
, true);
|
|
|
|
$this->apiAccountCreate($request, $response, $data);
|
|
|
|
/** @var Account $account */
|
|
$account = $response->getDataArray($request->uri->__toString())['response'] ?? null;
|
|
|
|
if ($account === null) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidUpdateResponse($request, $response, $account);
|
|
|
|
return;
|
|
}
|
|
|
|
// Create confirmation pending entry
|
|
$dataChange = new DataChange();
|
|
$dataChange->type = 'account';
|
|
$dataChange->createdBy = $account->id;
|
|
$dataChange->data = '{"status": ' . AccountStatus::ACTIVE . '}';
|
|
|
|
$tries = 0;
|
|
do {
|
|
$dataChange->reHash();
|
|
$this->createModel($account->id, $dataChange, DataChangeMapper::class, 'datachange', $request->getOrigin());
|
|
|
|
++$tries;
|
|
} while ($dataChange->id === 0 && $tries < 5);
|
|
|
|
$handler = $this->setUpServerMailHandler();
|
|
|
|
/** @var \Model\Setting[] $emailSettings */
|
|
$emailSettings = $this->app->appSettings->get(
|
|
names: [SettingsEnum::LOGIN_MAIL_REGISTRATION_TEMPLATE],
|
|
module: 'Admin'
|
|
);
|
|
|
|
/** @var \Modules\Messages\Models\Email $mail */
|
|
$mail = EmailMapper::get()
|
|
->with('l11n')
|
|
->where('id', (int) $emailSettings[SettingsEnum::LOGIN_MAIL_REGISTRATION_TEMPLATE]->content)
|
|
->where('l11n/language', $response->header->l11n->language)
|
|
->execute();
|
|
|
|
$status = false;
|
|
if ($mail->id !== 0) {
|
|
$status = $this->setupEmailDefaults($mail, $response->header->l11n->language);
|
|
}
|
|
|
|
$mail->addTo((string) $request->getData('email'));
|
|
|
|
$mail->template = \array_merge(
|
|
$mail->template,
|
|
[
|
|
'{confirmation_link}' => UriFactory::hasQuery('/' . \strtolower($app->name))
|
|
? UriFactory::build('{/' . \strtolower($app->name) . '}/' . \strtolower($app->name) . '/signup/confirmation?hash=' . $dataChange->getHash())
|
|
: UriFactory::build('{/tld}/{/lang}/' . \strtolower($app->name) . '/signup/confirmation?hash=' . $dataChange->getHash()),
|
|
'{user_name}' => (string) $account->login,
|
|
]
|
|
);
|
|
|
|
if ($status) {
|
|
$status = $handler->send($mail);
|
|
}
|
|
|
|
if (!$status) {
|
|
\phpOMS\Log\FileLogger::getInstance()->error(
|
|
\phpOMS\Log\FileLogger::MSG_FULL, [
|
|
'message' => 'Couldn\'t send mail: ' . $mail->id,
|
|
'line' => __LINE__,
|
|
'file' => self::class,
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
// Create client
|
|
if ($request->hasData('client')) {
|
|
$client = $this->app->moduleManager->get('ClientManagement', 'Api')
|
|
->findClientForAccount($account->id, $request->getDataInt('unit'));
|
|
|
|
if ($client === null) {
|
|
$internalRequest = new HttpRequest();
|
|
$internalResponse = new HttpResponse();
|
|
|
|
$internalRequest->header->account = $account->id;
|
|
$internalRequest->setData('account', $account->id);
|
|
$internalRequest->setData('number', 100000 + $account->id);
|
|
$internalRequest->setData('address', $request->getDataString('address') ?? '');
|
|
$internalRequest->setData('postal', $request->getDataString('postal') ?? '');
|
|
$internalRequest->setData('city', $request->getDataString('city') ?? '');
|
|
$internalRequest->setData('country', $request->getDataString('country'));
|
|
$internalRequest->setData('state', $request->getDataString('state') ?? '');
|
|
$internalRequest->setData('vat_id', $request->getDataString('vat_id') ?? '');
|
|
$internalRequest->setData('unit', $request->getDataInt('unit'));
|
|
|
|
$this->app->moduleManager->get('ClientManagement', 'Api')->apiClientCreate($internalRequest, $internalResponse);
|
|
}
|
|
}
|
|
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::OK,
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationTitle'),
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'RegistrationSuccessful'),
|
|
$account
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Method to validate account registration from request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateRegistration(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['email'] = $request->hasData('email')
|
|
&& !EmailValidator::isValid((string) $request->getData('email')))
|
|
|| ($val['unit'] = !$request->hasData('unit'))
|
|
|| ($val['app'] = !$request->hasData('app'))
|
|
|| ($val['password'] = !$request->hasData('password'))
|
|
|| ($val['terms'] = (($request->getDataBool('terms_required') ?? false) && !($request->getDataBool('terms') ?? false)))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to perform a pending model change
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @question Consider to re-implement the apiDataChange function as workflow
|
|
* https://github.com/Karaka-Management/oms-Admin/issues/31
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiDataChange(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateDataChange($request))) {
|
|
$response->data['data_change'] = new FormValidation($val);
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var DataChange $dataChange */
|
|
$dataChange = DataChangeMapper::get()->where('hash', (string) $request->getData('hash'))->execute();
|
|
if ($dataChange->id === 0) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($dataChange->type) {
|
|
case 'account':
|
|
/** @var Account $old */
|
|
$old = AccountMapper::get()->where('id', $dataChange->createdBy)->execute();
|
|
$new = clone $old;
|
|
|
|
$data = \json_decode($dataChange->data, true);
|
|
if (!\is_array($data)) {
|
|
break;
|
|
}
|
|
|
|
$new->status = AccountStatus::tryFromValue((int) ($data['status'] ?? AccountStatus::INACTIVE)) ?? AccountStatus::INACTIVE;
|
|
|
|
$this->updateModel($dataChange->createdBy, $old, $new, AccountMapper::class, 'datachange', $request->getOrigin());
|
|
$this->deleteModel($dataChange->createdBy, $dataChange, DataChangeMapper::class, 'datachange', $request->getOrigin());
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method to validate account registration from request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateDataChange(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['hash'] = !$request->hasData('hash'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Create directory for an account
|
|
*
|
|
* @param int $id Account id
|
|
* @param string $name Name of the directory/account
|
|
* @param int $createdBy Creator of the directory
|
|
*
|
|
* @return Collection
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function createMediaDirForAccount(int $id, string $name, int $createdBy) : Collection
|
|
{
|
|
$collection = new Collection();
|
|
$collection->name = ((string) $id) . ' ' . $name;
|
|
$collection->setVirtualPath('/Accounts');
|
|
$collection->setPath('/Modules/Media/Files/Accounts/' . ((string) $id));
|
|
$collection->createdBy = new NullAccount($createdBy);
|
|
|
|
return $collection;
|
|
}
|
|
|
|
/**
|
|
* Create profile for account
|
|
*
|
|
* @param Account $account Account to create profile for
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function createProfileForAccount(Account $account, RequestAbstract $request) : void
|
|
{
|
|
$request->setData('iaccount-idlist', $account->id);
|
|
|
|
$internalResponse = new HttpResponse();
|
|
|
|
$this->app->moduleManager->get('Profile', 'Api')->apiProfileCreate($request, $internalResponse);
|
|
}
|
|
|
|
/**
|
|
* Method to create an account from a request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return Account
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function createAccountFromRequest(RequestAbstract $request) : Account
|
|
{
|
|
$account = new Account();
|
|
$account->login = $request->getDataString('user') ?? '';
|
|
$account->name1 = $request->getDataString('name1') ?? '';
|
|
$account->name2 = $request->getDataString('name2') ?? '';
|
|
$account->name3 = $request->getDataString('name3') ?? '';
|
|
$account->status = AccountStatus::tryFromValue($request->getDataInt('status')) ?? AccountStatus::INACTIVE;
|
|
$account->type = AccountType::tryFromValue($request->getDataInt('type')) ?? AccountType::USER;
|
|
$account->setEmail($request->getDataString('email') ?? '');
|
|
$account->generatePassword($request->getDataString('password') ?? '');
|
|
|
|
if (!$request->hasData('locale')) {
|
|
$account->l11n = Localization::fromJson(
|
|
$this->app->l11nServer === null
|
|
? $request->header->l11n->toArray()
|
|
: $this->app->l11nServer->toArray()
|
|
);
|
|
} else {
|
|
$locale = \explode('_', $request->getDataString('locale') ?? '');
|
|
|
|
$account->l11n
|
|
->loadFromLanguage(
|
|
$locale[0] ?? $this->app->l11nServer->language,
|
|
$locale[1] ?? $this->app->l11nServer->country
|
|
);
|
|
}
|
|
|
|
return $account;
|
|
}
|
|
|
|
/**
|
|
* Api method to delete an account
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var Account $account */
|
|
$account = AccountMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->deleteModel($request->header->account, $account, AccountMapper::class, 'account', $request->getOrigin());
|
|
$this->createStandardDeleteResponse($request, $response, $account);
|
|
}
|
|
|
|
/**
|
|
* Api method to update an account
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var Account $old */
|
|
$old = AccountMapper::get()
|
|
->where('id', (int) $request->getData('id'))
|
|
->execute();
|
|
|
|
$new = $this->updateAccountFromRequest($request, clone $old);
|
|
$this->updateModel($request->header->account, $old, $new, AccountMapper::class, 'account', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $new);
|
|
}
|
|
|
|
/**
|
|
* Method to update an account from a request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param Account $account Account
|
|
* @param bool $allowPassword Allow to change password
|
|
*
|
|
* @return Account
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function updateAccountFromRequest(RequestAbstract $request, Account $account, bool $allowPassword = false) : Account
|
|
{
|
|
$account->login = $request->getDataString('user') ?? $account->login;
|
|
$account->name1 = $request->getDataString('name1') ?? $account->name1;
|
|
$account->name2 = $request->getDataString('name2') ?? $account->name2;
|
|
$account->name3 = $request->getDataString('name3') ?? $account->name3;
|
|
$account->setEmail($request->getDataString('email') ?? $account->getEmail());
|
|
$account->status = AccountStatus::tryFromValue($request->getDataInt('status')) ?? $account->status;
|
|
$account->type = AccountType::tryFromValue($request->getDataInt('type')) ?? $account->type;
|
|
|
|
if ($allowPassword && $request->hasData('password')) {
|
|
$account->generatePassword((string) $request->getData('password'));
|
|
}
|
|
|
|
return $account;
|
|
}
|
|
|
|
/**
|
|
* Api method to update the module settigns
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiModuleStatusUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$module = $request->getDataString('module') ?? '';
|
|
$status = (int) $request->getData('status');
|
|
|
|
if (empty($module) || empty($status)) {
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
NotificationLevel::WARNING,
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleStatusTitle'),
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'UnknownModuleOrStatusChange'),
|
|
[]
|
|
);
|
|
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
return;
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\Module $old */
|
|
$old = ModuleMapper::get()->where('id', $module)->execute();
|
|
|
|
$this->app->eventManager->triggerSimilar(
|
|
'PRE:Module:Admin-module-status-update', '',
|
|
[
|
|
$request->header->account,
|
|
['status' => $status, 'module' => $module],
|
|
]
|
|
);
|
|
switch ($status) {
|
|
case ModuleStatusUpdateType::ACTIVATE:
|
|
$done = $module === 'Admin' ? false : $this->app->moduleManager->activate($module);
|
|
$msg = $done
|
|
? $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleActivatedSuccessful')
|
|
: $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleActivatedFailure');
|
|
|
|
$new = clone $old;
|
|
$new->status = ModuleStatusUpdateType::ACTIVATE;
|
|
ModuleMapper::update()->execute($new);
|
|
|
|
break;
|
|
case ModuleStatusUpdateType::DEACTIVATE:
|
|
$done = $module === 'Admin' ? false : $this->app->moduleManager->deactivate($module);
|
|
$msg = $done
|
|
? $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleDeactivatedSuccessful')
|
|
: $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleDeactivatedFailure');
|
|
|
|
$new = clone $old;
|
|
$new->status = ModuleStatusUpdateType::DEACTIVATE;
|
|
ModuleMapper::update()->execute($new);
|
|
|
|
break;
|
|
case ModuleStatusUpdateType::INSTALL:
|
|
$done = $this->app->moduleManager->isInstalled($module);
|
|
$msg = $done
|
|
? $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleInstalledSuccessful')
|
|
: $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleInstalledFailure');
|
|
|
|
if ($done) {
|
|
break;
|
|
}
|
|
|
|
if (!\is_file(__DIR__ . '/../../../Modules/' . $module . '/info.json')) {
|
|
$msg = $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'UnknownModuleChange');
|
|
$done = false;
|
|
break;
|
|
}
|
|
|
|
$moduleInfo = new ModuleInfo(__DIR__ . '/../../../Modules/' . $module . '/info.json');
|
|
$moduleInfo->load();
|
|
|
|
// install dependencies
|
|
$dependencies = $moduleInfo->getDependencies();
|
|
foreach ($dependencies as $key => $_) {
|
|
$iResponse = new HttpResponse();
|
|
$iRequest = new HttpRequest();
|
|
$iRequest->header->account = 1;
|
|
$iRequest->setData('status', ModuleStatusUpdateType::INSTALL);
|
|
$iRequest->setData('module', $key);
|
|
|
|
$this->apiModuleStatusUpdate($iRequest, $iResponse);
|
|
}
|
|
|
|
// install module
|
|
$moduleObj = new Module();
|
|
$moduleObj->id = $module;
|
|
$moduleObj->theme = 'Default';
|
|
$moduleObj->path = $moduleInfo->getDirectory();
|
|
$moduleObj->version = $moduleInfo->getVersion();
|
|
$moduleObj->name = $moduleInfo->getExternalName();
|
|
|
|
$moduleObj->status = ModuleStatus::AVAILABLE;
|
|
|
|
$this->createModel($request->header->account, $moduleObj, ModuleMapper::class, 'module', $request->getOrigin());
|
|
|
|
$done = $this->app->moduleManager->install($module);
|
|
$msg = $done
|
|
? $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleInstalledSuccessful')
|
|
: $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleInstalledFailure');
|
|
|
|
$old = clone $moduleObj;
|
|
$moduleObj->status = ModuleStatus::ACTIVE;
|
|
|
|
$this->updateModel($request->header->account, $old, $moduleObj, ModuleMapper::class, 'module', $request->getOrigin());
|
|
|
|
$queryLoad = new Builder($this->app->dbPool->get('insert'));
|
|
$queryLoad->insert('module_load_pid', 'module_load_type', 'module_load_from', 'module_load_for', 'module_load_file')
|
|
->into('module_load');
|
|
|
|
$load = $moduleInfo->getLoad();
|
|
foreach ($load as $val) {
|
|
foreach ($val['pid'] as $pid) {
|
|
$queryLoad->values(
|
|
\sha1(\str_replace('/', '', $pid)),
|
|
(int) $val['type'],
|
|
$val['from'],
|
|
$val['for'],
|
|
$val['file']
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!empty($queryLoad->getValues())) {
|
|
$queryLoad->execute();
|
|
}
|
|
|
|
// install receiving from application (receiving from module is already installed during the module installation)
|
|
$appManager = new ApplicationManager($this->app);
|
|
$receiving = $appManager->getProvidingForModule($module);
|
|
foreach ($receiving as $app => $modules) {
|
|
foreach ($modules as $module) {
|
|
$this->app->moduleManager->installProviding('/Web/' . $app, $module);
|
|
}
|
|
}
|
|
|
|
break;
|
|
case ModuleStatusUpdateType::UNINSTALL:
|
|
$done = $module === 'Admin' ? false : $this->app->moduleManager->uninstall($module);
|
|
$msg = $done
|
|
? $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleUninstalledSuccessful')
|
|
: $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleUninstalledFailure');
|
|
|
|
$new = clone $old;
|
|
$new->status = ModuleStatusUpdateType::DELETE;
|
|
ModuleMapper::delete()->execute($new);
|
|
|
|
break;
|
|
default:
|
|
$done = false;
|
|
$msg = $this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'UnknownModuleStatusChange');
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
}
|
|
|
|
if ($done) {
|
|
$new = ModuleMapper::get()->where('id', $module)->execute();
|
|
|
|
$this->app->eventManager->triggerSimilar(
|
|
'POST:Module:Admin-module-status-update', '',
|
|
[
|
|
$request->header->account,
|
|
$old, $new,
|
|
StringUtils::intHash(ModuleMapper::class), 'module-status',
|
|
self::NAME,
|
|
$module,
|
|
'',
|
|
$request->getOrigin(),
|
|
]
|
|
);
|
|
} else {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
}
|
|
|
|
$this->fillJsonResponse(
|
|
$request,
|
|
$response,
|
|
$done ? NotificationLevel::OK : NotificationLevel::WARNING,
|
|
$this->app->l11nManager->getText($response->header->l11n->language, 'Admin', 'Api', 'ModuleStatusTitle'),
|
|
$msg,
|
|
[]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Api method to get a user permission
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountPermissionGet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var AccountPermission $account */
|
|
$account = AccountPermissionMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->createStandardReturnResponse($request, $response, $account);
|
|
}
|
|
|
|
/**
|
|
* Api method to get a group permission
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiGroupPermissionGet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
/** @var GroupPermission $group */
|
|
$group = GroupPermissionMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->createStandardReturnResponse($request, $response, $group);
|
|
}
|
|
|
|
/**
|
|
* Api method to delete a group permission
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiGroupPermissionDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateGroupPermissionDelete($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidDeleteResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var GroupPermission $permission */
|
|
$permission = GroupPermissionMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
|
|
if ($permission->getGroup() === 3) {
|
|
// admin group cannot be deleted
|
|
$this->createInvalidDeleteResponse($request, $response, []);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->deleteModel($request->header->account, $permission, GroupPermissionMapper::class, 'group-permission', $request->getOrigin());
|
|
$this->createStandardDeleteResponse($request, $response, $permission);
|
|
}
|
|
|
|
/**
|
|
* Api method to delete a user permission
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountPermissionDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateAccountPermissionDelete($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidDeleteResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var AccountPermission $permission */
|
|
$permission = AccountPermissionMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->deleteModel($request->header->account, $permission, AccountPermissionMapper::class, 'user-permission', $request->getOrigin());
|
|
$this->createStandardDeleteResponse($request, $response, $permission);
|
|
}
|
|
|
|
/**
|
|
* Api method to add a permission to a group
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAddGroupPermission(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validatePermissionCreate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
if (((int) $request->getData('permissionref')) === 3) {
|
|
// admin group cannot be deleted
|
|
$this->createInvalidUpdateResponse($request, $response, []);
|
|
|
|
return;
|
|
}
|
|
|
|
$permission = $this->createPermissionFromRequest($request);
|
|
|
|
if (!($permission instanceof GroupPermission)) {
|
|
$response->data['permission_create'] = new FormValidation($val);
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
return;
|
|
}
|
|
|
|
$this->createModel($request->header->account, $permission, GroupPermissionMapper::class, 'group-permission', $request->getOrigin());
|
|
$this->createStandardCreateResponse($request, $response, $permission);
|
|
}
|
|
|
|
/**
|
|
* Api method to add a permission to a account
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAddAccountPermission(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validatePermissionCreate($request))) {
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
return;
|
|
}
|
|
|
|
$permission = $this->createPermissionFromRequest($request);
|
|
if (!($permission instanceof AccountPermission)) {
|
|
// @todo Create a response text
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
|
|
return;
|
|
}
|
|
|
|
$this->createModel($request->header->account, $permission, AccountPermissionMapper::class, 'account-permission', $request->getOrigin());
|
|
$this->createStandardCreateResponse($request, $response, $permission);
|
|
}
|
|
|
|
/**
|
|
* Api method to add a permission to a account-model combination
|
|
*
|
|
* @param PermissionAbstract $permission Permission to create for account-model combination
|
|
* @param int $account Account creating this model
|
|
* @param string $ip Ip
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function createAccountModelPermission(PermissionAbstract $permission, int $account, string $ip) : void
|
|
{
|
|
$this->createModel($account, $permission, AccountPermissionMapper::class, 'account-permission', $ip);
|
|
}
|
|
|
|
/**
|
|
* Validate permission create request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validatePermissionCreate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['permissionowner'] = !PermissionOwner::isValidValue((int) $request->getData('permissionowner')))
|
|
|| ($val['permissionref'] = !\is_numeric($request->getData('permissionref')))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Method to create a permission from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return AccountPermission|GroupPermission
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function createPermissionFromRequest(RequestAbstract $request) : PermissionAbstract
|
|
{
|
|
/** @var AccountPermission|GroupPermission $permission */
|
|
$permission = ($request->getDataInt('permissionowner')) === PermissionOwner::GROUP
|
|
? new GroupPermission((int) $request->getData('permissionref'))
|
|
: new AccountPermission((int) $request->getData('permissionref'));
|
|
|
|
$permission->unit = $request->getDataInt('permissionunit');
|
|
$permission->app = $request->getDataInt('permissionapp');
|
|
$permission->module = $request->getDataString('permissionmodule');
|
|
$permission->category = $request->getDataInt('permissioncategory');
|
|
$permission->element = $request->getDataInt('permissionelement');
|
|
$permission->component = $request->getDataInt('permissioncomponent');
|
|
$permission->setPermission(
|
|
($request->getDataInt('permissionread') ?? 0)
|
|
| ($request->getDataInt('permissioncreate') ?? 0)
|
|
| ($request->getDataInt('permissionupdate') ?? 0)
|
|
| ($request->getDataInt('permissiondelete') ?? 0)
|
|
| ($request->getDataInt('permissionpermission') ?? 0)
|
|
);
|
|
|
|
return $permission;
|
|
}
|
|
|
|
/**
|
|
* Api method to update a account permission
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAccountPermissionUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateAccountPermissionUpdate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidUpdateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var AccountPermission $old */
|
|
$old = AccountPermissionMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
|
|
/** @var AccountPermission $new */
|
|
$new = $this->updatePermissionFromRequest($request, clone $old);
|
|
|
|
$this->updateModel($request->header->account, $old, $new, AccountPermissionMapper::class, 'account-permission', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $new);
|
|
}
|
|
|
|
/**
|
|
* Api method to update a group permission
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiGroupPermissionUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateGroupPermissionUpdate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidUpdateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var GroupPermission $old */
|
|
$old = GroupPermissionMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
|
|
if ($old->getGroup() === 3) {
|
|
// admin group cannot be deleted
|
|
$this->createInvalidUpdateResponse($request, $response, []);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var GroupPermission $new */
|
|
$new = $this->updatePermissionFromRequest($request, clone $old);
|
|
|
|
$this->updateModel($request->header->account, $old, $new, GroupPermissionMapper::class, 'group-permission', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $new);
|
|
}
|
|
|
|
/**
|
|
* Method to update a group permission from a request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param PermissionAbstract $permission Permission model
|
|
*
|
|
* @return PermissionAbstract
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function updatePermissionFromRequest(RequestAbstract $request, PermissionAbstract $permission) : PermissionAbstract
|
|
{
|
|
$permission->unit = $request->getDataInt('permissionunit') ?? $permission->unit;
|
|
$permission->app = $request->getDataInt('permissionapp') ?? $permission->app;
|
|
$permission->module = $request->getDataString('permissionmodule') ?? $permission->module;
|
|
$permission->category = $request->getDataInt('permissioncategory') ?? $permission->category;
|
|
$permission->element = $request->getDataInt('permissionelement') ?? $permission->element;
|
|
$permission->component = $request->getDataInt('permissioncomponent') ?? $permission->component;
|
|
$permission->setPermission(($request->getDataInt('permissioncreate') ?? 0)
|
|
| ($request->getDataInt('permissionread') ?? 0)
|
|
| ($request->getDataInt('permissionupdate') ?? 0)
|
|
| ($request->getDataInt('permissiondelete') ?? 0)
|
|
| ($request->getDataInt('permissionpermission') ?? 0));
|
|
|
|
return $permission;
|
|
}
|
|
|
|
/**
|
|
* Api method to add a group to an account
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAddGroupToAccount(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateAddGroupToAccount($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidAddResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$account = (int) $request->getData('account');
|
|
$groups = [$request->getDataInt('group') ?? 0];
|
|
|
|
// @todo Check if already in group
|
|
|
|
$this->createModelRelation($request->header->account, $account, $groups, AccountMapper::class, 'groups', 'account-group', $request->getOrigin());
|
|
$this->createStandardAddResponse($request, $response, $groups);
|
|
}
|
|
|
|
/**
|
|
* Validate adding a group to an account request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateAddGroupToAccount(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['account'] = !$request->hasData('account'))
|
|
|| ($val['group'] = !$request->hasData('group'))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to add an account to a group
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAddAccountToGroup(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateAddAccountToGroup($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidAddResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$group = (int) $request->getData('group');
|
|
$accounts = [$request->getDataInt('group-list') ?? 0];
|
|
|
|
$this->createModelRelation($request->header->account, $group, $accounts, GroupMapper::class, 'accounts', 'group-account', $request->getOrigin());
|
|
$this->createStandardAddResponse($request, $response, $accounts);
|
|
}
|
|
|
|
/**
|
|
* Validate adding an account to a group request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateAddAccountToGroup(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['group'] = !$request->hasData('group'))
|
|
|| ($val['grouplist'] = !$request->hasData('group-list'))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to add a group to an account
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiDeleteGroupFromAccount(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$account = (int) $request->getData('account');
|
|
$groups = \array_map('intval', $request->getDataList('igroup-idlist'));
|
|
|
|
if (\in_array(3, $groups) && $account === $request->header->account) {
|
|
// admin group cannot be deleted
|
|
$this->createInvalidRemoveResponse($request, $response, []);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->deleteModelRelation($request->header->account, $account, $groups, AccountMapper::class, 'groups', 'account-group', $request->getOrigin());
|
|
$this->createStandardRemoveResponse($request, $response, $groups);
|
|
}
|
|
|
|
/**
|
|
* Api method to add an account to a group
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiDeleteAccountFromGroup(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$group = (int) $request->getData('group');
|
|
$accounts = \array_map('intval', $request->getDataList('iaccount-idlist'));
|
|
|
|
if (\in_array($request->header->account, $accounts) && $group === 3) {
|
|
// admin group cannot be deleted
|
|
$this->createInvalidRemoveResponse($request, $response, []);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->deleteModelRelation($request->header->account, $group, $accounts, GroupMapper::class, 'accounts', 'group-account', $request->getOrigin());
|
|
$this->createStandardRemoveResponse($request, $response, $accounts);
|
|
}
|
|
|
|
/**
|
|
* Api re-init routes
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiReInit(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$directories = \glob(__DIR__ . '/../../../Web/*', \GLOB_ONLYDIR);
|
|
|
|
if ($directories !== false) {
|
|
foreach ($directories as $directory) {
|
|
if (\is_file($path = $directory . '/Routes.php')) {
|
|
\file_put_contents($path, '<?php return [];');
|
|
}
|
|
|
|
if (\is_file($path = $directory . '/Hooks.php')) {
|
|
\file_put_contents($path, '<?php return [];');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (\is_file($path = __DIR__ . '/../../../Cli/Routes.php')) {
|
|
\file_put_contents($path, '<?php return [];');
|
|
}
|
|
|
|
if (\is_file($path = __DIR__ . '/../../../Socket/Routes.php')) {
|
|
\file_put_contents($path, '<?php return [];');
|
|
}
|
|
|
|
\phpOMS\Module\StatusAbstract::$routes = [];
|
|
\phpOMS\Module\StatusAbstract::$hooks = [];
|
|
|
|
$installedModules = $this->app->moduleManager->getActiveModules();
|
|
foreach ($installedModules as $name => $_) {
|
|
$this->app->moduleManager->reInit($name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Api check for updates
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @todo Create update logic for application, resources, modules
|
|
* https://github.com/Karaka-Management/oms-Admin/issues/17
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiCheckForUpdates(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
// this is only a temp... in the future this logic will change but for current purposes this is the easiest way to implement updates
|
|
$request = new HttpRequest(new HttpUri('https://api.github.com/repos/Karaka/Updates/contents'));
|
|
$request->setMethod(RequestMethod::GET);
|
|
$request->header->set('User-Agent', 'spl1nes');
|
|
|
|
$updateFilesJson = Rest::request($request)->getJsonData();
|
|
|
|
/** @var array<string, array<string, mixed>> */
|
|
$toUpdate = [];
|
|
|
|
foreach ($updateFilesJson as $file) {
|
|
$name = \explode('_', $file['name']);
|
|
$path = '';
|
|
|
|
if (\is_dir(__DIR__ . '/../../../' . $name[0])) {
|
|
$path = __DIR__ . '/../../../' . $name[0];
|
|
} elseif (\is_dir(__DIR__ . '/../../' . $name[0])) {
|
|
$path = __DIR__ . '/../../' . $name[0];
|
|
}
|
|
|
|
if ($path === '') {
|
|
return;
|
|
}
|
|
|
|
$currentVersion = '';
|
|
$remoteVersion = \substr($file[1], 0, -5);
|
|
|
|
if (\phpOMS\Version\Version::compare($currentVersion, $remoteVersion) < 0) {
|
|
$toUpdate[$name[0]][$remoteVersion] = $file;
|
|
|
|
\uksort($toUpdate[$name[0]], [\phpOMS\Version\Version::class, 'compare']);
|
|
}
|
|
}
|
|
|
|
$this->apiUpdate($toUpdate);
|
|
}
|
|
|
|
/**
|
|
* Api update file
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiUpdateFile(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
$this->apiUpdate([[
|
|
'name' => 'temp.json',
|
|
'download_url' => 'https://raw.githubusercontent.com/Karaka-Management/' . ($request->getDataString('url') ?? ''),
|
|
]]);
|
|
}
|
|
|
|
/**
|
|
* Update the system or a module
|
|
*
|
|
* @param array $toUpdate Array of update resources
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @todo Implement in app download and installation
|
|
* https://github.com/Karaka-Management/oms-Admin/issues/13
|
|
*/
|
|
private function apiUpdate(array $toUpdate) : void
|
|
{
|
|
// this is only a temp... in the future this logic will change but for current purposes this is the easiest way to implement updates
|
|
|
|
foreach ($toUpdate as $update) {
|
|
$dest = __DIR__ . '/../Updates/' . \explode('.', $update['name'])[0];
|
|
\mkdir($dest);
|
|
$this->downloadUpdate($update['download_url'], $dest . '/' . $update['name']);
|
|
$this->runUpdate($dest . '/' . $update['name']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Package to download
|
|
*
|
|
* @param string $url Url to download from
|
|
* @param string $dest Local destination of the download
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function downloadUpdate(string $url, string $dest) : void
|
|
{
|
|
// this is only a temp... in the future this logic will change but for current purposes this is the easiest way to implement updates
|
|
$request = new HttpRequest(new HttpUri($url));
|
|
$request->setMethod(RequestMethod::GET);
|
|
|
|
$updateFile = Rest::request($request)->getBody();
|
|
File::put($dest, $updateFile);
|
|
}
|
|
|
|
/**
|
|
* Run the update
|
|
*
|
|
* @param string $updateFile Update file/package
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function runUpdate(string $updateFile) : void
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Routing end-point for application behavior.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiContactCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateContactCreate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
|
|
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->id,
|
|
AccountMapper::class, 'contacts', '', $request->getOrigin()
|
|
);
|
|
|
|
$this->createStandardCreateResponse($request, $response, $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'] = !$request->hasData('account'))
|
|
|| ($val['type'] = !\is_numeric($request->getData('type')))
|
|
|| ($val['content'] = !$request->hasData('content'))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Method to create a account element from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return Contact
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function createContactFromRequest(RequestAbstract $request) : Contact
|
|
{
|
|
/** @var Contact $element */
|
|
$element = new Contact();
|
|
$element->type = ContactType::tryFromValue($request->getDataInt('type')) ?? ContactType::EMAIL;
|
|
$element->subtype = $request->getDataInt('subtype') ?? 0;
|
|
$element->content = $request->getDataString('content') ?? '';
|
|
|
|
return $element;
|
|
}
|
|
|
|
/**
|
|
* Api method to delete Settings
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiSettingsDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateSettingsDelete($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidDeleteResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$settings = SettingMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->deleteModel($request->header->account, $settings, SettingMapper::class, 'settings', $request->getOrigin());
|
|
$this->createStandardDeleteResponse($request, $response, $settings);
|
|
}
|
|
|
|
/**
|
|
* Validate Settings delete request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateSettingsDelete(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to update Application
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiApplicationUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateApplicationUpdate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidUpdateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var App $old */
|
|
$old = AppMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$new = $this->updateApplicationFromRequest($request, clone $old);
|
|
|
|
$this->updateModel($request->header->account, $old, $new, AppMapper::class, 'application', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $new);
|
|
}
|
|
|
|
/**
|
|
* Method to update Application from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param App $new Model to modify
|
|
*
|
|
* @return App
|
|
*
|
|
* @todo Implement API update function
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function updateApplicationFromRequest(RequestAbstract $request, App $new) : App
|
|
{
|
|
return $new;
|
|
}
|
|
|
|
/**
|
|
* Validate Application update request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateApplicationUpdate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to delete Application
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiApplicationDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateApplicationDelete($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidDeleteResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\App $application */
|
|
$application = AppMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->deleteModel($request->header->account, $application, AppMapper::class, 'application', $request->getOrigin());
|
|
$this->createStandardDeleteResponse($request, $response, $application);
|
|
}
|
|
|
|
/**
|
|
* Validate Application delete request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateApplicationDelete(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Validate GroupPermission update request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @todo Implement API validation function
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateGroupPermissionUpdate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Validate GroupPermission delete request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateGroupPermissionDelete(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Method to update AccountPermission from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param AccountPermission $new Model to modify
|
|
*
|
|
* @return AccountPermission
|
|
*
|
|
* @todo Implement API update function
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function updateAccountPermissionFromRequest(RequestAbstract $request, AccountPermission $new) : AccountPermission
|
|
{
|
|
return $new;
|
|
}
|
|
|
|
/**
|
|
* Validate AccountPermission update request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @todo Implement API validation function
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateAccountPermissionUpdate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Validate AccountPermission delete request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateAccountPermissionDelete(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to update Contact
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiContactUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateContactUpdate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidUpdateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var Contact $old */
|
|
$old = ContactMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$new = $this->updateContactFromRequest($request, clone $old);
|
|
|
|
$this->updateModel($request->header->account, $old, $new, ContactMapper::class, 'contact', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $new);
|
|
}
|
|
|
|
/**
|
|
* Method to update Contact from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param Contact $new Model to modify
|
|
*
|
|
* @return Contact
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function updateContactFromRequest(RequestAbstract $request, Contact $new) : Contact
|
|
{
|
|
$new->type = ContactType::tryFromValue($request->getDataInt('type')) ?? $new->type;
|
|
$new->subtype = $request->getDataInt('subtype') ?? $new->subtype;
|
|
$new->content = $request->getDataString('content') ?? $new->content;
|
|
|
|
return $new;
|
|
}
|
|
|
|
/**
|
|
* Validate Contact update request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @todo Implement API validation function
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateContactUpdate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to delete Contact
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiContactDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateContactDelete($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidDeleteResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\Contact $contact */
|
|
$contact = ContactMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->deleteModelRelation($request->header->account, (int) $request->getData('account'), [$contact->id], AccountMapper::class, 'contacts', 'account-contact', $request->getOrigin());
|
|
$this->deleteModel($request->header->account, $contact, ContactMapper::class, 'contact', $request->getOrigin());
|
|
|
|
$this->createStandardDeleteResponse($request, $response, $contact);
|
|
}
|
|
|
|
/**
|
|
* Validate Contact delete request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateContactDelete(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))
|
|
|| ($val['account'] = !$request->hasData('account'))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to create Data
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiDataChangeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateDataChangeCreate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$data = $this->createDataChangeFromRequest();
|
|
$this->createModel($request->header->account, $data, DataChangeMapper::class, 'data', $request->getOrigin());
|
|
$this->createStandardCreateResponse($request, $response, $data);
|
|
}
|
|
|
|
/**
|
|
* Method to create DataChange from request.
|
|
*
|
|
* @return DataChange
|
|
*
|
|
* @todo implement
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function createDataChangeFromRequest() : DataChange
|
|
{
|
|
return new DataChange();
|
|
}
|
|
|
|
/**
|
|
* Validate Data create request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @todo Implement API validation function
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateDataChangeCreate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = ($request->header->account < 1))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to delete DataChange
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiDataChangeDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateDataChangeDelete($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidDeleteResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \Modules\Admin\Models\DataChange $data */
|
|
$data = DataChangeMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->deleteModel($request->header->account, $data, DataChangeMapper::class, 'data', $request->getOrigin());
|
|
$this->createStandardDeleteResponse($request, $response, $data);
|
|
}
|
|
|
|
/**
|
|
* Validate DataChange delete request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateDataChangeDelete(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to delete Contact
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAddressDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateAddressDelete($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidDeleteResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \phpOMS\Stdlib\Base\Address $address */
|
|
$address = AddressMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$this->deleteModelRelation($request->header->account, (int) $request->getData('account'), [$address->id], AccountMapper::class, 'addresses', 'account-address', $request->getOrigin());
|
|
$this->deleteModel($request->header->account, $address, AddressMapper::class, 'address', $request->getOrigin());
|
|
|
|
$this->createStandardDeleteResponse($request, $response, $address);
|
|
}
|
|
|
|
/**
|
|
* Validate Address delete request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateAddressDelete(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))
|
|
|| ($val['account'] = !$request->hasData('account'))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Api method to update Contact
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAddressUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateAddressUpdate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidUpdateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var Address $old */
|
|
$old = AddressMapper::get()->where('id', (int) $request->getData('id'))->execute();
|
|
$new = $this->updateAddressFromRequest($request, clone $old);
|
|
|
|
$this->updateModel($request->header->account, $old, $new, AddressMapper::class, 'address', $request->getOrigin());
|
|
$this->createStandardUpdateResponse($request, $response, $new);
|
|
}
|
|
|
|
/**
|
|
* Validate Contact update request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @todo Implement API validation function
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function validateAddressUpdate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['id'] = !$request->hasData('id'))) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Method to update an account from a request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param Address $address Address
|
|
*
|
|
* @return Address
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function updateAddressFromRequest(RequestAbstract $request, Address $address) : Address
|
|
{
|
|
$hasLocationChange = ($request->getDataString('address') ?? $address->address) !== $address->address
|
|
|| ($request->getDataString('postal') ?? $address->postal) !== $address->postal
|
|
|| ($request->getDataString('city') ?? $address->city) !== $address->city
|
|
|| ($request->getDataString('state') ?? $address->state) !== $address->state;
|
|
|
|
$address->name = $request->getDataString('name') ?? $address->name;
|
|
$address->fao = $request->getDataString('fao') ?? $address->fao;
|
|
$address->address = $request->getDataString('address') ?? $address->address;
|
|
$address->addressAddition = $request->getDataString('addition') ?? $address->addressAddition;
|
|
$address->postal = $request->getDataString('postal') ?? $address->postal;
|
|
$address->city = $request->getDataString('city') ?? $address->city;
|
|
$address->state = $request->getDataString('state') ?? $address->state;
|
|
|
|
if (ISO3166TwoEnum::isValidValue($request->getDataString('country') ?? ISO3166TwoEnum::_XXX)) {
|
|
$address->setCountry($request->getDataString('country') ?? $address->country);
|
|
}
|
|
|
|
if ($hasLocationChange) {
|
|
$geocoding = Nominatim::geocoding($address->country, $address->city, $address->address);
|
|
if ($geocoding === ['lat' => 0.0, 'lon' => 0.0]) {
|
|
$geocoding = Nominatim::geocoding($address->country, $address->city);
|
|
}
|
|
|
|
$address->lat = $geocoding['lat'];
|
|
$address->lon = $geocoding['lon'];
|
|
}
|
|
|
|
return $address;
|
|
}
|
|
|
|
/**
|
|
* Routing end-point for application behavior.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
* @param ResponseAbstract $response Response
|
|
* @param array $data Generic data
|
|
*
|
|
* @return void
|
|
*
|
|
* @api
|
|
*
|
|
* @todo Find a way to hide some contact/address information for some modules
|
|
* https://github.com/Karaka-Management/oms-Profile/issues/3
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function apiAddressCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
|
|
{
|
|
if (!empty($val = $this->validateAddressCreate($request))) {
|
|
$response->header->status = RequestStatusCode::R_400;
|
|
$this->createInvalidCreateResponse($request, $response, $val);
|
|
|
|
return;
|
|
}
|
|
|
|
$address = $this->createAddressFromRequest($request);
|
|
$this->createModel($request->header->account, $address, AddressMapper::class, 'account_address', $request->getOrigin());
|
|
|
|
$this->createModelRelation(
|
|
$request->header->account,
|
|
(int) $request->getData('account'),
|
|
$address->id,
|
|
AccountMapper::class, 'addresses', '', $request->getOrigin()
|
|
);
|
|
|
|
$this->createStandardCreateResponse($request, $response, $address);
|
|
}
|
|
|
|
/**
|
|
* Validate contact element create request
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return array<string, bool>
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function validateAddressCreate(RequestAbstract $request) : array
|
|
{
|
|
$val = [];
|
|
if (($val['account'] = !$request->hasData('account'))
|
|
) {
|
|
return $val;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Method to create unit from request.
|
|
*
|
|
* @param RequestAbstract $request Request
|
|
*
|
|
* @return Address
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function createAddressFromRequest(RequestAbstract $request) : Address
|
|
{
|
|
$address = new Address();
|
|
$address->name = $request->getDataString('name') ?? '';
|
|
$address->type = AddressType::tryFromValue($request->getDataInt('type')) ?? AddressType::BUSINESS;
|
|
$address->fao = $request->getDataString('fao') ?? '';
|
|
$address->address = $request->getDataString('address') ?? '';
|
|
$address->postal = $request->getDataString('postal') ?? '';
|
|
$address->city = $request->getDataString('city') ?? '';
|
|
$address->state = $request->getDataString('state') ?? '';
|
|
|
|
if (ISO3166TwoEnum::isValidValue($request->getDataString('country') ?? ISO3166TwoEnum::_XXX)) {
|
|
$address->setCountry($request->getDataString('country') ?? ISO3166TwoEnum::_XXX);
|
|
}
|
|
|
|
$geocoding = Nominatim::geocoding($address->country, $address->city, $address->address);
|
|
if ($geocoding === ['lat' => 0.0, 'lon' => 0.0]) {
|
|
$geocoding = Nominatim::geocoding($address->country, $address->city);
|
|
}
|
|
|
|
$address->lat = $geocoding['lat'];
|
|
$address->lon = $geocoding['lon'];
|
|
|
|
return $address;
|
|
}
|
|
}
|