Compare commits
39
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
882b326aca
|
||
|
|
49fe85dcde
|
||
|
|
a021aff92c
|
||
|
|
6abe93e3b5
|
||
|
|
7e84e6b4ba
|
||
|
|
76ed977375
|
||
|
|
fea403fe5a
|
||
|
|
1d96fd0cb9
|
||
|
|
7437e19de5
|
||
|
|
47567c9b75
|
||
|
|
ef16e70235
|
||
|
|
91d064947e
|
||
|
|
9a6e95673e
|
||
|
|
d24c3bb1cb
|
||
|
|
2ad637e55f
|
||
|
|
ac09342c9d
|
||
|
|
3a1054e1df
|
||
|
|
0f02c4b5be
|
||
|
|
be0a15d02d
|
||
|
|
12065b0525
|
||
|
|
0fc21cc461
|
||
|
|
7d63de4403
|
||
|
|
c520c256ee
|
||
|
|
2f9b97d1a4
|
||
|
|
ad18c7cb25
|
||
|
|
a2fb166b55
|
||
|
|
f0a7b34212
|
||
|
|
dccb34971b
|
||
|
|
36f767ea9b
|
||
|
|
c0739eeddf
|
||
|
|
cac30c9203
|
||
|
|
89b0ce768b
|
||
|
|
656ce219ef
|
||
|
|
fd30911dd3
|
||
|
|
b4cfa7aab2
|
||
|
|
617ae903ae
|
||
|
|
a7997429b7
|
||
|
|
4d5e982370
|
||
|
|
46ea01efe1
|
No files matched your search
@@ -15,9 +15,13 @@ $dotenv->load();
|
|||||||
class Container
|
class Container
|
||||||
{
|
{
|
||||||
static SokoWeb\Interfaces\Database\IConnection $dbConnection;
|
static SokoWeb\Interfaces\Database\IConnection $dbConnection;
|
||||||
static SokoWeb\Routing\RouteCollection $routeCollection;
|
static SokoWeb\Interfaces\Database\IAuditLogger $auditLogger;
|
||||||
|
static SokoWeb\Interfaces\PersistentData\IPersistentDataManager $persistentDataManager;
|
||||||
|
static SokoWeb\Interfaces\Routing\IRouteCollection $routeCollection;
|
||||||
static SokoWeb\Interfaces\Session\ISessionHandler $sessionHandler;
|
static SokoWeb\Interfaces\Session\ISessionHandler $sessionHandler;
|
||||||
static SokoWeb\Interfaces\Request\IRequest $request;
|
static SokoWeb\Interfaces\Request\IRequest $request;
|
||||||
}
|
}
|
||||||
|
|
||||||
Container::$dbConnection = new SokoWeb\Database\Mysql\Connection($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']);
|
Container::$dbConnection = new SokoWeb\Database\Mysql\Connection($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']);
|
||||||
|
Container::$auditLogger = new RVR\Database\AuditLogger(Container::$dbConnection, 'audit_log');
|
||||||
|
Container::$persistentDataManager = new SokoWeb\PersistentData\PersistentDataManager(Container::$dbConnection, Container::$auditLogger);
|
||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"esoko/soko-web": "0.4",
|
"esoko/soko-web": "0.6",
|
||||||
"firebase/php-jwt": "^6.4"
|
"firebase/php-jwt": "^6.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|||||||
Generated
+4
-4
@@ -4,15 +4,15 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "f7786e07bcb0373560ae67549fa28f0b",
|
"content-hash": "7b9e3854a5b7ef69d360c1dfbac75c17",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "esoko/soko-web",
|
"name": "esoko/soko-web",
|
||||||
"version": "v0.4",
|
"version": "0.6",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.esoko.eu/esoko/soko-web.git",
|
"url": "https://git.esoko.eu/esoko/soko-web.git",
|
||||||
"reference": "948b36c80d324e07339a543d97b9e629487f3a45"
|
"reference": "5e0579463cf0f4203c46e0d4f9c09cd283dbf0b8"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"phpmailer/phpmailer": "^6.8",
|
"phpmailer/phpmailer": "^6.8",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"GNU GPL 3.0"
|
"GNU GPL 3.0"
|
||||||
],
|
],
|
||||||
"description": "Lightweight web framework",
|
"description": "Lightweight web framework",
|
||||||
"time": "2023-04-16T18:52:06+00:00"
|
"time": "2023-04-19T21:35:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "firebase/php-jwt",
|
"name": "firebase/php-jwt",
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
CREATE TABLE `audit_log` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`local_table` varchar(255) NOT NULL,
|
||||||
|
`local_id` int(10) unsigned NOT NULL,
|
||||||
|
`type` enum('insert','update','delete') NOT NULL,
|
||||||
|
`date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`modifier_id` int(10) unsigned NULL,
|
||||||
|
`column` varchar(255) NULL,
|
||||||
|
`old` text NULL,
|
||||||
|
`new` text NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE `currencies` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`community_id` int(10) unsigned NOT NULL,
|
||||||
|
`code` varchar(3) NOT NULL,
|
||||||
|
`round_digits` tinyint(1) unsigned NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `unique_currency_for_community` (`community_id`, `code`),
|
||||||
|
KEY `community_id` (`community_id`),
|
||||||
|
CONSTRAINT `currencies_community_id` FOREIGN KEY (`community_id`) REFERENCES `communities` (`id`)
|
||||||
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE `currency_exchange_rates` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`currency_id` int(10) unsigned NOT NULL,
|
||||||
|
`exchange_rate` decimal(19,9) unsigned NOT NULL,
|
||||||
|
`valid_from` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `currency_id` (`currency_id`),
|
||||||
|
INDEX `valid_from` (`valid_from`),
|
||||||
|
CONSTRAINT `currency_exchange_rates_currency_id` FOREIGN KEY (`currency_id`) REFERENCES `currencies` (`id`)
|
||||||
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
@@ -113,7 +113,7 @@ p.small, span.small {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.marginLeft {
|
.marginLeft {
|
||||||
margin-left: 10px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.marginBottom {
|
.marginBottom {
|
||||||
@@ -121,7 +121,7 @@ p.small, span.small {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.marginRight {
|
.marginRight {
|
||||||
margin-right: 10px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.center {
|
.center {
|
||||||
@@ -455,10 +455,18 @@ table th {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table th, table td {
|
table th, table td {
|
||||||
padding: 2px 0;
|
padding: 3px 0;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table th:not(:first-child), table td:not(:first-child) {
|
||||||
|
padding-left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th:not(:last-child), table td:not(:last-child) {
|
||||||
|
padding-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.choices__inner {
|
.choices__inner {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@@ -477,6 +485,7 @@ table th, table td {
|
|||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
button, a.button {
|
button, a.button {
|
||||||
|
margin: 3px 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
(function () {
|
(function () {
|
||||||
const element = document.getElementById('new_member_user_id');
|
const element = document.getElementById('newMember').elements['user_id'];
|
||||||
const choices = new Choices(element, {
|
const choices = new Choices(element, {
|
||||||
noResultsText: 'No users found',
|
noResultsText: 'No users found',
|
||||||
noChoicesText: 'Start typing to search users'
|
noChoicesText: 'Start typing to search users'
|
||||||
@@ -13,50 +13,5 @@
|
|||||||
|
|
||||||
element.addEventListener('choice', function () {
|
element.addEventListener('choice', function () {
|
||||||
choices.setChoices([], 'value', 'label', true);
|
choices.setChoices([], 'value', 'label', true);
|
||||||
document.getElementById('new_member_button').disabled = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('new_member_button').addEventListener('click', function () {
|
|
||||||
document.getElementById('loading').style.visibility = 'visible';
|
|
||||||
|
|
||||||
let data = new FormData();
|
|
||||||
data.append('user_id', document.getElementById('new_member_user_id').value);
|
|
||||||
|
|
||||||
RVR.httpRequest('POST', newMemberUrl, function () {
|
|
||||||
window.location.reload();
|
|
||||||
}, data);
|
|
||||||
});
|
|
||||||
|
|
||||||
const ownerCheckboxesButtons = document.getElementsByClassName('member_owner');
|
|
||||||
for (const ownerCheckboxesButton of ownerCheckboxesButtons) {
|
|
||||||
ownerCheckboxesButton.addEventListener('change', function () {
|
|
||||||
document.getElementById('loading').style.visibility = 'visible';
|
|
||||||
|
|
||||||
let data = new FormData();
|
|
||||||
data.append('community_member_id', this.dataset.id);
|
|
||||||
data.append('owner', this.checked ? 1 : 0);
|
|
||||||
|
|
||||||
RVR.httpRequest('POST', editMemberUrl, function () {
|
|
||||||
document.getElementById('loading').style.visibility = 'hidden';
|
|
||||||
|
|
||||||
if (!this.response.success) {
|
|
||||||
ownerCheckboxesButton.checked = !ownerCheckboxesButton.checked;
|
|
||||||
}
|
|
||||||
}, data);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const deleteButtons = document.getElementsByClassName('delete_member');
|
|
||||||
for (const deleteButton of deleteButtons) {
|
|
||||||
deleteButton.addEventListener('click', function () {
|
|
||||||
document.getElementById('loading').style.visibility = 'visible';
|
|
||||||
|
|
||||||
let data = new FormData();
|
|
||||||
data.append('community_member_id', this.dataset.id);
|
|
||||||
|
|
||||||
RVR.httpRequest('POST', deleteMemberUrl, function () {
|
|
||||||
window.location.reload();
|
|
||||||
}, data);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
})();
|
})();
|
||||||
@@ -49,7 +49,7 @@ var RVR = {
|
|||||||
document.getElementById('loading').style.visibility = 'visible';
|
document.getElementById('loading').style.visibility = 'visible';
|
||||||
|
|
||||||
var formData = new FormData(form);
|
var formData = new FormData(form);
|
||||||
var formError = form.getElementsByClassName('formError')[0];
|
var formError = document.getElementsByClassName('formError')[0];
|
||||||
var pageLeaveOnSuccess = form.dataset.redirectOnSuccess || form.dataset.reloadOnSuccess;
|
var pageLeaveOnSuccess = form.dataset.redirectOnSuccess || form.dataset.reloadOnSuccess;
|
||||||
|
|
||||||
RVR.httpRequest('POST', form.action, function () {
|
RVR.httpRequest('POST', form.action, function () {
|
||||||
@@ -163,8 +163,14 @@ var RVR = {
|
|||||||
|
|
||||||
for (var i = 0; i < observedInputs.length; i++) {
|
for (var i = 0; i < observedInputs.length; i++) {
|
||||||
var input = form.elements[observedInputs[i]];
|
var input = form.elements[observedInputs[i]];
|
||||||
if (input.defaultValue !== input.value) {
|
if (input.type === 'checkbox') {
|
||||||
anyChanged = true;
|
if (input.defaultChecked !== input.checked) {
|
||||||
|
anyChanged = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (input.defaultValue !== input.value) {
|
||||||
|
anyChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ if [[ "${BRANCH_NAME}" =~ $BRANCH_PATTERN ]]; then
|
|||||||
TICKET_ID=$(echo $BRANCH_NAME | sed -E "s@$BRANCH_PATTERN@\\2@")
|
TICKET_ID=$(echo $BRANCH_NAME | sed -E "s@$BRANCH_PATTERN@\\2@")
|
||||||
|
|
||||||
COMMIT_MESSAGE=$(head -n 1 $1)
|
COMMIT_MESSAGE=$(head -n 1 $1)
|
||||||
COMMIT_MESSAGE_REGEX="^$TICKET_ID .*"
|
COMMIT_MESSAGE_REGEX="^(fixup! )?$TICKET_ID .*"
|
||||||
|
|
||||||
if [[ ! "${COMMIT_MESSAGE}" =~ $COMMIT_MESSAGE_REGEX ]]; then
|
if [[ ! "${COMMIT_MESSAGE}" =~ $COMMIT_MESSAGE_REGEX ]]; then
|
||||||
sed -i.bak -e "1s/^/$TICKET_ID /" $1
|
sed -i.bak -e "1s/^/$TICKET_ID /" $1
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?php namespace RVR\Cli;
|
<?php namespace RVR\Cli;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use RVR\PersistentData\Model\OAuthClient;
|
use RVR\PersistentData\Model\OAuthClient;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
@@ -33,8 +32,7 @@ class AddOAuthClientCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$pdm = new PersistentDataManager();
|
\Container::$persistentDataManager->saveToDb($oAuthClient);
|
||||||
$pdm->saveToDb($oAuthClient);
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$output->writeln('<error>Adding OAuth client failed!</error>');
|
$output->writeln('<error>Adding OAuth client failed!</error>');
|
||||||
$output->writeln('');
|
$output->writeln('');
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?php namespace RVR\Cli;
|
<?php namespace RVR\Cli;
|
||||||
|
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use RVR\Repository\OAuthClientRepository;
|
use RVR\Repository\OAuthClientRepository;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
@@ -32,8 +31,7 @@ class AddOAuthRedirectUriCommand extends Command
|
|||||||
$oAuthClient->setRedirectUrisArray($redirectUris);
|
$oAuthClient->setRedirectUrisArray($redirectUris);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$pdm = new PersistentDataManager();
|
\Container::$persistentDataManager->saveToDb($oAuthClient);
|
||||||
$pdm->saveToDb($oAuthClient);
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$output->writeln('<error>Adding redirect URI failed!</error>');
|
$output->writeln('<error>Adding redirect URI failed!</error>');
|
||||||
$output->writeln('');
|
$output->writeln('');
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?php namespace RVR\Cli;
|
<?php namespace RVR\Cli;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
@@ -36,8 +35,7 @@ class AddUserCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$pdm = new PersistentDataManager();
|
\Container::$persistentDataManager->saveToDb($user);
|
||||||
$pdm->saveToDb($user);
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$output->writeln('<error>Adding user failed!</error>');
|
$output->writeln('<error>Adding user failed!</error>');
|
||||||
$output->writeln('');
|
$output->writeln('');
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use DateTime;
|
|||||||
use SokoWeb\Database\Query\Modify;
|
use SokoWeb\Database\Query\Modify;
|
||||||
use SokoWeb\Database\Query\Select;
|
use SokoWeb\Database\Query\Select;
|
||||||
use SokoWeb\Interfaces\Database\IResultSet;
|
use SokoWeb\Interfaces\Database\IResultSet;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use RVR\Repository\UserPasswordResetterRepository;
|
use RVR\Repository\UserPasswordResetterRepository;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
@@ -12,15 +11,12 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||||||
|
|
||||||
class MaintainDatabaseCommand extends Command
|
class MaintainDatabaseCommand extends Command
|
||||||
{
|
{
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +50,7 @@ class MaintainDatabaseCommand extends Command
|
|||||||
private function deleteExpiredPasswordResetters(): void
|
private function deleteExpiredPasswordResetters(): void
|
||||||
{
|
{
|
||||||
foreach ($this->userPasswordResetterRepository->getAllExpired() as $passwordResetter) {
|
foreach ($this->userPasswordResetterRepository->getAllExpired() as $passwordResetter) {
|
||||||
$this->pdm->deleteFromDb($passwordResetter);
|
\Container::$persistentDataManager->deleteFromDb($passwordResetter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?php namespace RVR\Cli;
|
<?php namespace RVR\Cli;
|
||||||
|
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use RVR\Repository\OAuthClientRepository;
|
use RVR\Repository\OAuthClientRepository;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
@@ -32,8 +31,7 @@ class RemoveOAuthRedirectUriCommand extends Command
|
|||||||
$oAuthClient->setRedirectUrisArray($redirectUris);
|
$oAuthClient->setRedirectUrisArray($redirectUris);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$pdm = new PersistentDataManager();
|
\Container::$persistentDataManager->saveToDb($oAuthClient);
|
||||||
$pdm->saveToDb($oAuthClient);
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$output->writeln('<error>Removing redirect URI failed!</error>');
|
$output->writeln('<error>Removing redirect URI failed!</error>');
|
||||||
$output->writeln('');
|
$output->writeln('');
|
||||||
|
|||||||
@@ -3,36 +3,38 @@
|
|||||||
use DateTime;
|
use DateTime;
|
||||||
use RVR\PersistentData\Model\Community;
|
use RVR\PersistentData\Model\Community;
|
||||||
use RVR\PersistentData\Model\CommunityMember;
|
use RVR\PersistentData\Model\CommunityMember;
|
||||||
|
use RVR\PersistentData\Model\Currency;
|
||||||
|
use RVR\PersistentData\Model\CurrencyExchangeRate;
|
||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use RVR\Repository\CommunityRepository;
|
use RVR\Repository\CommunityRepository;
|
||||||
use RVR\Repository\CommunityMemberRepository;
|
use RVR\Repository\CommunityMemberRepository;
|
||||||
|
use RVR\Repository\CurrencyExchangeRateRepository;
|
||||||
|
use RVR\Repository\CurrencyRepository;
|
||||||
use RVR\Repository\UserRepository;
|
use RVR\Repository\UserRepository;
|
||||||
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
||||||
use SokoWeb\Interfaces\Request\IRequest;
|
|
||||||
use SokoWeb\Interfaces\Response\IContent;
|
use SokoWeb\Interfaces\Response\IContent;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use SokoWeb\Response\HtmlContent;
|
use SokoWeb\Response\HtmlContent;
|
||||||
use SokoWeb\Response\JsonContent;
|
use SokoWeb\Response\JsonContent;
|
||||||
|
|
||||||
class CommunityController implements IAuthenticationRequired
|
class CommunityController implements IAuthenticationRequired
|
||||||
{
|
{
|
||||||
private IRequest $request;
|
|
||||||
|
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
private UserRepository $userRepository;
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
private CommunityRepository $communityRepository;
|
private CommunityRepository $communityRepository;
|
||||||
|
|
||||||
private CommunityMemberRepository $communityMemberRepository;
|
private CommunityMemberRepository $communityMemberRepository;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
private CurrencyRepository $currencyRepository;
|
||||||
|
|
||||||
|
private CurrencyExchangeRateRepository $currencyExchangeRatesRepository;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
$this->userRepository = new UserRepository();
|
$this->userRepository = new UserRepository();
|
||||||
$this->communityRepository = new CommunityRepository();
|
$this->communityRepository = new CommunityRepository();
|
||||||
$this->communityMemberRepository = new CommunityMemberRepository();
|
$this->communityMemberRepository = new CommunityMemberRepository();
|
||||||
|
$this->currencyRepository = new CurrencyRepository();
|
||||||
|
$this->currencyExchangeRatesRepository = new CurrencyExchangeRateRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isAuthenticationRequired(): bool
|
public function isAuthenticationRequired(): bool
|
||||||
@@ -42,14 +44,14 @@ class CommunityController implements IAuthenticationRequired
|
|||||||
|
|
||||||
public function getCommunityHome(): ?IContent
|
public function getCommunityHome(): ?IContent
|
||||||
{
|
{
|
||||||
if (!$this->checkPermission($this->request->query('communityId'), false, $community, $ownCommunityMember)) {
|
if (!$this->checkPermission(\Container::$request->query('communityId'), false, $community, $ownCommunityMember)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HtmlContent('communities/community', [
|
return new HtmlContent('communities/community', [
|
||||||
'community' => $community,
|
'community' => $community,
|
||||||
'members' => $this->getMembers($community),
|
'members' => $this->getMembers($community),
|
||||||
'currencyNames' => [],
|
'currencies' => $this->getCurrencies($community),
|
||||||
'upcomingEvents' => [],
|
'upcomingEvents' => [],
|
||||||
'editPermission' => $ownCommunityMember->getOwner()
|
'editPermission' => $ownCommunityMember->getOwner()
|
||||||
]);
|
]);
|
||||||
@@ -62,7 +64,7 @@ class CommunityController implements IAuthenticationRequired
|
|||||||
|
|
||||||
public function getCommunityEdit(): ?IContent
|
public function getCommunityEdit(): ?IContent
|
||||||
{
|
{
|
||||||
if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) {
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +75,7 @@ class CommunityController implements IAuthenticationRequired
|
|||||||
|
|
||||||
public function getMembersEdit(): ?IContent
|
public function getMembersEdit(): ?IContent
|
||||||
{
|
{
|
||||||
if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) {
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +85,224 @@ class CommunityController implements IAuthenticationRequired
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function saveMember(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$communityMemberId = \Container::$request->query('community_member_id');
|
||||||
|
if ($communityMemberId) {
|
||||||
|
$communityMember = $this->communityMemberRepository->getById($communityMemberId);
|
||||||
|
if ($communityMember->getUserId() === $ownCommunityMember->getUserId()) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => ['errorText' => 'Own user cannot be edited.']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$user = $this->userRepository->getById(\Container::$request->post('user_id'));
|
||||||
|
$communityMember = new CommunityMember();
|
||||||
|
$communityMember->setCommunity($community);
|
||||||
|
$communityMember->setUser($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
$communityMember->setOwner((bool)\Container::$request->post('owner'));
|
||||||
|
\Container::$persistentDataManager->saveToDb($communityMember);
|
||||||
|
|
||||||
|
return new JsonContent(['success' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteMember(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$communityMember = $this->communityMemberRepository->getById(\Container::$request->query('community_member_id'));
|
||||||
|
if ($communityMember->getUserId() === \Container::$request->user()->getUniqueId()) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => ['errorText' => 'Own user cannot be deleted.']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
\Container::$persistentDataManager->deleteFromDb($communityMember);
|
||||||
|
|
||||||
|
return new JsonContent(['success' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCurrenciesEdit(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HtmlContent('communities/community_currencies', [
|
||||||
|
'community' => $community,
|
||||||
|
'currencies' => $this->getCurrencies($community)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveCurrency(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$code = \Container::$request->post('code');
|
||||||
|
$roundDigits = (int)\Container::$request->post('round_digits');
|
||||||
|
if (strlen($code) === 0 || strlen($code) > 3 || $roundDigits < 0 || $roundDigits > 9) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => ['errorText' => 'Please fill all required fields!']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$currencyId = \Container::$request->query('currency_id');
|
||||||
|
if ($currencyId){
|
||||||
|
$currency = $this->currencyRepository->getById($currencyId);
|
||||||
|
} else {
|
||||||
|
$currency = new Currency();
|
||||||
|
$currency->setCommunity($community);
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingCurrency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, $code);
|
||||||
|
if ($existingCurrency !== null && $currency->getId() !== $existingCurrency->getId()) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => ['errorText' => 'A currency with the same code exists for this community.']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$currency->setCode($code);
|
||||||
|
$currency->setRoundDigits($roundDigits);
|
||||||
|
\Container::$persistentDataManager->saveToDb($currency);
|
||||||
|
|
||||||
|
return new JsonContent(['success' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteCurrency(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currency = $this->currencyRepository->getById(\Container::$request->query('currency_id'));
|
||||||
|
\Container::$persistentDataManager->deleteFromDb($currency);
|
||||||
|
|
||||||
|
return new JsonContent(['success' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCurrencyExchangeRates(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, \Container::$request->query('code'));
|
||||||
|
if ($currency === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currencyExchangeRates = $this->currencyExchangeRatesRepository->getAllByCurrency($currency);
|
||||||
|
|
||||||
|
return new HtmlContent('communities/currency_exchange_rates', [
|
||||||
|
'community' => $community,
|
||||||
|
'currency' => $currency,
|
||||||
|
'currencyExchangeRates' => $currencyExchangeRates,
|
||||||
|
'editPermission' => $ownCommunityMember->getOwner()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveCurrencyExchangeRate(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, \Container::$request->query('code'));
|
||||||
|
if ($currency === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$exchangeRate = (float)\Container::$request->post('exchange_rate');
|
||||||
|
if ($exchangeRate < 0) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => ['errorText' => 'Please fill all required fields!']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$currencyExchangeRateId = \Container::$request->query('currency_exchange_rate_id');
|
||||||
|
if ($currencyExchangeRateId){
|
||||||
|
$currencyExchangeRate = $this->currencyExchangeRatesRepository->getById($currencyExchangeRateId);
|
||||||
|
} else {
|
||||||
|
$currencyExchangeRate = new CurrencyExchangeRate();
|
||||||
|
$currencyExchangeRate->setCurrency($currency);
|
||||||
|
}
|
||||||
|
|
||||||
|
$currencyExchangeRate->setExchangeRate($exchangeRate);
|
||||||
|
$currencyExchangeRate->setValidFromDate(new DateTime(\Container::$request->post('valid_from')));
|
||||||
|
\Container::$persistentDataManager->saveToDb($currencyExchangeRate);
|
||||||
|
|
||||||
|
return new JsonContent(['success' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteCurrencyExchangeRate(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currency = $this->currencyRepository->getByCommunityAndCurrencyCode($community, \Container::$request->query('code'));
|
||||||
|
if ($currency === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currencyExchangeRate = $this->currencyExchangeRatesRepository->getById(\Container::$request->query('currency_exchange_rate_id'));
|
||||||
|
\Container::$persistentDataManager->deleteFromDb($currencyExchangeRate);
|
||||||
|
|
||||||
|
return new JsonContent(['success' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveCommunity(): ?IContent
|
||||||
|
{
|
||||||
|
$name = \Container::$request->post('name');
|
||||||
|
$currency = \Container::$request->post('currency');
|
||||||
|
if (strlen($name) === 0 || strlen($currency) === 0 || strlen($currency) > 3) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => ['errorText' => 'Please fill all required fields!']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$communityId = \Container::$request->query('communityId');
|
||||||
|
if ($communityId){
|
||||||
|
if (!$this->checkPermission($communityId, true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$community = new Community();
|
||||||
|
$community->setCreatedDate(new DateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
$community->setName($name);
|
||||||
|
$community->setCurrency($currency);
|
||||||
|
\Container::$persistentDataManager->saveToDb($community);
|
||||||
|
|
||||||
|
if (!$communityId) {
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = \Container::$request->user();
|
||||||
|
|
||||||
|
$communityMember = new CommunityMember();
|
||||||
|
$communityMember->setCommunity($community);
|
||||||
|
$communityMember->setUser($user);
|
||||||
|
$communityMember->setOwner(true);
|
||||||
|
\Container::$persistentDataManager->saveToDb($communityMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JsonContent([
|
||||||
|
'redirect' => ['target' => \Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()])]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
private function getMembers(Community $community): array
|
private function getMembers(Community $community): array
|
||||||
{
|
{
|
||||||
$members = iterator_to_array($this->communityMemberRepository->getAllByCommunity($community, true));
|
$members = iterator_to_array($this->communityMemberRepository->getAllByCommunity($community, true));
|
||||||
@@ -92,102 +312,13 @@ class CommunityController implements IAuthenticationRequired
|
|||||||
return $members;
|
return $members;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getCurrencies(Community $community): array
|
||||||
public function newMember(): ?IContent
|
|
||||||
{
|
{
|
||||||
if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) {
|
$currencies = iterator_to_array($this->currencyRepository->getAllByCommunity($community));
|
||||||
return null;
|
usort($currencies, function($a, $b) {
|
||||||
}
|
return strnatcmp($a->getCode(), $b->getCode());
|
||||||
|
});
|
||||||
$user = $this->userRepository->getById($this->request->post('user_id'));
|
return $currencies;
|
||||||
|
|
||||||
$communityMember = new CommunityMember();
|
|
||||||
$communityMember->setCommunity($community);
|
|
||||||
$communityMember->setUser($user);
|
|
||||||
$this->pdm->saveToDb($communityMember);
|
|
||||||
|
|
||||||
return new JsonContent(['success' => true]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function editMember(): ?IContent
|
|
||||||
{
|
|
||||||
if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$communityMember = $this->communityMemberRepository->getById($this->request->post('community_member_id'));
|
|
||||||
if ($communityMember->getUserId() === $this->request->user()->getUniqueId()) {
|
|
||||||
return new JsonContent([
|
|
||||||
'error' => ['errorText' => 'Own user cannot be edited.']
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$communityMember->setOwner($this->request->post('owner'));
|
|
||||||
$this->pdm->saveToDb($communityMember);
|
|
||||||
|
|
||||||
return new JsonContent(['success' => true]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteMember(): ?IContent
|
|
||||||
{
|
|
||||||
if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$communityMember = $this->communityMemberRepository->getById($this->request->post('community_member_id'));
|
|
||||||
if ($communityMember->getUserId() === $this->request->user()->getUniqueId()) {
|
|
||||||
return new JsonContent([
|
|
||||||
'error' => ['errorText' => 'Own user cannot be deleted.']
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pdm->deleteFromDb($communityMember);
|
|
||||||
|
|
||||||
return new JsonContent(['success' => true]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function saveCommunity(): ?IContent
|
|
||||||
{
|
|
||||||
$communityId = $this->request->query('communityId');
|
|
||||||
if ($communityId){
|
|
||||||
if (!$this->checkPermission($communityId, true, $community, $ownCommunityMember)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$community = new Community();
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = $this->request->post('name');
|
|
||||||
$currency = $this->request->post('currency');
|
|
||||||
if (strlen($name) === 0 || strlen($currency) === 0 || strlen($currency) > 3) {
|
|
||||||
return new JsonContent([
|
|
||||||
'error' => ['errorText' => 'Please fill all required fields!']
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$community->setName($name);
|
|
||||||
$community->setCurrency($currency);
|
|
||||||
if (!$communityId) {
|
|
||||||
$community->setCreatedDate(new DateTime());
|
|
||||||
}
|
|
||||||
$this->pdm->saveToDb($community);
|
|
||||||
|
|
||||||
if (!$communityId) {
|
|
||||||
/**
|
|
||||||
* @var User $user
|
|
||||||
*/
|
|
||||||
$user = $this->request->user();
|
|
||||||
|
|
||||||
$communityMember = new CommunityMember();
|
|
||||||
$communityMember->setCommunity($community);
|
|
||||||
$communityMember->setUser($user);
|
|
||||||
$communityMember->setOwner(true);
|
|
||||||
$this->pdm->saveToDb($communityMember);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new JsonContent([
|
|
||||||
'redirect' => ['target' => \Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()])]
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkPermission(
|
private function checkPermission(
|
||||||
@@ -204,7 +335,7 @@ class CommunityController implements IAuthenticationRequired
|
|||||||
/**
|
/**
|
||||||
* @var User $user
|
* @var User $user
|
||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = \Container::$request->user();
|
||||||
|
|
||||||
$ownCommunityMember = $this->communityMemberRepository->getByCommunityAndUser($community, $user);
|
$ownCommunityMember = $this->communityMemberRepository->getByCommunityAndUser($community, $user);
|
||||||
if ($ownCommunityMember === null || ($needToBeOwner && !$ownCommunityMember->getOwner())) {
|
if ($ownCommunityMember === null || ($needToBeOwner && !$ownCommunityMember->getOwner())) {
|
||||||
|
|||||||
@@ -3,19 +3,15 @@
|
|||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use RVR\Repository\CommunityMemberRepository;
|
use RVR\Repository\CommunityMemberRepository;
|
||||||
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
||||||
use SokoWeb\Interfaces\Request\IRequest;
|
|
||||||
use SokoWeb\Interfaces\Response\IContent;
|
use SokoWeb\Interfaces\Response\IContent;
|
||||||
use SokoWeb\Response\HtmlContent;
|
use SokoWeb\Response\HtmlContent;
|
||||||
|
|
||||||
class HomeController implements IAuthenticationRequired
|
class HomeController implements IAuthenticationRequired
|
||||||
{
|
{
|
||||||
private IRequest $request;
|
|
||||||
|
|
||||||
private CommunityMemberRepository $communityMemberRepository;
|
private CommunityMemberRepository $communityMemberRepository;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
|
||||||
$this->communityMemberRepository = new CommunityMemberRepository();
|
$this->communityMemberRepository = new CommunityMemberRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +25,7 @@ class HomeController implements IAuthenticationRequired
|
|||||||
/**
|
/**
|
||||||
* @var User $user
|
* @var User $user
|
||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = \Container::$request->user();
|
||||||
|
|
||||||
$ownCommunityMembers = $this->communityMemberRepository->getAllByUser($user, true);
|
$ownCommunityMembers = $this->communityMemberRepository->getAllByUser($user, true);
|
||||||
$communities = [];
|
$communities = [];
|
||||||
|
|||||||
@@ -2,13 +2,11 @@
|
|||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use SokoWeb\Http\Request;
|
use SokoWeb\Http\Request;
|
||||||
use SokoWeb\Interfaces\Request\IRequest;
|
|
||||||
use SokoWeb\Interfaces\Response\IContent;
|
use SokoWeb\Interfaces\Response\IContent;
|
||||||
use SokoWeb\Interfaces\Response\IRedirect;
|
use SokoWeb\Interfaces\Response\IRedirect;
|
||||||
use SokoWeb\Mailing\Mail;
|
use SokoWeb\Mailing\Mail;
|
||||||
use SokoWeb\OAuth\GoogleOAuth;
|
use SokoWeb\OAuth\GoogleOAuth;
|
||||||
use RVR\PersistentData\Model\UserPasswordResetter;
|
use RVR\PersistentData\Model\UserPasswordResetter;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use RVR\Repository\UserPasswordResetterRepository;
|
use RVR\Repository\UserPasswordResetterRepository;
|
||||||
use RVR\Repository\UserRepository;
|
use RVR\Repository\UserRepository;
|
||||||
use SokoWeb\Response\HtmlContent;
|
use SokoWeb\Response\HtmlContent;
|
||||||
@@ -19,30 +17,24 @@ use SokoWeb\Util\JwtParser;
|
|||||||
|
|
||||||
class LoginController
|
class LoginController
|
||||||
{
|
{
|
||||||
private IRequest $request;
|
|
||||||
|
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
private UserRepository $userRepository;
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
||||||
|
|
||||||
private string $redirectUrl;
|
private string $redirectUrl;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
$this->userRepository = new UserRepository();
|
$this->userRepository = new UserRepository();
|
||||||
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
||||||
$this->redirectUrl = $this->request->session()->has('redirect_after_login') ?
|
$this->redirectUrl = \Container::$request->session()->has('redirect_after_login') ?
|
||||||
$this->request->session()->get('redirect_after_login') :
|
\Container::$request->session()->get('redirect_after_login') :
|
||||||
\Container::$routeCollection->getRoute('home')->generateLink();
|
\Container::$routeCollection->getRoute('home')->generateLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLoginForm()
|
public function getLoginForm()
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if (\Container::$request->user() !== null) {
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
@@ -55,13 +47,13 @@ class LoginController
|
|||||||
$state = bin2hex(random_bytes(16));
|
$state = bin2hex(random_bytes(16));
|
||||||
$nonce = bin2hex(random_bytes(16));
|
$nonce = bin2hex(random_bytes(16));
|
||||||
|
|
||||||
$this->request->session()->set('oauth_state', $state);
|
\Container::$request->session()->set('oauth_state', $state);
|
||||||
$this->request->session()->set('oauth_nonce', $nonce);
|
\Container::$request->session()->set('oauth_nonce', $nonce);
|
||||||
|
|
||||||
$oAuth = new GoogleOAuth(new Request());
|
$oAuth = new GoogleOAuth(new Request());
|
||||||
$url = $oAuth->getDialogUrl(
|
$url = $oAuth->getDialogUrl(
|
||||||
$state,
|
$state,
|
||||||
$this->request->getBase() . \Container::$routeCollection->getRoute('login-google-action')->generateLink(),
|
\Container::$request->getBase() . \Container::$routeCollection->getRoute('login-google-action')->generateLink(),
|
||||||
$nonce
|
$nonce
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -70,12 +62,12 @@ class LoginController
|
|||||||
|
|
||||||
public function getRequestPasswordResetForm()
|
public function getRequestPasswordResetForm()
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if (\Container::$request->user() !== null) {
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HtmlContent('login/password_reset_request', ['email' => $this->request->query('email')]);
|
return new HtmlContent('login/password_reset_request', ['email' => \Container::$request->query('email')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRequestPasswordResetSuccess(): IContent
|
public function getRequestPasswordResetSuccess(): IContent
|
||||||
@@ -85,12 +77,12 @@ class LoginController
|
|||||||
|
|
||||||
public function getResetPasswordForm()
|
public function getResetPasswordForm()
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if (\Container::$request->user() !== null) {
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = $this->request->query('token');
|
$token = \Container::$request->query('token');
|
||||||
$resetter = $this->userPasswordResetterRepository->getByToken($token);
|
$resetter = $this->userPasswordResetterRepository->getByToken($token);
|
||||||
|
|
||||||
if ($resetter === null || $resetter->getExpiresDate() < new DateTime()) {
|
if ($resetter === null || $resetter->getExpiresDate() < new DateTime()) {
|
||||||
@@ -104,22 +96,22 @@ class LoginController
|
|||||||
|
|
||||||
public function login(): IContent
|
public function login(): IContent
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if (\Container::$request->user() !== null) {
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new JsonContent(['success' => true]);
|
return new JsonContent(['success' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $this->userRepository->getByEmailOrUsername($this->request->post('email'));
|
$user = $this->userRepository->getByEmailOrUsername(\Container::$request->post('email'));
|
||||||
if ($user === null || !$user->checkPassword($this->request->post('password'))) {
|
if ($user === null || !$user->checkPassword(\Container::$request->post('password'))) {
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'error' => [
|
'error' => [
|
||||||
'errorText' => 'No user found with the given email address / username or the given password is wrong. You can <a href="' .
|
'errorText' => 'No user found with the given email address / username or the given password is wrong. You can <a href="' .
|
||||||
\Container::$routeCollection->getRoute('password-requestReset')->generateLink(['email' => $this->request->post('email')]) . '" title="Request password reset">request password reset</a>!'
|
\Container::$routeCollection->getRoute('password-requestReset')->generateLink(['email' => \Container::$request->post('email')]) . '" title="Request password reset">request password reset</a>!'
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->request->setUser($user);
|
\Container::$request->setUser($user);
|
||||||
|
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new JsonContent(['success' => true]);
|
return new JsonContent(['success' => true]);
|
||||||
@@ -129,19 +121,19 @@ class LoginController
|
|||||||
{
|
{
|
||||||
$defaultError = 'Authentication with Google failed. Please <a href="' . \Container::$routeCollection->getRoute('login-google')->generateLink() . '" title="Login with Google">try again</a>!';
|
$defaultError = 'Authentication with Google failed. Please <a href="' . \Container::$routeCollection->getRoute('login-google')->generateLink() . '" title="Login with Google">try again</a>!';
|
||||||
|
|
||||||
if ($this->request->user() !== null) {
|
if (\Container::$request->user() !== null) {
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->request->query('state') !== $this->request->session()->get('oauth_state')) {
|
if (\Container::$request->query('state') !== \Container::$request->session()->get('oauth_state')) {
|
||||||
return new HtmlContent('login/google_login_error', ['error' => $defaultError]);
|
return new HtmlContent('login/google_login_error', ['error' => $defaultError]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oAuth = new GoogleOAuth(new Request());
|
$oAuth = new GoogleOAuth(new Request());
|
||||||
$tokenData = $oAuth->getToken(
|
$tokenData = $oAuth->getToken(
|
||||||
$this->request->query('code'),
|
\Container::$request->query('code'),
|
||||||
$this->request->getBase() . \Container::$routeCollection->getRoute('login-google-action')->generateLink()
|
\Container::$request->getBase() . \Container::$routeCollection->getRoute('login-google-action')->generateLink()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isset($tokenData['id_token'])) {
|
if (!isset($tokenData['id_token'])) {
|
||||||
@@ -151,7 +143,7 @@ class LoginController
|
|||||||
$jwtParser = new JwtParser($tokenData['id_token']);
|
$jwtParser = new JwtParser($tokenData['id_token']);
|
||||||
$idToken = $jwtParser->getPayload();
|
$idToken = $jwtParser->getPayload();
|
||||||
|
|
||||||
if ($idToken['nonce'] !== $this->request->session()->get('oauth_nonce')) {
|
if ($idToken['nonce'] !== \Container::$request->session()->get('oauth_nonce')) {
|
||||||
return new HtmlContent('login/google_login_error', ['error' => $defaultError]);
|
return new HtmlContent('login/google_login_error', ['error' => $defaultError]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +156,7 @@ class LoginController
|
|||||||
return new HtmlContent('login/google_login_error', ['error' => 'No user found for this Google account.']);
|
return new HtmlContent('login/google_login_error', ['error' => 'No user found for this Google account.']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->request->setUser($user);
|
\Container::$request->setUser($user);
|
||||||
|
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
@@ -172,14 +164,14 @@ class LoginController
|
|||||||
|
|
||||||
public function logout(): IRedirect
|
public function logout(): IRedirect
|
||||||
{
|
{
|
||||||
$this->request->setUser(null);
|
\Container::$request->setUser(null);
|
||||||
|
|
||||||
return new Redirect(\Container::$routeCollection->getRoute('home')->generateLink(), IRedirect::TEMPORARY);
|
return new Redirect(\Container::$routeCollection->getRoute('home')->generateLink(), IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function requestPasswordReset(): IContent
|
public function requestPasswordReset(): IContent
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if (\Container::$request->user() !== null) {
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'redirect' => [
|
'redirect' => [
|
||||||
@@ -189,18 +181,18 @@ class LoginController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_ENV['RECAPTCHA_SITEKEY'])) {
|
if (!empty($_ENV['RECAPTCHA_SITEKEY'])) {
|
||||||
if (!$this->request->post('g-recaptcha-response')) {
|
if (!\Container::$request->post('g-recaptcha-response')) {
|
||||||
return new JsonContent(['error' => ['errorText' => 'Please check "I\'m not a robot" in the reCAPTCHA box!']]);
|
return new JsonContent(['error' => ['errorText' => 'Please check "I\'m not a robot" in the reCAPTCHA box!']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$captchaValidator = new CaptchaValidator();
|
$captchaValidator = new CaptchaValidator();
|
||||||
$captchaResponse = $captchaValidator->validate($this->request->post('g-recaptcha-response'));
|
$captchaResponse = $captchaValidator->validate(\Container::$request->post('g-recaptcha-response'));
|
||||||
if (!$captchaResponse['success']) {
|
if (!$captchaResponse['success']) {
|
||||||
return new JsonContent(['error' => ['errorText' => 'reCAPTCHA challenge failed. Please try again!']]);
|
return new JsonContent(['error' => ['errorText' => 'reCAPTCHA challenge failed. Please try again!']]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $this->userRepository->getByEmailOrUsername($this->request->post('email'));
|
$user = $this->userRepository->getByEmailOrUsername(\Container::$request->post('email'));
|
||||||
if ($user === null) {
|
if ($user === null) {
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'error' => [
|
'error' => [
|
||||||
@@ -226,15 +218,11 @@ class LoginController
|
|||||||
$passwordResetter->setToken($token);
|
$passwordResetter->setToken($token);
|
||||||
$passwordResetter->setExpiresDate($expires);
|
$passwordResetter->setExpiresDate($expires);
|
||||||
|
|
||||||
\Container::$dbConnection->startTransaction();
|
|
||||||
|
|
||||||
if ($existingResetter !== null) {
|
if ($existingResetter !== null) {
|
||||||
$this->pdm->deleteFromDb($existingResetter);
|
\Container::$persistentDataManager->deleteFromDb($existingResetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->pdm->saveToDb($passwordResetter);
|
\Container::$persistentDataManager->saveToDb($passwordResetter);
|
||||||
|
|
||||||
\Container::$dbConnection->commit();
|
|
||||||
|
|
||||||
$this->sendPasswordResetEmail($user->getEmail(), $token, $expires);
|
$this->sendPasswordResetEmail($user->getEmail(), $token, $expires);
|
||||||
|
|
||||||
@@ -243,7 +231,7 @@ class LoginController
|
|||||||
|
|
||||||
public function resetPassword(): IContent
|
public function resetPassword(): IContent
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if (\Container::$request->user() !== null) {
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'redirect' => [
|
'redirect' => [
|
||||||
@@ -252,7 +240,7 @@ class LoginController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = $this->request->query('token');
|
$token = \Container::$request->query('token');
|
||||||
$resetter = $this->userPasswordResetterRepository->getByToken($token);
|
$resetter = $this->userPasswordResetterRepository->getByToken($token);
|
||||||
|
|
||||||
if ($resetter === null || $resetter->getExpiresDate() < new DateTime()) {
|
if ($resetter === null || $resetter->getExpiresDate() < new DateTime()) {
|
||||||
@@ -263,7 +251,7 @@ class LoginController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen($this->request->post('password')) < 6) {
|
if (strlen(\Container::$request->post('password')) < 6) {
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'error' => [
|
'error' => [
|
||||||
'errorText' => 'The given password is too short. Please choose a password that is at least 6 characters long!'
|
'errorText' => 'The given password is too short. Please choose a password that is at least 6 characters long!'
|
||||||
@@ -271,22 +259,18 @@ class LoginController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->request->post('password') !== $this->request->post('password_confirm')) {
|
if (\Container::$request->post('password') !== \Container::$request->post('password_confirm')) {
|
||||||
return new JsonContent(['error' => ['errorText' => 'The given passwords do not match.']]);
|
return new JsonContent(['error' => ['errorText' => 'The given passwords do not match.']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
\Container::$dbConnection->startTransaction();
|
\Container::$persistentDataManager->deleteFromDb($resetter);
|
||||||
|
|
||||||
$this->pdm->deleteFromDb($resetter);
|
|
||||||
|
|
||||||
$user = $this->userRepository->getById($resetter->getUserId());
|
$user = $this->userRepository->getById($resetter->getUserId());
|
||||||
$user->setPlainPassword($this->request->post('password'));
|
$user->setPlainPassword(\Container::$request->post('password'));
|
||||||
|
|
||||||
$this->pdm->saveToDb($user);
|
\Container::$persistentDataManager->saveToDb($user);
|
||||||
|
|
||||||
\Container::$dbConnection->commit();
|
\Container::$request->setUser($user);
|
||||||
|
|
||||||
$this->request->setUser($user);
|
|
||||||
|
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new JsonContent(['success' => true]);
|
return new JsonContent(['success' => true]);
|
||||||
@@ -299,7 +283,7 @@ class LoginController
|
|||||||
$mail->setSubject($_ENV['APP_NAME'] . ' - Password reset');
|
$mail->setSubject($_ENV['APP_NAME'] . ' - Password reset');
|
||||||
$mail->setBodyFromTemplate('password-reset', [
|
$mail->setBodyFromTemplate('password-reset', [
|
||||||
'EMAIL' => $email,
|
'EMAIL' => $email,
|
||||||
'RESET_LINK' => $this->request->getBase() .
|
'RESET_LINK' => \Container::$request->getBase() .
|
||||||
\Container::$routeCollection->getRoute('password-reset')->generateLink(['token' => $token]),
|
\Container::$routeCollection->getRoute('password-reset')->generateLink(['token' => $token]),
|
||||||
'EXPIRES' => $expires->format('Y-m-d H:i T')
|
'EXPIRES' => $expires->format('Y-m-d H:i T')
|
||||||
]);
|
]);
|
||||||
@@ -308,6 +292,6 @@ class LoginController
|
|||||||
|
|
||||||
private function deleteRedirectUrl(): void
|
private function deleteRedirectUrl(): void
|
||||||
{
|
{
|
||||||
$this->request->session()->delete('redirect_after_login');
|
\Container::$request->session()->delete('redirect_after_login');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,24 +5,16 @@ use RVR\PersistentData\Model\OAuthToken;
|
|||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use RVR\Repository\OAuthClientRepository;
|
use RVR\Repository\OAuthClientRepository;
|
||||||
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
||||||
use SokoWeb\Interfaces\Request\IRequest;
|
|
||||||
use SokoWeb\Interfaces\Response\IRedirect;
|
use SokoWeb\Interfaces\Response\IRedirect;
|
||||||
use SokoWeb\Response\Redirect;
|
use SokoWeb\Response\Redirect;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use SokoWeb\Response\HtmlContent;
|
use SokoWeb\Response\HtmlContent;
|
||||||
|
|
||||||
class OAuthAuthController implements IAuthenticationRequired
|
class OAuthAuthController implements IAuthenticationRequired
|
||||||
{
|
{
|
||||||
private IRequest $request;
|
|
||||||
|
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
private OAuthClientRepository $oAuthClientRepository;
|
private OAuthClientRepository $oAuthClientRepository;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
$this->oAuthClientRepository = new OAuthClientRepository();
|
$this->oAuthClientRepository = new OAuthClientRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,11 +25,11 @@ class OAuthAuthController implements IAuthenticationRequired
|
|||||||
|
|
||||||
public function auth()
|
public function auth()
|
||||||
{
|
{
|
||||||
$redirectUri = $this->request->query('redirect_uri');
|
$redirectUri = \Container::$request->query('redirect_uri');
|
||||||
$clientId = $this->request->query('client_id');
|
$clientId = \Container::$request->query('client_id');
|
||||||
$scope = $this->request->query('scope') ? $this->request->query('scope'): '';
|
$scope = \Container::$request->query('scope') ? \Container::$request->query('scope'): '';
|
||||||
$state = $this->request->query('state');
|
$state = \Container::$request->query('state');
|
||||||
$nonce = $this->request->query('nonce') ? $this->request->query('nonce'): '';
|
$nonce = \Container::$request->query('nonce') ? \Container::$request->query('nonce'): '';
|
||||||
|
|
||||||
if (!$clientId || !$redirectUri || !$state) {
|
if (!$clientId || !$redirectUri || !$state) {
|
||||||
return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']);
|
return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']);
|
||||||
@@ -62,7 +54,7 @@ class OAuthAuthController implements IAuthenticationRequired
|
|||||||
/**
|
/**
|
||||||
* @var ?User $user
|
* @var ?User $user
|
||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = \Container::$request->user();
|
||||||
$code = bin2hex(random_bytes(16));
|
$code = bin2hex(random_bytes(16));
|
||||||
$accessToken = bin2hex(random_bytes(16));
|
$accessToken = bin2hex(random_bytes(16));
|
||||||
|
|
||||||
@@ -74,7 +66,7 @@ class OAuthAuthController implements IAuthenticationRequired
|
|||||||
$token->setAccessToken($accessToken);
|
$token->setAccessToken($accessToken);
|
||||||
$token->setCreatedDate(new DateTime());
|
$token->setCreatedDate(new DateTime());
|
||||||
$token->setExpiresDate(new DateTime('+5 minutes'));
|
$token->setExpiresDate(new DateTime('+5 minutes'));
|
||||||
$this->pdm->saveToDb($token);
|
\Container::$persistentDataManager->saveToDb($token);
|
||||||
|
|
||||||
$redirectUriQuery = array_merge($redirectUriQuery, [
|
$redirectUriQuery = array_merge($redirectUriQuery, [
|
||||||
'state' => $state,
|
'state' => $state,
|
||||||
|
|||||||
@@ -6,23 +6,19 @@ use RVR\Repository\OAuthTokenRepository;
|
|||||||
use RVR\Repository\UserRepository;
|
use RVR\Repository\UserRepository;
|
||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use RVR\Repository\OAuthClientRepository;
|
use RVR\Repository\OAuthClientRepository;
|
||||||
use SokoWeb\Interfaces\Request\IRequest;
|
|
||||||
use SokoWeb\Interfaces\Response\IContent;
|
use SokoWeb\Interfaces\Response\IContent;
|
||||||
use SokoWeb\Response\JsonContent;
|
use SokoWeb\Response\JsonContent;
|
||||||
|
|
||||||
class OAuthController
|
class OAuthController
|
||||||
{
|
{
|
||||||
private IRequest $request;
|
|
||||||
|
|
||||||
private OAuthClientRepository $oAuthClientRepository;
|
private OAuthClientRepository $oAuthClientRepository;
|
||||||
|
|
||||||
private OAuthTokenRepository $oAuthTokenRepository;
|
private OAuthTokenRepository $oAuthTokenRepository;
|
||||||
|
|
||||||
private UserRepository $userRepository;
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
|
||||||
$this->oAuthClientRepository = new OAuthClientRepository();
|
$this->oAuthClientRepository = new OAuthClientRepository();
|
||||||
$this->oAuthTokenRepository = new OAuthTokenRepository();
|
$this->oAuthTokenRepository = new OAuthTokenRepository();
|
||||||
$this->userRepository = new UserRepository();
|
$this->userRepository = new UserRepository();
|
||||||
@@ -30,9 +26,9 @@ class OAuthController
|
|||||||
|
|
||||||
public function getToken(): ?IContent
|
public function getToken(): ?IContent
|
||||||
{
|
{
|
||||||
$clientId = $this->request->post('client_id');
|
$clientId = \Container::$request->post('client_id');
|
||||||
$clientSecret = $this->request->post('client_secret');
|
$clientSecret = \Container::$request->post('client_secret');
|
||||||
$code = $this->request->post('code');
|
$code = \Container::$request->post('code');
|
||||||
|
|
||||||
if (!$clientId || !$clientSecret || !$code) {
|
if (!$clientId || !$clientSecret || !$code) {
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
@@ -80,7 +76,7 @@ class OAuthController
|
|||||||
|
|
||||||
public function getUserInfo() : IContent
|
public function getUserInfo() : IContent
|
||||||
{
|
{
|
||||||
$authorization = $this->request->header('Authorization');
|
$authorization = \Container::$request->header('Authorization');
|
||||||
if ($authorization === null) {
|
if ($authorization === null) {
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'error' => 'No Authorization header was sent.'
|
'error' => 'No Authorization header was sent.'
|
||||||
@@ -108,10 +104,10 @@ class OAuthController
|
|||||||
{
|
{
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'issuer' => $_ENV['APP_URL'],
|
'issuer' => $_ENV['APP_URL'],
|
||||||
'authorization_endpoint' => $this->request->getBase() . \Container::$routeCollection->getRoute('oauth-auth')->generateLink(),
|
'authorization_endpoint' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('oauth-auth')->generateLink(),
|
||||||
'token_endpoint' => $this->request->getBase() . \Container::$routeCollection->getRoute('oauth-token')->generateLink(),
|
'token_endpoint' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('oauth-token')->generateLink(),
|
||||||
'userinfo_endpoint' => $this->request->getBase() . \Container::$routeCollection->getRoute('oauth-userinfo')->generateLink(),
|
'userinfo_endpoint' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('oauth-userinfo')->generateLink(),
|
||||||
'jwks_uri' => $this->request->getBase() . \Container::$routeCollection->getRoute('oauth-certs')->generateLink(),
|
'jwks_uri' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('oauth-certs')->generateLink(),
|
||||||
'response_types_supported' =>
|
'response_types_supported' =>
|
||||||
[
|
[
|
||||||
'code',
|
'code',
|
||||||
|
|||||||
@@ -3,11 +3,9 @@
|
|||||||
use DateTime;
|
use DateTime;
|
||||||
use SokoWeb\Http\Request;
|
use SokoWeb\Http\Request;
|
||||||
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
||||||
use SokoWeb\Interfaces\Request\IRequest;
|
|
||||||
use SokoWeb\Interfaces\Response\IContent;
|
use SokoWeb\Interfaces\Response\IContent;
|
||||||
use SokoWeb\Interfaces\Response\IRedirect;
|
use SokoWeb\Interfaces\Response\IRedirect;
|
||||||
use SokoWeb\OAuth\GoogleOAuth;
|
use SokoWeb\OAuth\GoogleOAuth;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use SokoWeb\Response\HtmlContent;
|
use SokoWeb\Response\HtmlContent;
|
||||||
use SokoWeb\Response\JsonContent;
|
use SokoWeb\Response\JsonContent;
|
||||||
@@ -17,16 +15,10 @@ use RVR\Repository\UserRepository;
|
|||||||
|
|
||||||
class UserController implements IAuthenticationRequired
|
class UserController implements IAuthenticationRequired
|
||||||
{
|
{
|
||||||
private IRequest $request;
|
|
||||||
|
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
private UserRepository $userRepository;
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
$this->userRepository = new UserRepository();
|
$this->userRepository = new UserRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +32,7 @@ class UserController implements IAuthenticationRequired
|
|||||||
/**
|
/**
|
||||||
* @var User $user
|
* @var User $user
|
||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = \Container::$request->user();
|
||||||
|
|
||||||
return new HtmlContent('account/account', ['user' => $user->toArray()]);
|
return new HtmlContent('account/account', ['user' => $user->toArray()]);
|
||||||
}
|
}
|
||||||
@@ -50,19 +42,19 @@ class UserController implements IAuthenticationRequired
|
|||||||
/**
|
/**
|
||||||
* @var User $user
|
* @var User $user
|
||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = \Container::$request->user();
|
||||||
|
|
||||||
$state = bin2hex(random_bytes(16));
|
$state = bin2hex(random_bytes(16));
|
||||||
$nonce = bin2hex(random_bytes(16));
|
$nonce = bin2hex(random_bytes(16));
|
||||||
|
|
||||||
$this->request->session()->set('oauth_state', $state);
|
\Container::$request->session()->set('oauth_state', $state);
|
||||||
$this->request->session()->set('oauth_nonce', $nonce);
|
\Container::$request->session()->set('oauth_nonce', $nonce);
|
||||||
|
|
||||||
$oAuth = new GoogleOAuth(new Request());
|
$oAuth = new GoogleOAuth(new Request());
|
||||||
|
|
||||||
$url = $oAuth->getDialogUrl(
|
$url = $oAuth->getDialogUrl(
|
||||||
$state,
|
$state,
|
||||||
$this->request->getBase() . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink(),
|
\Container::$request->getBase() . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink(),
|
||||||
$nonce,
|
$nonce,
|
||||||
$user->getEmail()
|
$user->getEmail()
|
||||||
);
|
);
|
||||||
@@ -75,16 +67,16 @@ class UserController implements IAuthenticationRequired
|
|||||||
/**
|
/**
|
||||||
* @var User $user
|
* @var User $user
|
||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = \Container::$request->user();
|
||||||
|
|
||||||
if ($this->request->query('state') !== $this->request->session()->get('oauth_state')) {
|
if (\Container::$request->query('state') !== \Container::$request->session()->get('oauth_state')) {
|
||||||
return new HtmlContent('account/google_authenticate', ['success' => false]);
|
return new HtmlContent('account/google_authenticate', ['success' => false]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oAuth = new GoogleOAuth(new Request());
|
$oAuth = new GoogleOAuth(new Request());
|
||||||
$tokenData = $oAuth->getToken(
|
$tokenData = $oAuth->getToken(
|
||||||
$this->request->query('code'),
|
\Container::$request->query('code'),
|
||||||
$this->request->getBase() . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink()
|
\Container::$request->getBase() . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isset($tokenData['id_token'])) {
|
if (!isset($tokenData['id_token'])) {
|
||||||
@@ -94,7 +86,7 @@ class UserController implements IAuthenticationRequired
|
|||||||
$jwtParser = new JwtParser($tokenData['id_token']);
|
$jwtParser = new JwtParser($tokenData['id_token']);
|
||||||
$idToken = $jwtParser->getPayload();
|
$idToken = $jwtParser->getPayload();
|
||||||
|
|
||||||
if ($idToken['nonce'] !== $this->request->session()->get('oauth_nonce')) {
|
if ($idToken['nonce'] !== \Container::$request->session()->get('oauth_nonce')) {
|
||||||
return new HtmlContent('account/google_authenticate', ['success' => false]);
|
return new HtmlContent('account/google_authenticate', ['success' => false]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +98,7 @@ class UserController implements IAuthenticationRequired
|
|||||||
}
|
}
|
||||||
|
|
||||||
$authenticatedWithGoogleUntil = new DateTime('+45 seconds');
|
$authenticatedWithGoogleUntil = new DateTime('+45 seconds');
|
||||||
$this->request->session()->set('authenticated_with_google_until', $authenticatedWithGoogleUntil);
|
\Container::$request->session()->set('authenticated_with_google_until', $authenticatedWithGoogleUntil);
|
||||||
|
|
||||||
return new HtmlContent('account/google_authenticate', [
|
return new HtmlContent('account/google_authenticate', [
|
||||||
'success' => true,
|
'success' => true,
|
||||||
@@ -119,18 +111,18 @@ class UserController implements IAuthenticationRequired
|
|||||||
/**
|
/**
|
||||||
* @var User $user
|
* @var User $user
|
||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = \Container::$request->user();
|
||||||
|
|
||||||
if (!$this->confirmUserIdentity(
|
if (!$this->confirmUserIdentity(
|
||||||
$user,
|
$user,
|
||||||
$this->request->session()->get('authenticated_with_google_until'),
|
\Container::$request->session()->get('authenticated_with_google_until'),
|
||||||
$this->request->post('password'),
|
\Container::$request->post('password'),
|
||||||
$error
|
$error
|
||||||
)) {
|
)) {
|
||||||
return new JsonContent(['error' => ['errorText' => $error]]);
|
return new JsonContent(['error' => ['errorText' => $error]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$newEmail = $this->request->post('email');
|
$newEmail = \Container::$request->post('email');
|
||||||
if ($newEmail !== $user->getEmail()) {
|
if ($newEmail !== $user->getEmail()) {
|
||||||
if (!filter_var($newEmail, FILTER_VALIDATE_EMAIL)) {
|
if (!filter_var($newEmail, FILTER_VALIDATE_EMAIL)) {
|
||||||
return new JsonContent(['error' => ['errorText' => 'Please provide a valid email address.']]);
|
return new JsonContent(['error' => ['errorText' => 'Please provide a valid email address.']]);
|
||||||
@@ -143,7 +135,7 @@ class UserController implements IAuthenticationRequired
|
|||||||
$user->setEmail($newEmail);
|
$user->setEmail($newEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
$newUsername = $this->request->post('username');
|
$newUsername = \Container::$request->post('username');
|
||||||
if ($newUsername !== $user->getUsername()) {
|
if ($newUsername !== $user->getUsername()) {
|
||||||
if (strlen($newUsername) > 0) {
|
if (strlen($newUsername) > 0) {
|
||||||
if (filter_var($newUsername, FILTER_VALIDATE_EMAIL)) {
|
if (filter_var($newUsername, FILTER_VALIDATE_EMAIL)) {
|
||||||
@@ -160,7 +152,7 @@ class UserController implements IAuthenticationRequired
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$newPassword = $this->request->post('password_new');
|
$newPassword = \Container::$request->post('password_new');
|
||||||
if (strlen($newPassword) > 0) {
|
if (strlen($newPassword) > 0) {
|
||||||
if (strlen($newPassword) < 6) {
|
if (strlen($newPassword) < 6) {
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
@@ -170,7 +162,7 @@ class UserController implements IAuthenticationRequired
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($newPassword !== $this->request->post('password_new_confirm')) {
|
if ($newPassword !== \Container::$request->post('password_new_confirm')) {
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'error' => [
|
'error' => [
|
||||||
'errorText' => 'The given new passwords do not match.'
|
'errorText' => 'The given new passwords do not match.'
|
||||||
@@ -181,13 +173,13 @@ class UserController implements IAuthenticationRequired
|
|||||||
$user->setPlainPassword($newPassword);
|
$user->setPlainPassword($newPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->setNickname($this->request->post('nickname'));
|
$user->setNickname(\Container::$request->post('nickname'));
|
||||||
$user->setPhone($this->request->post('phone'));
|
$user->setPhone(\Container::$request->post('phone'));
|
||||||
$user->setIdNumber($this->request->post('id_number'));
|
$user->setIdNumber(\Container::$request->post('id_number'));
|
||||||
|
|
||||||
$this->pdm->saveToDb($user);
|
\Container::$persistentDataManager->saveToDb($user);
|
||||||
|
|
||||||
$this->request->session()->delete('authenticated_with_google_until');
|
\Container::$request->session()->delete('authenticated_with_google_until');
|
||||||
|
|
||||||
return new JsonContent(['success' => true]);
|
return new JsonContent(['success' => true]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,19 +2,15 @@
|
|||||||
|
|
||||||
use RVR\Repository\UserRepository;
|
use RVR\Repository\UserRepository;
|
||||||
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
||||||
use SokoWeb\Interfaces\Request\IRequest;
|
|
||||||
use SokoWeb\Interfaces\Response\IContent;
|
use SokoWeb\Interfaces\Response\IContent;
|
||||||
use SokoWeb\Response\JsonContent;
|
use SokoWeb\Response\JsonContent;
|
||||||
|
|
||||||
class UserSearchController implements IAuthenticationRequired
|
class UserSearchController implements IAuthenticationRequired
|
||||||
{
|
{
|
||||||
private IRequest $request;
|
|
||||||
|
|
||||||
private UserRepository $userRepository;
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
|
||||||
$this->userRepository = new UserRepository();
|
$this->userRepository = new UserRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +21,7 @@ class UserSearchController implements IAuthenticationRequired
|
|||||||
|
|
||||||
public function searchUser(): IContent
|
public function searchUser(): IContent
|
||||||
{
|
{
|
||||||
$users = iterator_to_array($this->userRepository->searchByName($this->request->query('q')));
|
$users = iterator_to_array($this->userRepository->searchByName(\Container::$request->query('q')));
|
||||||
usort($users, function($a, $b) {
|
usort($users, function($a, $b) {
|
||||||
return strnatcmp($a->getDisplayName(), $b->getDisplayName());
|
return strnatcmp($a->getDisplayName(), $b->getDisplayName());
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php namespace RVR\Database;
|
||||||
|
|
||||||
|
use SokoWeb\Database\AuditLoggerBase;
|
||||||
|
|
||||||
|
class AuditLogger extends AuditLoggerBase
|
||||||
|
{
|
||||||
|
protected function getModifierId()
|
||||||
|
{
|
||||||
|
$user = \Container::$request->user();
|
||||||
|
if ($user === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $user->getUniqueId();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<?php namespace RVR\PersistentData\Model;
|
||||||
|
|
||||||
|
use SokoWeb\PersistentData\Model\Model;
|
||||||
|
|
||||||
|
class Currency extends Model
|
||||||
|
{
|
||||||
|
protected static string $table = 'currencies';
|
||||||
|
|
||||||
|
protected static array $fields = ['community_id', 'code', 'round_digits'];
|
||||||
|
|
||||||
|
protected static array $relations = ['community' => Community::class];
|
||||||
|
|
||||||
|
private ?Community $community = null;
|
||||||
|
|
||||||
|
private ?int $communityId = null;
|
||||||
|
|
||||||
|
private string $code = '';
|
||||||
|
|
||||||
|
private int $roundDigits = 0;
|
||||||
|
|
||||||
|
public function setCommunity(Community $community): void
|
||||||
|
{
|
||||||
|
$this->community = $community;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCommunityId(int $communityId): void
|
||||||
|
{
|
||||||
|
$this->communityId = $communityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCode(string $code): void
|
||||||
|
{
|
||||||
|
$this->code = $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRoundDigits(int $roundDigits): void
|
||||||
|
{
|
||||||
|
$this->roundDigits = $roundDigits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommunity(): ?Community
|
||||||
|
{
|
||||||
|
return $this->community;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommunityId(): ?int
|
||||||
|
{
|
||||||
|
return $this->communityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode(): string
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoundDigits(): int
|
||||||
|
{
|
||||||
|
return $this->roundDigits;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<?php namespace RVR\PersistentData\Model;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use SokoWeb\PersistentData\Model\Model;
|
||||||
|
|
||||||
|
class CurrencyExchangeRate extends Model
|
||||||
|
{
|
||||||
|
protected static string $table = 'currency_exchange_rates';
|
||||||
|
|
||||||
|
protected static array $fields = ['currency_id', 'exchange_rate', 'valid_from'];
|
||||||
|
|
||||||
|
protected static array $relations = ['currency' => Currency::class];
|
||||||
|
|
||||||
|
private ?Currency $currency = null;
|
||||||
|
|
||||||
|
private ?int $currencyId = null;
|
||||||
|
|
||||||
|
private float $exchangeRate = 0.0;
|
||||||
|
|
||||||
|
private DateTime $validFrom;
|
||||||
|
|
||||||
|
public function setCurrency(Currency $currency): void
|
||||||
|
{
|
||||||
|
$this->currency = $currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCurrencyId(int $currencyId): void
|
||||||
|
{
|
||||||
|
$this->currencyId = $currencyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setExchangeRate(float $exchangeRate): void
|
||||||
|
{
|
||||||
|
$this->exchangeRate = $exchangeRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValidFromDate(DateTime $validFrom): void
|
||||||
|
{
|
||||||
|
$this->validFrom = $validFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValidFrom(string $validFrom): void
|
||||||
|
{
|
||||||
|
$this->validFrom = new DateTime($validFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCurrency(): ?Currency
|
||||||
|
{
|
||||||
|
return $this->currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCurrencyId(): ?int
|
||||||
|
{
|
||||||
|
return $this->currencyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExchangeRate(): float
|
||||||
|
{
|
||||||
|
return $this->exchangeRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidFromDate(): DateTime
|
||||||
|
{
|
||||||
|
return $this->validFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidFrom(): string
|
||||||
|
{
|
||||||
|
return $this->validFrom->format('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,20 +5,12 @@ use RVR\PersistentData\Model\Community;
|
|||||||
use RVR\PersistentData\Model\CommunityMember;
|
use RVR\PersistentData\Model\CommunityMember;
|
||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use SokoWeb\Database\Query\Select;
|
use SokoWeb\Database\Query\Select;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
|
|
||||||
class CommunityMemberRepository
|
class CommunityMemberRepository
|
||||||
{
|
{
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getById(int $id): ?CommunityMember
|
public function getById(int $id): ?CommunityMember
|
||||||
{
|
{
|
||||||
return $this->pdm->selectFromDbById($id, CommunityMember::class);
|
return \Container::$persistentDataManager->selectFromDbById($id, CommunityMember::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllByCommunity(Community $community, bool $useRelations = false): Generator
|
public function getAllByCommunity(Community $community, bool $useRelations = false): Generator
|
||||||
@@ -26,7 +18,7 @@ class CommunityMemberRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('community_id', '=', $community->getId());
|
$select->where('community_id', '=', $community->getId());
|
||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, CommunityMember::class, $useRelations);
|
yield from \Container::$persistentDataManager->selectMultipleFromDb($select, CommunityMember::class, $useRelations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllByUser(User $user, bool $useRelations = false): Generator
|
public function getAllByUser(User $user, bool $useRelations = false): Generator
|
||||||
@@ -34,7 +26,7 @@ class CommunityMemberRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('user_id', '=', $user->getId());
|
$select->where('user_id', '=', $user->getId());
|
||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, CommunityMember::class, $useRelations);
|
yield from \Container::$persistentDataManager->selectMultipleFromDb($select, CommunityMember::class, $useRelations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByCommunityAndUser(Community $community, User $user) : ?CommunityMember
|
public function getByCommunityAndUser(Community $community, User $user) : ?CommunityMember
|
||||||
@@ -43,6 +35,6 @@ class CommunityMemberRepository
|
|||||||
$select->where('community_id', '=', $community->getId());
|
$select->where('community_id', '=', $community->getId());
|
||||||
$select->where('user_id', '=', $user->getId());
|
$select->where('user_id', '=', $user->getId());
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, CommunityMember::class);
|
return \Container::$persistentDataManager->selectFromDb($select, CommunityMember::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,11 @@
|
|||||||
<?php namespace RVR\Repository;
|
<?php namespace RVR\Repository;
|
||||||
|
|
||||||
use RVR\PersistentData\Model\Community;
|
use RVR\PersistentData\Model\Community;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
|
|
||||||
class CommunityRepository
|
class CommunityRepository
|
||||||
{
|
{
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getById(int $id): ?Community
|
public function getById(int $id): ?Community
|
||||||
{
|
{
|
||||||
return $this->pdm->selectFromDbById($id, Community::class);
|
return \Container::$persistentDataManager->selectFromDbById($id, Community::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?php namespace RVR\Repository;
|
||||||
|
|
||||||
|
use Generator;
|
||||||
|
use Container;
|
||||||
|
use RVR\PersistentData\Model\Currency;
|
||||||
|
use RVR\PersistentData\Model\CurrencyExchangeRate;
|
||||||
|
use SokoWeb\Database\Query\Select;
|
||||||
|
|
||||||
|
class CurrencyExchangeRateRepository
|
||||||
|
{
|
||||||
|
public function getById(int $id): ?CurrencyExchangeRate
|
||||||
|
{
|
||||||
|
return \Container::$persistentDataManager->selectFromDbById($id, CurrencyExchangeRate::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllByCurrency(Currency $currency): Generator
|
||||||
|
{
|
||||||
|
$select = new Select(Container::$dbConnection);
|
||||||
|
$select->where('currency_id', '=', $currency->getId());
|
||||||
|
$select->orderBy('valid_from');
|
||||||
|
|
||||||
|
yield from Container::$persistentDataManager->selectMultipleFromDb($select, CurrencyExchangeRate::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php namespace RVR\Repository;
|
||||||
|
|
||||||
|
use Generator;
|
||||||
|
use Container;
|
||||||
|
use RVR\PersistentData\Model\Community;
|
||||||
|
use RVR\PersistentData\Model\Currency;
|
||||||
|
use SokoWeb\Database\Query\Select;
|
||||||
|
|
||||||
|
class CurrencyRepository
|
||||||
|
{
|
||||||
|
public function getById(int $id): ?Currency
|
||||||
|
{
|
||||||
|
return \Container::$persistentDataManager->selectFromDbById($id, Currency::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllByCommunity(Community $community, bool $useRelations = false): Generator
|
||||||
|
{
|
||||||
|
$select = new Select(Container::$dbConnection);
|
||||||
|
$select->where('community_id', '=', $community->getId());
|
||||||
|
|
||||||
|
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Currency::class, $useRelations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByCommunityAndCurrencyCode(Community $community, string $code): ?Currency
|
||||||
|
{
|
||||||
|
$select = new Select(Container::$dbConnection);
|
||||||
|
$select->where('community_id', '=', $community->getId());
|
||||||
|
$select->where('code', '=', $code);
|
||||||
|
|
||||||
|
return Container::$persistentDataManager->selectFromDb($select, Currency::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,20 +2,12 @@
|
|||||||
|
|
||||||
use SokoWeb\Database\Query\Select;
|
use SokoWeb\Database\Query\Select;
|
||||||
use RVR\PersistentData\Model\OAuthClient;
|
use RVR\PersistentData\Model\OAuthClient;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
|
|
||||||
class OAuthClientRepository
|
class OAuthClientRepository
|
||||||
{
|
{
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getById(int $id): ?OAuthClient
|
public function getById(int $id): ?OAuthClient
|
||||||
{
|
{
|
||||||
return $this->pdm->selectFromDbById($id, OAuthClient::class);
|
return \Container::$persistentDataManager->selectFromDbById($id, OAuthClient::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByClientId(string $clientId): ?OAuthClient
|
public function getByClientId(string $clientId): ?OAuthClient
|
||||||
@@ -23,6 +15,6 @@ class OAuthClientRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('client_id', '=', $clientId);
|
$select->where('client_id', '=', $clientId);
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, OAuthClient::class);
|
return \Container::$persistentDataManager->selectFromDb($select, OAuthClient::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,20 +4,12 @@ use DateTime;
|
|||||||
use Generator;
|
use Generator;
|
||||||
use SokoWeb\Database\Query\Select;
|
use SokoWeb\Database\Query\Select;
|
||||||
use RVR\PersistentData\Model\OAuthToken;
|
use RVR\PersistentData\Model\OAuthToken;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
|
|
||||||
class OAuthTokenRepository
|
class OAuthTokenRepository
|
||||||
{
|
{
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getById(int $id): ?OAuthToken
|
public function getById(int $id): ?OAuthToken
|
||||||
{
|
{
|
||||||
return $this->pdm->selectFromDbById($id, OAuthToken::class);
|
return \Container::$persistentDataManager->selectFromDbById($id, OAuthToken::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByCode(string $code): ?OAuthToken
|
public function getByCode(string $code): ?OAuthToken
|
||||||
@@ -25,7 +17,7 @@ class OAuthTokenRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('code', '=', $code);
|
$select->where('code', '=', $code);
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, OAuthToken::class);
|
return \Container::$persistentDataManager->selectFromDb($select, OAuthToken::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByAccessToken(string $accessToken): ?OAuthToken
|
public function getByAccessToken(string $accessToken): ?OAuthToken
|
||||||
@@ -33,7 +25,7 @@ class OAuthTokenRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('access_token', '=', $accessToken);
|
$select->where('access_token', '=', $accessToken);
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, OAuthToken::class);
|
return \Container::$persistentDataManager->selectFromDb($select, OAuthToken::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllExpired(): Generator
|
public function getAllExpired(): Generator
|
||||||
@@ -41,6 +33,6 @@ class OAuthTokenRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('expires', '<', (new DateTime())->format('Y-m-d H:i:s'));
|
$select->where('expires', '<', (new DateTime())->format('Y-m-d H:i:s'));
|
||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, OAuthToken::class);
|
yield from \Container::$persistentDataManager->selectMultipleFromDb($select, OAuthToken::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,20 +5,12 @@ use Generator;
|
|||||||
use SokoWeb\Database\Query\Select;
|
use SokoWeb\Database\Query\Select;
|
||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use RVR\PersistentData\Model\UserPasswordResetter;
|
use RVR\PersistentData\Model\UserPasswordResetter;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
|
|
||||||
class UserPasswordResetterRepository
|
class UserPasswordResetterRepository
|
||||||
{
|
{
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getById(int $userConfirmationId): ?UserPasswordResetter
|
public function getById(int $userConfirmationId): ?UserPasswordResetter
|
||||||
{
|
{
|
||||||
return $this->pdm->selectFromDbById($userConfirmationId, UserPasswordResetter::class);
|
return \Container::$persistentDataManager->selectFromDbById($userConfirmationId, UserPasswordResetter::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByToken(string $token): ?UserPasswordResetter
|
public function getByToken(string $token): ?UserPasswordResetter
|
||||||
@@ -26,7 +18,7 @@ class UserPasswordResetterRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('token', '=', $token);
|
$select->where('token', '=', $token);
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, UserPasswordResetter::class);
|
return \Container::$persistentDataManager->selectFromDb($select, UserPasswordResetter::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByUser(User $user): ?UserPasswordResetter
|
public function getByUser(User $user): ?UserPasswordResetter
|
||||||
@@ -34,7 +26,7 @@ class UserPasswordResetterRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('user_id', '=', $user->getId());
|
$select->where('user_id', '=', $user->getId());
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, UserPasswordResetter::class);
|
return \Container::$persistentDataManager->selectFromDb($select, UserPasswordResetter::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllExpired(): Generator
|
public function getAllExpired(): Generator
|
||||||
@@ -42,6 +34,6 @@ class UserPasswordResetterRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('expires', '<', (new DateTime())->format('Y-m-d H:i:s'));
|
$select->where('expires', '<', (new DateTime())->format('Y-m-d H:i:s'));
|
||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, UserPasswordResetter::class);
|
yield from \Container::$persistentDataManager->selectMultipleFromDb($select, UserPasswordResetter::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,20 +4,12 @@ use Generator;
|
|||||||
use SokoWeb\Interfaces\Repository\IUserRepository;
|
use SokoWeb\Interfaces\Repository\IUserRepository;
|
||||||
use SokoWeb\Database\Query\Select;
|
use SokoWeb\Database\Query\Select;
|
||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use SokoWeb\PersistentData\PersistentDataManager;
|
|
||||||
|
|
||||||
class UserRepository implements IUserRepository
|
class UserRepository implements IUserRepository
|
||||||
{
|
{
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getById(int $userId): ?User
|
public function getById(int $userId): ?User
|
||||||
{
|
{
|
||||||
return $this->pdm->selectFromDbById($userId, User::class);
|
return \Container::$persistentDataManager->selectFromDbById($userId, User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByEmail(string $email): ?User
|
public function getByEmail(string $email): ?User
|
||||||
@@ -25,7 +17,7 @@ class UserRepository implements IUserRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('email', '=', $email);
|
$select->where('email', '=', $email);
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, User::class);
|
return \Container::$persistentDataManager->selectFromDb($select, User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByUsername(string $username): ?User
|
public function getByUsername(string $username): ?User
|
||||||
@@ -33,7 +25,7 @@ class UserRepository implements IUserRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('username', '=', $username);
|
$select->where('username', '=', $username);
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, User::class);
|
return \Container::$persistentDataManager->selectFromDb($select, User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getByEmailOrUsername(string $emailOrUsername): ?User
|
public function getByEmailOrUsername(string $emailOrUsername): ?User
|
||||||
@@ -50,7 +42,7 @@ class UserRepository implements IUserRepository
|
|||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
$select->where('google_sub', '=', $sub);
|
$select->where('google_sub', '=', $sub);
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, User::class);
|
return \Container::$persistentDataManager->selectFromDb($select, User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function searchByName(string $name): Generator
|
public function searchByName(string $name): Generator
|
||||||
@@ -60,6 +52,6 @@ class UserRepository implements IUserRepository
|
|||||||
$select->orWhere('nickname', 'LIKE', '%' . $name . '%');
|
$select->orWhere('nickname', 'LIKE', '%' . $name . '%');
|
||||||
$select->limit(10);
|
$select->limit(10);
|
||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, User::class);
|
yield from \Container::$persistentDataManager->selectMultipleFromDb($select, User::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,17 @@
|
|||||||
<div>
|
<div>
|
||||||
<h3 class="marginBottom">Currencies</h3>
|
<h3 class="marginBottom">Currencies</h3>
|
||||||
<p>Main currency: <b><?= $community->getCurrency() ?></b></p>
|
<p>Main currency: <b><?= $community->getCurrency() ?></b></p>
|
||||||
<p>Further currencies: <b><?= implode(', ', $currencyNames) ?></b></p>
|
<?php if (count($currencies) > 0): ?>
|
||||||
|
<p>Further currencies: <b>
|
||||||
|
<?php foreach ($currencies as $currency): ?>
|
||||||
|
<a href="<?= Container::$routeCollection->getRoute('community-currency-exchange-rates')->generateLink(['communityId' => $community->getId(), 'code' => $currency->getCode()]) ?>"><?= $currency->getCode() ?></a>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</b></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($editPermission): ?>
|
||||||
|
<hr>
|
||||||
|
<p><a href="<?= Container::$routeCollection->getRoute('community-currencies')->generateLink(['communityId' => $community->getId()]) ?>">Edit currencies</a></p>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="marginBottom">Upcoming events</h3>
|
<h3 class="marginBottom">Upcoming events</h3>
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
@extends(templates/layout_normal)
|
||||||
|
|
||||||
|
@section(main)
|
||||||
|
<h2><a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()]) ?>"><?= $community->getName() ?></a> - Edit currencies</h2>
|
||||||
|
<div class="box">
|
||||||
|
<table class="fullWidth">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: calc(100% / 3); text-align: left;">Currency</th>
|
||||||
|
<th style="width: calc(100% / 3); text-align: left;">Round digits</th>
|
||||||
|
<th style="width: calc(100% / 3);"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<?php foreach ($currencies as $currency): ?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<form id="editCurrency_<?= $currency->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-currencies-edit')->generateLink(['communityId' => $community->getId(), 'currency_id' => $currency->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="code,round_digits"></form>
|
||||||
|
<form id="deleteCurrency_<?= $currency->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-currencies-delete')->generateLink(['communityId' => $community->getId(), 'currency_id' => $currency->getId()]) ?>" method="post" data-reload-on-success="true"></form>
|
||||||
|
<input type="text" form="editCurrency_<?= $currency->getId() ?>" class="text fullWidth" name="code" value="<?= $currency->getCode() ?>" maxlength="3" required>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="number" form="editCurrency_<?= $currency->getId() ?>" class="text fullWidth" name="round_digits" value="<?= $currency->getRoundDigits() ?>" min="0" max="9" required>
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<button type="submit" form="editCurrency_<?= $currency->getId() ?>" name="submit" class="small marginRight" disabled>Save</button><!--
|
||||||
|
--><button type="submit" form="deleteCurrency_<?= $currency->getId() ?>" class="small red">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<form id="newCurrency" action="<?= Container::$routeCollection->getRoute('community-currencies-new')->generateLink(['communityId' => $community->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="code,round_digits"></form>
|
||||||
|
<input type="text" form="newCurrency" class="text fullWidth" name="code" placeholder="Currency" maxlength="3" required>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="number" form="newCurrency" class="text fullWidth" name="round_digits" placeholder="Round digits" min="0" max="9" required>
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<button type="submit" form="newCurrency" name="submit" class="small" disabled>Add</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p class="formError justify marginTop"></p>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
@extends(templates/layout_normal)
|
@extends(templates/layout_normal)
|
||||||
|
|
||||||
@section(main)
|
@section(main)
|
||||||
<h2><?= isset($community) ? $community->getName() . ' - Edit' : 'New community' ?></h2>
|
<h2>
|
||||||
|
<?php if (isset($community)): ?>
|
||||||
|
<a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()]) ?>"><?= $community->getName() ?></a> - Edit
|
||||||
|
<?php else: ?>
|
||||||
|
New community
|
||||||
|
<?php endif; ?>
|
||||||
|
</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<?php
|
<?php
|
||||||
$formAction = isset($community) ?
|
$formAction = isset($community) ?
|
||||||
@@ -11,7 +17,7 @@
|
|||||||
<form id="communityForm" action="<?= $formAction ?>" method="post" data-redirect-on-success="true">
|
<form id="communityForm" action="<?= $formAction ?>" method="post" data-redirect-on-success="true">
|
||||||
<input type="text" class="text big fullWidth" name="name" placeholder="Name" value="<?= isset($community) ? $community->getName() : '' ?>" required>
|
<input type="text" class="text big fullWidth" name="name" placeholder="Name" value="<?= isset($community) ? $community->getName() : '' ?>" required>
|
||||||
<input type="text" class="text big fullWidth marginTop" name="currency" value="<?= isset($community) ? $community->getCurrency() : '' ?>" placeholder="Default currency" maxlength="3" required>
|
<input type="text" class="text big fullWidth marginTop" name="currency" value="<?= isset($community) ? $community->getCurrency() : '' ?>" placeholder="Default currency" maxlength="3" required>
|
||||||
<p id="accountFormError" class="formError justify marginTop"></p>
|
<p id="communityFormError" class="formError justify marginTop"></p>
|
||||||
<div class="right marginTop">
|
<div class="right marginTop">
|
||||||
<button type="submit" name="submit"><?= isset($community) ? 'Save' : 'Create' ?></button>
|
<button type="submit" name="submit"><?= isset($community) ? 'Save' : 'Create' ?></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
@extends(templates/layout_normal)
|
@extends(templates/layout_normal)
|
||||||
|
|
||||||
@section(main)
|
@section(main)
|
||||||
<h2><?= $community->getName() ?> - Edit members</h2>
|
<h2><a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()]) ?>"><?= $community->getName() ?></a> - Edit members</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<table class="fullWidth">
|
<table class="fullWidth">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -18,25 +18,41 @@
|
|||||||
<?php foreach ($members as $member): ?>
|
<?php foreach ($members as $member): ?>
|
||||||
<?php $editable = $member->getUserId() !== Container::$request->user()->getUniqueId(); ?>
|
<?php $editable = $member->getUserId() !== Container::$request->user()->getUniqueId(); ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?= $member->getUser()->getDisplayName() ?></td>
|
<td>
|
||||||
<td style="text-align: center;"><input type="checkbox" class="member_owner" data-id="<?= $member->getId() ?>" <?= $member->getOwner() ? 'checked' : '' ?> <?= !$editable ? 'disabled' : '' ?> /></td>
|
<form id="editMember_<?= $member->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-members-edit')->generateLink(['communityId' => $community->getId(), 'community_member_id' => $member->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="owner"></form>
|
||||||
<td style="text-align: right;"><button type="button" class="small red delete_member" data-id="<?= $member->getId() ?>" <?= !$editable ? 'disabled' : '' ?>>Delete</button></td>
|
<form id="deleteMember_<?= $member->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-members-delete')->generateLink(['communityId' => $community->getId(), 'community_member_id' => $member->getId()]) ?>" method="post" data-reload-on-success="true"></form>
|
||||||
|
<?= $member->getUser()->getDisplayName() ?>
|
||||||
|
</td>
|
||||||
|
<td style="text-align: center;">
|
||||||
|
<input type="checkbox" form="editMember_<?= $member->getId() ?>" name="owner" <?= $member->getOwner() ? 'checked' : '' ?> <?= !$editable ? 'disabled' : '' ?> />
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<?php if ($editable): ?>
|
||||||
|
<button type="submit" form="editMember_<?= $member->getId() ?>" name="submit" class="small marginRight" disabled>Save</button><!--
|
||||||
|
--><button type="submit" form="deleteMember_<?= $member->getId() ?>" class="small red">Delete</button>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><select type="text" id="new_member_user_id"></td>
|
<td>
|
||||||
<td></td>
|
<form id="newMember" action="<?= Container::$routeCollection->getRoute('community-members-new')->generateLink(['communityId' => $community->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="user_id"></form>
|
||||||
<td style="text-align: right;"><button type="button" class="small" id="new_member_button" disabled>Add</button></td>
|
<select type="text" form="newMember" name="user_id">
|
||||||
|
</td>
|
||||||
|
<td style="text-align: center;">
|
||||||
|
<input type="checkbox" form="newMember" name="owner" />
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<button type="submit" form="newMember" name="submit" class="small" disabled>Add</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<p class="formError justify marginTop"></p>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section(pageScript)
|
@section(pageScript)
|
||||||
<script>
|
<script>
|
||||||
var searchUserUrl = '<?= Container::$routeCollection->getRoute('searchUser')->generateLink(['q' => 'QUERY']) ?>';
|
var searchUserUrl = '<?= Container::$routeCollection->getRoute('searchUser')->generateLink(['q' => 'QUERY']) ?>';
|
||||||
var newMemberUrl = '<?= Container::$routeCollection->getRoute('community-members-new')->generateLink(['communityId' => $community->getId()]) ?>';
|
|
||||||
var editMemberUrl = '<?= Container::$routeCollection->getRoute('community-members-edit')->generateLink(['communityId' => $community->getId()]) ?>';
|
|
||||||
var deleteMemberUrl = '<?= Container::$routeCollection->getRoute('community-members-delete')->generateLink(['communityId' => $community->getId()]) ?>';
|
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
@extends(templates/layout_normal)
|
||||||
|
|
||||||
|
@section(main)
|
||||||
|
<h2><a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communityId' => $community->getId()]) ?>"><?= $community->getName() ?></a> - Exchange rates for <?= $currency->getCode() ?></h2>
|
||||||
|
<div class="box">
|
||||||
|
<table class="fullWidth">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<?php if ($editPermission): ?>
|
||||||
|
<th style="width: 25%; text-align: left;">Exchange rate</th>
|
||||||
|
<th style="width: 50%; text-align: left;">Valid from</th>
|
||||||
|
<th style="width: 25%;"></th>
|
||||||
|
<?php else: ?>
|
||||||
|
<th style="width: 35%; text-align: left;">Exchange rate</th>
|
||||||
|
<th style="width: 65%; text-align: left;">Valid from</th>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<?php foreach ($currencyExchangeRates as $currencyExchangeRate): ?>
|
||||||
|
<tr>
|
||||||
|
<?php if ($editPermission): ?>
|
||||||
|
<td>
|
||||||
|
<form id="editExchangeRate_<?= $currencyExchangeRate->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-currency-exchange-rates-edit')->generateLink(['communityId' => $community->getId(), 'code' => $currency->getCode(), 'currency_exchange_rate_id' => $currencyExchangeRate->getId()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="exchange_rate,valid_from"></form>
|
||||||
|
<form id="deleteCurrency_<?= $currencyExchangeRate->getId() ?>" action="<?= Container::$routeCollection->getRoute('community-currency-exchange-rates-delete')->generateLink(['communityId' => $community->getId(), 'code' => $currency->getCode(), 'currency_exchange_rate_id' => $currencyExchangeRate->getId()]) ?>" method="post" data-reload-on-success="true"></form>
|
||||||
|
<input type="number" form="editExchangeRate_<?= $currencyExchangeRate->getId() ?>" class="text fullWidth" name="exchange_rate" value="<?= $currencyExchangeRate->getExchangeRate() ?>" min="0" step="0.000000001" required>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="datetime-local" form="editExchangeRate_<?= $currencyExchangeRate->getId() ?>" class="text fullWidth" name="valid_from" value="<?= $currencyExchangeRate->getValidFromDate()->format('Y-m-d\TH:i') ?>" required>
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<button type="submit" form="editExchangeRate_<?= $currencyExchangeRate->getId() ?>" name="submit" class="small marginRight" disabled>Save</button><!--
|
||||||
|
--><button type="submit" form="deleteCurrency_<?= $currencyExchangeRate->getId() ?>" class="small red">Delete</button>
|
||||||
|
</td>
|
||||||
|
<?php else: ?>
|
||||||
|
<td><?= $currencyExchangeRate->getExchangeRate() ?></td>
|
||||||
|
<td><?= $currencyExchangeRate->getValidFromDate()->format('Y-m-d H:i') ?></td>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php if ($editPermission): ?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<form id="newExchangeRate" action="<?= Container::$routeCollection->getRoute('community-currency-exchange-rates-new')->generateLink(['communityId' => $community->getId(), 'code' => $currency->getCode()]) ?>" method="post" data-reload-on-success="true" data-observe-inputs="exchange_rate,valid_from"></form>
|
||||||
|
<input type="number" form="newExchangeRate" class="text fullWidth" name="exchange_rate" placeholder="Exchange rate" min="0" step="0.000000001" required>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="datetime-local" form="newExchangeRate" class="text fullWidth" name="valid_from" placeholder="Valid from" required>
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<button type="submit" form="newExchangeRate" name="submit" class="small" disabled>Add</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endif; ?>
|
||||||
|
</table>
|
||||||
|
<p class="formError justify marginTop"></p>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
@extends(templates/layout_normal)
|
||||||
|
|
||||||
|
@section(main)
|
||||||
|
<h2>500 | Internal server error</h2>
|
||||||
|
<p>An error occured during processing your request. <a href="<?= Container::$routeCollection->getRoute('home')->generateLink() ?>" title="<?= $_ENV['APP_NAME'] ?>">Back to start.</a></p>
|
||||||
|
<?php if (isset($exceptionToPrint)): ?>
|
||||||
|
<pre class="marginTop">
|
||||||
|
<?= $exceptionToPrint ?>
|
||||||
|
</pre>
|
||||||
|
<?php endif; ?>
|
||||||
|
@endsection
|
||||||
@@ -63,13 +63,23 @@ Container::$routeCollection->group('communities', function (RouteCollection $rou
|
|||||||
$routeCollection->get('community-edit', 'edit', [CommunityController::class, 'getCommunityEdit']);
|
$routeCollection->get('community-edit', 'edit', [CommunityController::class, 'getCommunityEdit']);
|
||||||
$routeCollection->post('community-edit-action', 'edit', [CommunityController::class, 'saveCommunity']);
|
$routeCollection->post('community-edit-action', 'edit', [CommunityController::class, 'saveCommunity']);
|
||||||
$routeCollection->get('community-members', 'members', [CommunityController::class, 'getMembersEdit']);
|
$routeCollection->get('community-members', 'members', [CommunityController::class, 'getMembersEdit']);
|
||||||
$routeCollection->post('community-members-new', 'newMember', [CommunityController::class, 'newMember']);
|
$routeCollection->post('community-members-new', 'newMember', [CommunityController::class, 'saveMember']);
|
||||||
$routeCollection->post('community-members-edit', 'editMember', [CommunityController::class, 'editMember']);
|
$routeCollection->post('community-members-edit', 'editMember', [CommunityController::class, 'saveMember']);
|
||||||
$routeCollection->post('community-members-delete', 'deleteMember', [CommunityController::class, 'deleteMember']);
|
$routeCollection->post('community-members-delete', 'deleteMember', [CommunityController::class, 'deleteMember']);
|
||||||
|
$routeCollection->get('community-currencies', 'currencies', [CommunityController::class, 'getCurrenciesEdit']);
|
||||||
|
$routeCollection->post('community-currencies-new', 'newCurrency', [CommunityController::class, 'saveCurrency']);
|
||||||
|
$routeCollection->post('community-currencies-edit', 'editCurrency', [CommunityController::class, 'saveCurrency']);
|
||||||
|
$routeCollection->post('community-currencies-delete', 'deleteCurrency', [CommunityController::class, 'deleteCurrency']);
|
||||||
|
$routeCollection->group('currencyExchangeRates', function (RouteCollection $routeCollection) {
|
||||||
|
$routeCollection->get('community-currency-exchange-rates', '{code}', [CommunityController::class, 'getCurrencyExchangeRates']);
|
||||||
|
$routeCollection->post('community-currency-exchange-rates-new', '{code}/new', [CommunityController::class, 'saveCurrencyExchangeRate']);
|
||||||
|
$routeCollection->post('community-currency-exchange-rates-edit', '{code}/edit', [CommunityController::class, 'saveCurrencyExchangeRate']);
|
||||||
|
$routeCollection->post('community-currency-exchange-rates-delete', '{code}/delete', [CommunityController::class, 'deleteCurrencyExchangeRate']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Container::$sessionHandler = new DatabaseSessionHandler();
|
Container::$sessionHandler = new DatabaseSessionHandler(Container::$dbConnection);
|
||||||
|
|
||||||
session_set_save_handler(Container::$sessionHandler, true);
|
session_set_save_handler(Container::$sessionHandler, true);
|
||||||
session_start([
|
session_start([
|
||||||
@@ -108,11 +118,13 @@ $appConfig = [
|
|||||||
'antiCsrfTokenErrorResponse' => ['error' => 'no_valid_anti_csrf_token'],
|
'antiCsrfTokenErrorResponse' => ['error' => 'no_valid_anti_csrf_token'],
|
||||||
'antiCsrfTokenExceptions' => ['/oauth/token'],
|
'antiCsrfTokenExceptions' => ['/oauth/token'],
|
||||||
'loginRouteId' => 'login',
|
'loginRouteId' => 'login',
|
||||||
'error404View' => 'error/404'
|
'error404View' => 'error/404',
|
||||||
|
'error500View' => 'error/500'
|
||||||
];
|
];
|
||||||
|
|
||||||
$httpReponse = new HttpResponse(
|
$httpReponse = new HttpResponse(
|
||||||
Container::$request,
|
Container::$request,
|
||||||
|
Container::$dbConnection,
|
||||||
Container::$routeCollection,
|
Container::$routeCollection,
|
||||||
$appConfig,
|
$appConfig,
|
||||||
$_SERVER['REQUEST_METHOD'],
|
$_SERVER['REQUEST_METHOD'],
|
||||||
|
|||||||
Reference in new issue
Block a user