diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 420bb4e..28e091e 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -19,7 +19,7 @@ "type": 3, "subtype": 1, "name": "Dashboard", - "uri": "{/prefix}admin/exchange/dashboard?{?}", + "uri": "{/prefix}admin/exchange/log/list?{?}", "target": "self", "icon": null, "order": 1, diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 142d2a6..570c56b 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -66,11 +66,23 @@ "type": "TINYINT", "null": false }, - "exchange_log_time": { - "name": "exchange_log_time", + "exchange_log_subtype": { + "name": "exchange_log_subtype", + "type": "VARCHAR(100)", + "null": false + }, + "exchange_log_created_at": { + "name": "exchange_log_created_at", "type": "DATETIME", "null": false }, + "exchange_log_created_by": { + "name": "exchange_log_created_by", + "type": "INT", + "null": false, + "foreignTable": "account", + "foreignKey": "account_id" + }, "exchange_log_exchange": { "name": "exchange_log_exchange", "type": "INT", diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index 3f164dd..13e823e 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -50,9 +50,20 @@ return [ ], ], ], - '^.*/admin/exchange/dashboard.*$' => [ + '^.*/admin/exchange/log/list.*$' => [ [ - 'dest' => '\Modules\Exchange\Controller\BackendController:viewExchangeDashboard', + 'dest' => '\Modules\Exchange\Controller\BackendController:viewExchangeLogList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::MODULE_NAME, + 'type' => PermissionType::READ, + 'state' => PermissionState::DASHBOARD, + ], + ], + ], + '^.*/admin/exchange/log\?.*$' => [ + [ + 'dest' => '\Modules\Exchange\Controller\BackendController:viewExchangeLog', 'verb' => RouteVerb::GET, 'permission' => [ 'module' => BackendController::MODULE_NAME, diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 81f608f..4bb2fcf 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Modules\Exchange\Controller; +use Modules\Exchange\Models\ExchangeLogMapper; use Modules\Exchange\Models\InterfaceManager; use Modules\Exchange\Models\InterfaceManagerMapper; use Modules\Media\Models\UploadFile; @@ -54,7 +55,11 @@ final class ApiController extends Controller $status = NotificationLevel::ERROR; $message = 'Import failed.'; - if ($import) { + foreach ($import['logs'] as $log) { + $this->createModel($request->header->account, $log, ExchangeLogMapper::class, 'import', $request->getOrigin()); + } + + if ($import['status']) { $status = NotificationLevel::OK; $message = 'Import succeeded.'; } @@ -71,26 +76,18 @@ final class ApiController extends Controller * * @param RequestAbstract $request Request * - * @return bool + * @return array * * @since 1.0.0 */ - private function importDataFromRequest(RequestAbstract $request) : bool + private function importDataFromRequest(RequestAbstract $request) : array { - /** @var \Modules\Exchange\Models\InterfaceManager[] $interfaces */ - $interfaces = InterfaceManagerMapper::getAll(); - foreach ($interfaces as $interface) { - if ($request->getData('exchange') ?? '' === $interface->getInterfacePath()) { - $class = '\\Modules\\Exchange\\Interfaces\\' . $interface->getInterfacePath() . '\\Importer'; - $importer = new $class($this->app->dbPool->get()); + /** @var \Modules\Exchange\Models\InterfaceManager $interface */ + $interface = InterfaceManagerMapper::get($request->getData('id')); + $class = '\\Modules\\Exchange\\Interfaces\\' . $interface->getInterfacePath() . '\\Importer'; + $importer = new $class($this->app->dbPool->get()); - return $importer->importFromRequest($request); - } - } - - Directory::delete(__DIR__ . '/../tmp/'); - - return false; + return $importer->importFromRequest($request); } /** @@ -162,6 +159,10 @@ final class ApiController extends Controller public function apiExchangeExport(RequestAbstract $request, ResponseAbstract $response, $data = null) : void { $export = $this->exportDataFromRequest($request); + foreach ($export['logs'] as $log) { + $this->createModel($request->header->account, $log, ExchangeLogMapper::class, 'export', $request->getOrigin()); + } + if ($export['type'] === 'file') { $file = \explode('.', $export['name']); @@ -206,20 +207,12 @@ final class ApiController extends Controller */ private function exportDataFromRequest(RequestAbstract $request) : array { - /** @var \Modules\Exchange\Models\InterfaceManager[] $interfaces */ - $interfaces = InterfaceManagerMapper::getAll(); - foreach ($interfaces as $interface) { - if ($request->getData('exchange') ?? '' === $interface->getInterfacePath()) { - $class = '\\Modules\\Exchange\\Interfaces\\' . $interface->getInterfacePath() . '\\Exporter'; - $exporter = new $class($this->app->dbPool->get()); + /** @var \Modules\Exchange\Models\InterfaceManager $interface */ + $interface = InterfaceManagerMapper::get($request->getData('id')); + $class = '\\Modules\\Exchange\\Interfaces\\' . $interface->getInterfacePath() . '\\Exporter'; + $exporter = new $class($this->app->dbPool->get()); - return $exporter->exportFromRequest($request); - } - } - - Directory::delete(__DIR__ . '/../tmp/'); - - return []; + return $exporter->exportFromRequest($request); } /** diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 9fbdbfd..ad53e0e 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -19,6 +19,7 @@ use phpOMS\Contract\RenderableInterface; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Views\View; +use Modules\Exchange\Models\ExchangeLogMapper; /** * Exchange controller class. @@ -42,12 +43,50 @@ final class BackendController extends Controller * @since 1.0.0 * @codeCoverageIgnore */ - public function viewExchangeDashboard(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface + public function viewExchangeLogList(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); - $view->setTemplate('/Modules/Exchange/Theme/Backend/exchange-dashboard'); + $view->setTemplate('/Modules/Exchange/Theme/Backend/exchange-log-list'); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1007001001, $request, $response)); + if ($request->getData('ptype') === 'p') { + $view->setData('logs', + ExchangeLogMapper::getBeforePivot((int) ($request->getData('id') ?? 0), limit: 25, depth: 4) + ); + } elseif ($request->getData('ptype') === 'n') { + $view->setData('logs', + ExchangeLogMapper::getAfterPivot((int) ($request->getData('id') ?? 0), limit: 25, depth: 4) + ); + } else { + $view->setData('logs', + ExchangeLogMapper::getAfterPivot(0, limit: 25, depth: 4) + ); + } + + return $view; + } + + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewExchangeLog(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/Exchange/Theme/Backend/exchange-log'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1007001001, $request, $response)); + + $log = ExchangeLogMapper::get((int) $request->getData('id')); + $view->setData('log', $log); + return $view; } diff --git a/Interfaces/OMS/Exporter.php b/Interfaces/OMS/Exporter.php index 667315d..28a7f00 100644 --- a/Interfaces/OMS/Exporter.php +++ b/Interfaces/OMS/Exporter.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace Modules\Exchange\Interfaces\OMS; +use Modules\Exchange\Models\ExchangeLog; +use Modules\Exchange\Models\ExchangeType; use phpOMS\DataStorage\Database\Connection\ConnectionAbstract; use phpOMS\DataStorage\Database\Connection\ConnectionFactory; use phpOMS\DataStorage\Database\DatabaseStatus; @@ -84,10 +86,19 @@ final class Exporter extends ExporterAbstract $this->account = $request->header->account; if ($request->getData('type') === 'language') { - return $this->exportLanguage(); + $result = $this->exportLanguage(); + + $log = new ExchangeLog(); + $log->createdBy = $this->account; + $log->setType(ExchangeType::EXPORT); + $log->message = 'Language file exported.'; // @todo: localize! + $log->subtype = 'language'; + $log->exchange = (int) $request->getData('id'); + + $result['logs'][] = $log; } - return []; + return $result; } /** diff --git a/Interfaces/OMS/Importer.php b/Interfaces/OMS/Importer.php index 10b2cbd..633f904 100644 --- a/Interfaces/OMS/Importer.php +++ b/Interfaces/OMS/Importer.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Modules\Exchange\Interfaces\OMS; +use Modules\Exchange\Models\ExchangeLog; use phpOMS\DataStorage\Database\Connection\ConnectionAbstract; use phpOMS\DataStorage\Database\Connection\ConnectionFactory; use phpOMS\DataStorage\Database\DatabaseStatus; @@ -25,6 +26,8 @@ use phpOMS\System\File\Local\Directory; use phpOMS\Utils\IO\Zip\Zip; use Modules\Media\Controller\ApiController; use Modules\Exchange\Models\ImporterAbstract; +use phpOMS\Message\Http\HttpRequest; +use Modules\Exchange\Models\ExchangeType; /** * OMS import class @@ -64,7 +67,7 @@ final class Importer extends ImporterAbstract */ public function import(\DateTime $start, \DateTime $end) : void { - $this->importLanguage(); + $this->importLanguage(new HttpRequest()); } /** @@ -72,11 +75,11 @@ final class Importer extends ImporterAbstract * * @param RequestAbstract $request Request * - * @return bool + * @return array * * @since 1.0.0 */ - public function importFromRequest(RequestAbstract $request) : bool + public function importFromRequest(RequestAbstract $request) : array { $start = new \DateTime($request->getData('start') ?? 'now'); $end = new \DateTime($request->getData('end') ?? 'now'); @@ -95,17 +98,27 @@ final class Importer extends ImporterAbstract $this->remote->connect(); if ($this->remote->getStatus() !== DatabaseStatus::OK) { - return false; + return ['status' => false]; } } $this->account = $request->header->account; + $result = ['status' => true]; + if ($request->getData('type') === 'language') { $this->importLanguage($request); + $log = new ExchangeLog(); + $log->createdBy = $this->account; + $log->setType(ExchangeType::IMPORT); + $log->message = 'Language file imported.'; // @todo: localize! + $log->subtype = 'language'; + $log->exchange = (int) $request->getData('id'); + + $result['logs'][] = $log; } - return true; + return $result; } /** diff --git a/Interfaces/OMS/export.tpl.php b/Interfaces/OMS/export.tpl.php index bf74739..43b52a4 100644 --- a/Interfaces/OMS/export.tpl.php +++ b/Interfaces/OMS/export.tpl.php @@ -5,7 +5,7 @@ $lang = $this->getData('lang');
-
+
printHtml($lang['Language']); ?> - OMS
diff --git a/Interfaces/OMS/import.tpl.php b/Interfaces/OMS/import.tpl.php index 4361261..da086f1 100644 --- a/Interfaces/OMS/import.tpl.php +++ b/Interfaces/OMS/import.tpl.php @@ -5,7 +5,7 @@ $lang = $this->getData('lang');
- +
printHtml($lang['Language']); ?> - OMS
diff --git a/Models/ExchangeLog.php b/Models/ExchangeLog.php index 2078022..04f034a 100644 --- a/Models/ExchangeLog.php +++ b/Models/ExchangeLog.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Modules\Exchange\Models; +use Modules\Admin\Models\Account; use phpOMS\Contract\ArrayableInterface; /** @@ -60,6 +61,14 @@ class ExchangeLog implements \JsonSerializable, ArrayableInterface public string $subtype = ''; + /** + * Exchange id. + * + * @var int + * @since 1.0.0 + */ + public int|InterfaceManager $exchange = 0; + /** * Date type. * @@ -68,7 +77,7 @@ class ExchangeLog implements \JsonSerializable, ArrayableInterface */ public \DateTimeImmutable $createdAt; - public int $createdBy = 0; + public int|Account $createdBy = 0; /** * Constructor. diff --git a/Models/ExchangeLogMapper.php b/Models/ExchangeLogMapper.php index 3735137..477d818 100644 --- a/Models/ExchangeLogMapper.php +++ b/Models/ExchangeLogMapper.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace Modules\Exchange\Models; use phpOMS\DataStorage\Database\DataMapperAbstract; +use Modules\Admin\Models\AccountMapper; /** * Exchange log mapper class. @@ -37,7 +38,10 @@ final class ExchangeLogMapper extends DataMapperAbstract 'exchange_log_message' => ['name' => 'exchange_log_message', 'type' => 'string', 'internal' => 'message'], 'exchange_log_fields' => ['name' => 'exchange_log_fields', 'type' => 'Json', 'internal' => 'fields'], 'exchange_log_type' => ['name' => 'exchange_log_type', 'type' => 'int', 'internal' => 'type'], - 'exchange_log_time' => ['name' => 'exchange_log_time', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt'], + 'exchange_log_subtype' => ['name' => 'exchange_log_subtype', 'type' => 'string', 'internal' => 'subtype'], + 'exchange_log_created_at' => ['name' => 'exchange_log_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true], + 'exchange_log_created_by' => ['name' => 'exchange_log_created_by', 'type' => 'int', 'internal' => 'createdBy', 'readonly' => true], + 'exchange_log_exchange' => ['name' => 'exchange_log_exchange', 'type' => 'int', 'internal' => 'exchange'], ]; /** @@ -63,4 +67,21 @@ final class ExchangeLogMapper extends DataMapperAbstract * @since 1.0.0 */ protected static string $primaryField = 'exchange_log_id'; + + /** + * Belongs to. + * + * @var array + * @since 1.0.0 + */ + protected static array $belongsTo = [ + 'createdBy' => [ + 'mapper' => AccountMapper::class, + 'external' => 'exchange_log_created_by', + ], + 'exchange' => [ + 'mapper' => InterfaceManagerMapper::class, + 'external' => 'exchange_log_exchange', + ], + ]; } diff --git a/Models/ImporterAbstract.php b/Models/ImporterAbstract.php index 8c8bb3e..0d99a4e 100755 --- a/Models/ImporterAbstract.php +++ b/Models/ImporterAbstract.php @@ -52,9 +52,9 @@ abstract class ImporterAbstract * * @param RequestAbstract $request Request * - * @return bool + * @return array * * @since 1.0.0 */ - abstract public function importFromRequest(RequestAbstract $request) : bool; + abstract public function importFromRequest(RequestAbstract $request) : array; } diff --git a/Theme/Backend/exchange-dashboard.tpl.php b/Theme/Backend/exchange-dashboard.tpl.php deleted file mode 100755 index d263b86..0000000 --- a/Theme/Backend/exchange-dashboard.tpl.php +++ /dev/null @@ -1,16 +0,0 @@ -getData('nav')->render(); diff --git a/Theme/Backend/exchange-log-list.tpl.php b/Theme/Backend/exchange-log-list.tpl.php new file mode 100755 index 0000000..b97c951 --- /dev/null +++ b/Theme/Backend/exchange-log-list.tpl.php @@ -0,0 +1,54 @@ +getData('logs') ?? []; + +echo $this->getData('nav')->render(); ?> + +
+
+
+
getHtml('Logs'); ?>
+
+ + + + $value) : + ++$count; + $url = UriFactory::build('{/prefix}admin/exchange/log?{?}&id=' . $value->getId()); + ?> + +
getHtml('ID', '0', '0'); ?> + getHtml('Type'); ?> + getHtml('Subtype'); ?> + getHtml('Exchange'); ?> + getHtml('CreatedBy'); ?> + getHtml('CreatedAt'); ?> +
getId(); ?> + getType(); ?> + subtype; ?> + exchange->getName(); ?> + createdBy->name1; ?> + createdAt->format('Y-m-d'); ?> + + +
getHtml('Empty', '0', '0'); ?> + +
+
+
+
diff --git a/Theme/Backend/exchange-log.tpl.php b/Theme/Backend/exchange-log.tpl.php new file mode 100644 index 0000000..e69de29