From 76205250ad7022ad5b8d24238fb73c7d7c47256b Mon Sep 17 00:00:00 2001 From: Aldarien Date: Tue, 13 Apr 2021 23:02:10 -0400 Subject: [PATCH 1/6] Name cron --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 181e19c..6039676 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,7 @@ services: ports: - 9123:9000 app-cron: + container_name: money_cron image: sleeck/crond volumes: - ./automation/crontab:/etc/cron.d/auto-crontab From 3651969c33e87dc89406ff80c12da980e5682989 Mon Sep 17 00:00:00 2001 From: Aldarien Date: Tue, 13 Apr 2021 23:03:00 -0400 Subject: [PATCH 2/6] Alias models --- src/Alias.php | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Currency.php | 36 +++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 src/Alias.php diff --git a/src/Alias.php b/src/Alias.php new file mode 100644 index 0000000..bfd0f0a --- /dev/null +++ b/src/Alias.php @@ -0,0 +1,56 @@ +currency === null) { + $this->currency = $this->childOf(Currency::class, [Model::SELF_KEY => 'currency_id']); + } + return $this->currency; + } + + protected static $fields = ['currency_id', 'alias']; + public static function add(ModelFactory $factory, $info) { + $input = array_intersect_key((array) $info, array_combine(self::$fields, self::$fields)); + $alias = $factory->find(Alias::class)->where([['currency_id', $input['currency_id']], ['alias', $input['alias']]])->one(); + $created = false; + $result = (object) compact('input', 'alias', 'created'); + if (!$alias) { + $alias = $factory->create(Alias::class, $input); + $created = $alias->save(); + $result->created = $created; + } + $result->source = $alias->asArray(); + return $result; + } + public function edit($info): bool { + $data = array_intersect_key((array) $info, array_combine(self::$fields, self::$fields)); + $edited = false; + foreach ($data as $field => $value) { + if ($this->{$field} != $value) { + $this->{$field} = $value; + $edited = true; + } + } + if ($edited) { + $edited = $this->save(); + } + return $edited; + } + public function asArray(): array { + $output = parent::asArray(); + $output['currency'] = $this->currency()->asArray(); + return $output; + } +} diff --git a/src/Currency.php b/src/Currency.php index a53d614..dd03e4a 100644 --- a/src/Currency.php +++ b/src/Currency.php @@ -38,6 +38,13 @@ class Currency extends Model { } return $this->sources; } + protected $aliases; + public function aliases() { + if ($this->aliases === null) { + $this->aliases = $this->parentOf(Alias::class, [Model::CHILD_KEY => 'currency_id']); + } + return $this->aliases; + } protected static $fields = ['code', 'name']; public static function add(ModelFactory $factory, $info) { @@ -73,6 +80,12 @@ class Currency extends Model { } return $edited; } + public function addAlias($info) { + $arr = (array) $info; + $arr['currency_id'] = (int) $this->id; + $result = Alias::add($this->factory, $arr); + return $result; + } public function addValue($info) { $arr = (array) $info; $arr['currency_id'] = (int) $this->id; @@ -85,4 +98,27 @@ class Currency extends Model { $result = Source::add($this->factory, $arr); return $result; } + + public static function find(ModelFactory $factory, string $query) { + $query = '%' . $query . '%'; + $currency = $factory->find(Currency::class)->where([ + ['code', $query, 'like'] + ])->one(); + if ($currency !== false and $currency !== null) { + return $currency; + } + $currency = $factory->find(Currency::class)->where([ + ['name', $query, 'like'] + ])->one(); + if ($currency !== false and $currency !== null) { + return $currency; + } + $alias = $factory->find(Alias::class)->where([ + ['alias', $query, 'like'] + ])->one(); + if ($alias !== false and $alias !== null) { + return $alias->currency(); + } + return false; + } } From f9a00578f456b496ad04daea95ad314345f0f58b Mon Sep 17 00:00:00 2001 From: Aldarien Date: Tue, 13 Apr 2021 23:03:25 -0400 Subject: [PATCH 3/6] Migration foreign keys --- .../20210315235815_create_values.php | 10 +++- .../20210320020631_create_sources.php | 6 +- .../20210414015145_create_aliases.php | 59 +++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 db/migrations/20210414015145_create_aliases.php diff --git a/db/migrations/20210315235815_create_values.php b/db/migrations/20210315235815_create_values.php index 02d4c21..b99ad28 100644 --- a/db/migrations/20210315235815_create_values.php +++ b/db/migrations/20210315235815_create_values.php @@ -34,13 +34,21 @@ class CreateValues extends Phinx\Migration\AbstractMigration 'signed' => false, 'after' => 'value', ]) - ->addIndex(['currency_id'], [ + /*->addIndex(['currency_id'], [ 'name' => 'currency_id', 'unique' => false, ]) ->addIndex(['base_id'], [ 'name' => 'base_id', 'unique' => false, + ])*/ + ->addForeignKey(['currency_id'], 'currencies', ['id'], [ + 'delete' => 'CASCADE', + 'update' => 'CASCADE' + ]) + ->addForeignKey(['base_id'], 'currencies', ['id'], [ + 'delete' => 'CASCADE', + 'update' => 'CASCADE' ]) ->create(); /*$this->table('currencies', [ diff --git a/db/migrations/20210320020631_create_sources.php b/db/migrations/20210320020631_create_sources.php index 2b77479..64167be 100644 --- a/db/migrations/20210320020631_create_sources.php +++ b/db/migrations/20210320020631_create_sources.php @@ -53,9 +53,13 @@ final class CreateSources extends AbstractMigration 'encoding' => 'utf8mb4', 'after' => 'url', ]) - ->addIndex(['currency_id'], [ + /*->addIndex(['currency_id'], [ 'name' => 'currency_id', 'unique' => false, + ])*/ + ->addForeignKey(['currency_id'], 'currencies', ['id'], [ + 'delete' => 'CASCADE', + 'update' => 'CASCADE' ]) ->create(); } diff --git a/db/migrations/20210414015145_create_aliases.php b/db/migrations/20210414015145_create_aliases.php new file mode 100644 index 0000000..95572b7 --- /dev/null +++ b/db/migrations/20210414015145_create_aliases.php @@ -0,0 +1,59 @@ +table('aliases', [ + 'id' => false, + 'primary_key' => ['id'], + 'engine' => 'InnoDB', + 'encoding' => 'utf8mb4', + 'collation' => 'utf8mb4_general_ci', + 'comment' => '', + 'row_format' => 'DYNAMIC', + ]) + ->addColumn('id', 'integer', [ + 'null' => false, + 'limit' => '10', + 'signed' => false, + 'identity' => 'enable', + ]) + ->addColumn('currency_id', 'integer', [ + 'null' => false, + 'limit' => '10', + 'signed' => false, + 'after' => 'id', + ]) + ->addColumn('alias', 'string', [ + 'null' => false, + 'limit' => 100, + 'collation' => 'utf8mb4_general_ci', + 'encoding' => 'utf8mb4', + 'after' => 'currency_id', + ]) + /*->addIndex(['currency_id'], [ + 'name' => 'currency_id', + 'unique' => false, + ])*/ + ->addForeignKey(['currency_id'], 'currencies', ['id'], [ + 'delete' => 'CASCADE', + 'update' => 'CASCADE' + ]) + ->create(); + } +} From 3b20fbd66fd203eaf14e7fc3c1d983728a0e1600 Mon Sep 17 00:00:00 2001 From: Aldarien Date: Tue, 13 Apr 2021 23:03:39 -0400 Subject: [PATCH 4/6] Alias API --- app/common/Controller/Aliases.php | 73 +++++++++++++++++ app/common/Controller/Currencies.php | 104 ++++++++++++++++++++++++ app/phinx.php | 10 +-- app/resources/routes/api/aliases.php | 19 +++++ app/resources/routes/api/currencies.php | 24 +++++- 5 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 app/common/Controller/Aliases.php create mode 100644 app/resources/routes/api/aliases.php diff --git a/app/common/Controller/Aliases.php b/app/common/Controller/Aliases.php new file mode 100644 index 0000000..ba22316 --- /dev/null +++ b/app/common/Controller/Aliases.php @@ -0,0 +1,73 @@ +find(Alias::class)->array(); + $output = compact('aliases'); + return $this->withJson($response, $output); + } + public function get(Request $request, Response $response, ModelFactory $factory, $alias_id): Response { + $alias = $factory->find(Alias::class)->one($alias_id); + $output = [ + 'get_data' => compact('alias_id'), + 'alias' => null + ]; + if ($alias) { + $output['alias'] = $alias->asArray(); + } + return $this->withJson($response, $output); + } + public function add(Request $request, Response $response, ModelFactory $factory): Response { + $post = json_decode($request->getBody()->getContents()); + $aliases = []; + if (is_array($post)) { + foreach ($post as $obj) { + if (!is_object($obj)) { + continue; + } + $aliases []= Alias::add($factory, $obj); + } + } else { + $aliases []= Alias::add($factory, $post); + } + $output = [ + 'post_data' => $post, + 'aliases' => $aliases + ]; + return $this->withJson($response, $output); + } + public function edit(Request $request, Response $response, ModelFactory $factory, $alias_id) { + $post = json_decode($request->getBody()->getContents()); + $output = [ + 'get_data' => compact('alias_id'), + 'post_data' => $post + ]; + $alias = $factory->find(Alias::class)->one($alias_id); + $edited = false; + if ($alias) { + $edited = $alias->edit($post); + $output['alias'] = $alias->asArray(); + $output['edited'] = $edited; + } + return $this->withJson($response, $output); + } + public function delete(Request $request, Response $response, ModelFactory $factory, $alias_id): Response { + $alias = $factory->find(Alias::class)->one($alias_id); + $output = ['get_data' => compact('alias_id'), 'alias' => null, 'deleted' => false]; + if ($alias) { + $output['alias'] = $alias->asArray(); + $status = $alias->delete(); + $output['deleted'] = $status; + } + return $this->withJson($response, $output); + } +} diff --git a/app/common/Controller/Currencies.php b/app/common/Controller/Currencies.php index a1065f6..0136054 100644 --- a/app/common/Controller/Currencies.php +++ b/app/common/Controller/Currencies.php @@ -72,6 +72,49 @@ class Currencies { } return $this->withJson($response, $output); } + public function getAliases(Request $request, Response $response, ModelFactory $factory, $currency_id): Response { + $currency = $factory->find(Currency::class)->one($currency_id); + $output = [ + 'get_data' => compact('currency_id'), + 'currency' => null, + 'aliases' => [] + ]; + if ($currency) { + $output['currency'] = $currency->asArray(); + if ($currency->aliases()) { + $output['aliases'] = array_map(function($item) { + return $item->asArray(); + }, $currency->aliases()); + } + } + return $this->withJson($response, $output); + } + public function addAliases(Request $request, Response $response, ModelFactory $factory, $currency_id): Response { + $currency = $factory->find(Currency::class)->one($currency_id); + $post = json_decode($request->getBody()->getContents()); + $output = [ + 'get_data' => compact('currency_id'), + 'post_data' => $post, + 'currency' => null, + 'aliases' => [] + ]; + if ($currency) { + $output['currency'] = $currency->asArray(); + $aliases = []; + if (is_array($post)) { + foreach ($post as $obj) { + if (!is_object($obj)) { + continue; + } + $aliases []= $currency->addAlias($obj); + } + } else { + $aliases []= $currency->addAlias($post); + } + $output['aliases'] = $aliases; + } + return $this->withJson($response, $output); + } public function getValues(Request $request, Response $response, ModelFactory $factory, $currency_id): Response { $currency = $factory->find(Currency::class)->one($currency_id); $output = [ @@ -173,4 +216,65 @@ class Currencies { } return $this->withJson($response, $output); } + + public function find(Request $request, Response $response, ModelFactory $factory, $query): Response { + $currency = Currency::find($factory, $query); + $output = [ + 'get_data' => compact('query'), + 'currency' => null + ]; + if ($currency) { + $output['currency'] = $currency->asArray(); + } + return $this->withJson($response, $output); + } + public function findValues(Request $request, Response $response, ModelFactory $factory, $query): Response { + $currency = Currency::find($factory, $query); + $output = [ + 'get_data' => compact('query'), + 'currency' => null, + 'values' => [] + ]; + if ($currency) { + $output['currency'] = $currency->asArray(); + if ($currency->values()) { + $output['values'] = array_map(function($item) { + return $item->asArray(); + }, $currency->values()); + } + } + return $this->withJson($response, $output); + } + public function findLatest(Request $request, Response $response, ModelFactory $factory, $query): Response { + $currency = Currency::find($factory, $query); + $output = [ + 'get_data' => compact('currency_id'), + 'currency' => null, + 'value' => null + ]; + if ($currency) { + $output['currency'] = $currency->asArray(); + if ($currency->latest()) { + $output['value'] = $currency->latest()->asArray(); + } + } + return $this->withJson($response, $output); + } + public function findSources(Request $request, Response $response, ModelFactory $factory, $query): Response { + $currency = Currency::find($factory, $query); + $output = [ + 'get_data' => compact('query'), + 'currency' => null, + 'sources' => [] + ]; + if ($currency) { + $output['currency'] = $currency->asArray(); + if ($currency->sources()) { + $output['sources'] = array_map(function($item) { + return $item->asArray(); + }, $currency->sources()); + } + } + return $this->withJson($response, $output); + } } diff --git a/app/phinx.php b/app/phinx.php index 104f7c9..588b98d 100644 --- a/app/phinx.php +++ b/app/phinx.php @@ -21,11 +21,11 @@ return ], 'development' => [ 'adapter' => 'mysql', - 'host' => $_ENV['DB_HOST'], - 'name' => $_ENV['DB_NAME'], - 'user' => $_ENV['DB_USER'], - 'pass' => $_ENV['DB_PASSWORD'], - 'port' => '3306', + 'host' => $_ENV['DB_HOST'] ?? 'localhost', + 'name' => $_ENV['DB_NAME'] ?? 'money_dev', + 'user' => $_ENV['DB_USER'] ?? 'money', + 'pass' => $_ENV['DB_PASSWORD'] ?? 'money_pass', + 'port' => '3307', 'charset' => 'utf8', ], 'testing' => [ diff --git a/app/resources/routes/api/aliases.php b/app/resources/routes/api/aliases.php new file mode 100644 index 0000000..b976c70 --- /dev/null +++ b/app/resources/routes/api/aliases.php @@ -0,0 +1,19 @@ +group('/aliases', function($app) { + $app->post('/add[/]', [Aliases::class, 'add']); + $app->get('[/]', Aliases::class); + $app->options('[/]', function (Request $request, Response $response): Response { + return $response; + }); +}); + +$app->group('/alias/{alias_id}', function($app) { + $app->put('/edit[/]', [Aliases::class, 'edit']); + $app->delete('/delete[/]', [Aliases::class, 'delete']); + $app->get('[/]', [Aliases::class, 'get']); + $app->options('[/]', function (Request $request, Response $response): Response { + return $response; + }); +}); diff --git a/app/resources/routes/api/currencies.php b/app/resources/routes/api/currencies.php index 8ca0172..973fe1a 100644 --- a/app/resources/routes/api/currencies.php +++ b/app/resources/routes/api/currencies.php @@ -10,9 +10,16 @@ $app->group('/currencies', function($app) { }); }); -$app->group('/currency/{currency_id}', function($app) { +$app->group('/currency/{currency_id:[0-9]+}', function($app) { $app->put('/edit[/]', [Currencies::class, 'edit']); $app->delete('/delete[/]', [Currencies::class, 'delete']); + $app->group('/aliases', function($app) { + $app->post('/add[/]', [Currencies::class, 'addAliases']); + $app->get('[/]', [Currencies::class, 'getAliases']); + $app->options('[/]', function (Request $request, Response $response): Response { + return $response; + }); + }); $app->group('/values', function($app) { $app->get('/latest[/]', [Currencies::class, 'latestValue']); $app->post('/add[/]', [Currencies::class, 'addValues']); @@ -33,3 +40,18 @@ $app->group('/currency/{currency_id}', function($app) { return $response; }); }); + +$app->group('/currency/{query:[a-z]+}', function($app) { + $app->group('/values', function($app) { + $app->get('/latest[/]', [Currencies::class, 'findLatest']); + $app->get('[/]', [Currencies::class, 'findValues']); + $app->options('[/]', function (Request $request, Response $response): Response { + return $response; + }); + }); + $app->get('/sources', [Currencies::class, 'findSources']); + $app->get('[/]', [Currencies::class, 'find']); + $app->options('[/]', function (Request $request, Response $response): Response { + return $response; + }); +}); From 446834c100f9def72b656b1c50d3d605dd35d19d Mon Sep 17 00:00:00 2001 From: Aldarien Date: Tue, 13 Apr 2021 23:03:49 -0400 Subject: [PATCH 5/6] Alias WebSocket --- ws/common/Listener/Currencies.php | 18 ++++++++++++++++++ ws/resources/routes/ws/currencies.php | 1 + 2 files changed, 19 insertions(+) diff --git a/ws/common/Listener/Currencies.php b/ws/common/Listener/Currencies.php index c62ae6d..23e92e7 100644 --- a/ws/common/Listener/Currencies.php +++ b/ws/common/Listener/Currencies.php @@ -37,6 +37,24 @@ class Currencies { $response->getBody()->write($output); return $response; } + public function getAliases(Request $request, Response $response, ModelFactory $factory): Response { + $currency_id = $request->getBody()->read()['currency_id']; + $currency = $factory->find(Currency::class)->one($currency_id); + $output = [ + 'currency' => null, + 'aliases' => [] + ]; + if ($currency) { + $output['currency'] = $currency->asArray(); + if ($currency->aliases()) { + $output['aliases'] = array_map(function($item) { + return $item->asArray(); + }, $currency->aliases()); + } + } + $response->getBody()->write($output); + return $response; + } public function getSources(Request $request, Response $response, ModelFactory $factory): Response { $currency_id = $request->getBody()->read()['currency_id']; $currency = $factory->find(Currency::class)->one($currency_id); diff --git a/ws/resources/routes/ws/currencies.php b/ws/resources/routes/ws/currencies.php index 6c668d4..426c202 100644 --- a/ws/resources/routes/ws/currencies.php +++ b/ws/resources/routes/ws/currencies.php @@ -4,6 +4,7 @@ use ProVM\Money\Common\Listener\Currencies; $controller = new Currencies(); $app->add('currencies', $controller); $app->add('currency', [$controller, 'get']); +$app->add('currency.aliases', [$controller, 'getAliases']); $app->add('currency.values.latest', [$controller, 'latest']); $app->add('currency.sources', [$controller, 'getSources']); $app->add('currency.values', [$controller, 'getValues']); From b86e69b60e9f1cb07a0040407638a9b18bc30f4a Mon Sep 17 00:00:00 2001 From: Aldarien Date: Tue, 13 Apr 2021 23:04:03 -0400 Subject: [PATCH 6/6] Alias UI --- ui/resources/views/currencies/show.blade.php | 118 ++++++++++++++++++- ui/setup/web/settings.php | 2 +- 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/ui/resources/views/currencies/show.blade.php b/ui/resources/views/currencies/show.blade.php index 0a3d083..44ccb14 100644 --- a/ui/resources/views/currencies/show.blade.php +++ b/ui/resources/views/currencies/show.blade.php @@ -6,6 +6,15 @@ @section('content')

+ + + + + + +
Alias + +
@@ -87,10 +96,112 @@ + @endsection @push('scripts')
Url