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; + }); +}); 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(); + } +} 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 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; + } } 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