diff --git a/src/Controller/Caching.php b/src/Controller/Caching.php index 1c5ebbc..dc2a555 100644 --- a/src/Controller/Caching.php +++ b/src/Controller/Caching.php @@ -3,31 +3,18 @@ namespace Lean\Console\Controller; use League\Route\Router; -use Picea\Caching\Opcache; -use Picea\FileFetcher; -use Picea\Picea; +use Picea\{ FileFetcher, Picea ,Caching\Opcache, Extension\UrlExtension }; use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface }; - -use Notes\Route\Annotation\Object\Route as RouteParam, - Notes\Route\Annotation\Method\Route, - Notes\Security\Annotation\Security, - Notes\Tell\Annotation\Language; - use Lean\Console\{ Form, Lib }; - -use Picea\Extension\UrlExtension; +use Notes\Tell\Attribute\Language, Notes\Route\Attribute\Method\Route; use function Home\View\{ _, lang, url, route, form }; -/** - * @Language("lean.caching") - */ +#[Language("lean.caching")] class Caching extends Console { use Lib\ConsoleControllerTrait; - /** - * @Route("/caching/picea", "name" => "lean.console:caching") - */ + #[Route(route: "/caching/picea", name: "lean.console:caching")] public function picea(ServerRequestInterface $request, array $arguments) : ResponseInterface { $list = []; diff --git a/src/Controller/Console.php b/src/Controller/Console.php index aedde98..5f5a2eb 100644 --- a/src/Controller/Console.php +++ b/src/Controller/Console.php @@ -4,22 +4,15 @@ namespace Lean\Console\Controller; use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface }; -use Notes\Route\Annotation\Object\Route as RouteParam, - Notes\Route\Annotation\Method\Route, - Notes\Security\Annotation\Security, - Notes\Tell\Annotation\Language; +use Notes\Tell\Attribute\Language, Notes\Route\Attribute\Method\Route; use \Lean\Console\Lib; -/** - * @Language("lean.console") - */ +#[Language("lean.console")] class Console { use Lib\ConsoleControllerTrait; - /** - * @Route("/", "name" => "lean.console:home") - */ + #[Route(route: "/", name: "lean.console:home")] public function home(ServerRequestInterface $request, array $arguments) : ResponseInterface { return $this->renderView("lean-console/page/dashboard/index", [ diff --git a/src/Controller/Dev.php b/src/Controller/Dev.php index 1680371..4f50188 100644 --- a/src/Controller/Dev.php +++ b/src/Controller/Dev.php @@ -4,22 +4,15 @@ namespace Lean\Console\Controller; use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface }; -use Notes\Route\Annotation\Object\Route as RouteParam, - Notes\Route\Annotation\Method\Route, - Notes\Security\Annotation\Security, - Notes\Tell\Annotation\Language; +use Notes\Tell\Attribute\Language, Notes\Route\Attribute\Method\Route; use \Lean\Console\Lib; -/** - * @Language("lean.dev") - */ +#[Language("lean.dev")] class Dev { use Lib\ConsoleControllerTrait; - /** - * @Route("/phpinfo", "name" => "lean.dev:phpinfo") - */ + #[Route(route: "/phpinfo", name: "lean.dev:phpinfo")] public function home(ServerRequestInterface $request, array $arguments) : ResponseInterface { phpinfo(); diff --git a/src/Controller/Request.php b/src/Controller/Request.php index 2210479..407b485 100644 --- a/src/Controller/Request.php +++ b/src/Controller/Request.php @@ -5,27 +5,17 @@ namespace Lean\Console\Controller; use League\Route\Router; use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface }; -use Notes\Route\Annotation\Object\Route as RouteParam, - Notes\Route\Annotation\Method\Route, - Notes\Security\Annotation\Security, - Notes\Tell\Annotation\Language; +use Notes\Tell\Attribute\Language, Notes\Route\Attribute\Method\Route; use \Lean\Console\Lib; use Picea\Extension\UrlExtension; -/** - * @Language("lean.request") - */ +#[Language("lean.request")] class Request extends Console { use Lib\ConsoleControllerTrait; - /** - * @Route("/request/routes", "name" => "lean.console:request.route") - * @param ServerRequestInterface $request - * @param array $arguments - * @return ResponseInterface - */ + #[Route(route: "/request/routes", name: "lean.console:request.route")] public function routes(ServerRequestInterface $request, array $arguments) : ResponseInterface { $routes = $this->container->has(UrlExtension::class) ? $this->container->get(UrlExtension::class)->getRouteList(true) : false; diff --git a/src/Controller/Storage.php b/src/Controller/Storage.php index aa319a8..4d1c92f 100644 --- a/src/Controller/Storage.php +++ b/src/Controller/Storage.php @@ -7,10 +7,7 @@ use League\Route\Router; use Picea\Ui\Method\FormHandler; use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface }; -use Notes\Route\Annotation\Object\Route as RouteParam, - Notes\Route\Annotation\Method\Route, - Notes\Security\Annotation\Security, - Notes\Tell\Annotation\Language; +use Notes\Tell\Attribute\Language, Notes\Route\Attribute\Method\Route; use \Lean\Console\Lib, \Lean\Console\Form; @@ -21,30 +18,37 @@ use Ulmus\Annotation\Classes\Table, Ulmus\Container\AdapterProxy; -/** - * @Language("lean.storage") - */ +#[Language("lean.storage")] class Storage extends Console { use Lib\ConsoleControllerTrait; - /** - * @Route("/storage/database", "name" => "lean.console:storage.database") - */ + #[Route(route: "/storage/database", name: "lean.console:storage.database")] public function database(ServerRequestInterface $request, array $arguments) : ResponseInterface { $connections = $this->container->has(AdapterProxy::class) ? $this->container->get(AdapterProxy::class)->connections : false; $migrations = $this->container->has(Lib\DatabaseMigrations::class) ? $this->container->get(Lib\DatabaseMigrations::class) : false; $migrations->getEntities(); - $form = new FormHandler($request, new Form\Database($migrations), null); - $context = $form->context; + $context = (new FormHandler($request, new Form\Storage\DatabaseMigration($migrations)))->context; return $this->renderView("lean-console/page/storage/database", get_defined_vars()); } - /** - * @Route("/storage/session", "name" => "lean.console:storage.session") - */ + #[Route(route: "/storage/database/import", name: "lean.console:storage.database_import")] + public function database_import(ServerRequestInterface $request, array $arguments) : ResponseInterface + { + $connections = $this->container->has(AdapterProxy::class) ? $this->container->get(AdapterProxy::class)->connections : false; + $migrations = $this->container->has(Lib\DatabaseMigrations::class) ? $this->container->get(Lib\DatabaseMigrations::class) : false; + $migrations->getEntities(); + + $form = new Form\Storage\DatabaseImport($migrations, $connections); + + $context = (new FormHandler($request, $form, $this->pushContext(new Lib\FormContext($request, "database.import"))))->context; + + return $this->renderView("lean-console/page/storage/database_import", get_defined_vars()); + } + + #[Route(route: "/storage/session", name: "lean.console:storage.session")] # migrated from: "/storage/session", "name" => "lean.console:storage.session" public function session(ServerRequestInterface $request, array $arguments) : ResponseInterface { $path = ini_get("session.save_path"); @@ -54,10 +58,7 @@ class Storage extends Console { return $this->renderView("lean-console/page/storage/session", get_defined_vars()); } - /** - * #Taxus('admin') - * @Route("/storage/session/content/{hash}", "name" => "lean.console:storage.session_content") - */ + #[Route(route: "/storage/session/content/{hash}", name: "lean.console:storage.session_content")] # migrated from: "/storage/session/content/{hash}", "name" => "lean.console:storage.session_content" public function sessionContent(ServerRequestInterface $request, array $arguments) : ResponseInterface { $sess = session_encode(); diff --git a/src/Controller/Templating.php b/src/Controller/Templating.php index 237aa1c..750868c 100644 --- a/src/Controller/Templating.php +++ b/src/Controller/Templating.php @@ -7,24 +7,17 @@ use Picea\FileFetcher; use Picea\Picea; use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface }; -use Notes\Route\Annotation\Object\Route as RouteParam, - Notes\Route\Annotation\Method\Route, - Notes\Security\Annotation\Security, - Notes\Tell\Annotation\Language; +use Notes\Tell\Attribute\Language, Notes\Route\Attribute\Method\Route; use \Lean\Console\Lib; use Picea\Extension\UrlExtension; -/** - * @Language("lean.templating") - */ +#[Language("lean.templating")] # migrated from: "lean.templating" class Templating extends Console { use Lib\ConsoleControllerTrait; - /** - * @Route("/templating/picea", "name" => "lean.console:templating.picea") - */ + #[Route(route: "/templating/picea", name: "lean.console:templating.picea")] public function picea(ServerRequestInterface $request, array $arguments) : ResponseInterface { $picea = $this->container->has(Picea::class) ? $this->container->get(Picea::class) : false; diff --git a/src/Entity/Column.php b/src/Entity/Mysql/Column.php similarity index 78% rename from src/Entity/Column.php rename to src/Entity/Mysql/Column.php index b498fc8..3d3f760 100644 --- a/src/Entity/Column.php +++ b/src/Entity/Mysql/Column.php @@ -1,6 +1,6 @@ "columns", 'database' => "information_schema") - */ +use Ulmus\Attribute\Obj\Table; + +#[Table(name: "columns", database: "information_schema")] # migrated from: 'name' => "columns", 'database' => "information_schema" class Column extends InformationSchema\Column { @@ -39,6 +39,5 @@ class Column extends InformationSchema\Column } }; } -*/ } \ No newline at end of file diff --git a/src/Entity/Sqlite/Column.php b/src/Entity/Sqlite/Column.php new file mode 100644 index 0000000..ee0adce --- /dev/null +++ b/src/Entity/Sqlite/Column.php @@ -0,0 +1,42 @@ + + + // return true; + + + } + + return false; + } + +/* public static function entityCollection(...$arguments) : EntityCollection + { + return new class(...$arguments) extends EntityCollection + { + public function getEntityData() : array + { + return [ + + ]; + } + }; + } + +} \ No newline at end of file diff --git a/src/Form/Storage/DatabaseImport.php b/src/Form/Storage/DatabaseImport.php new file mode 100644 index 0000000..e052871 --- /dev/null +++ b/src/Form/Storage/DatabaseImport.php @@ -0,0 +1,63 @@ +migration = $migration; + $this->connections = $connections; + } + + public function initialize(FormContextInterface $context) : void + { + $context->sourceTables ??= new EntityCollection(); + $context->destinationTables ??= new EntityCollection(); + + } + + public function validate(FormContextInterface $context) : bool + { + if ($context->source) { + $filtered = array_filter($this->migration->entities, fn($e, $key) => $key::repository()->adapter->name === $context->source, ARRAY_FILTER_USE_BOTH); + $context->sourceTables->replaceWith($filtered); + } + + return $context->valid(); + } + + public function execute(FormContextInterface $context) : void + { + if ($context->copy) { + foreach (array_filter($context->copy) as $dest => $source) { + foreach($source::repository()->yield() as $src) { + $dest::repository()->save( $src->toArray(), null, true ); + } + } + } + } + + public static function getContext(ServerRequestInterface $request, ? string $formName = null) : FormContextInterface + { + return new class($request, $formName) extends FormContext { + + public EntityCollection $sourceTables; + + public EntityCollection $destinationTables; + + }; + } +} diff --git a/src/Form/Database.php b/src/Form/Storage/DatabaseMigration.php similarity index 91% rename from src/Form/Database.php rename to src/Form/Storage/DatabaseMigration.php index fbff688..296d53a 100644 --- a/src/Form/Database.php +++ b/src/Form/Storage/DatabaseMigration.php @@ -1,6 +1,6 @@ initialize($context); } - public function getContext(ServerRequestInterface $request) : FormContextInterface + public static function getContext(ServerRequestInterface $request, ? string $formName = null) : FormContextInterface { - return new class($request) extends FormContext { + return new class($request, $formName) extends FormContext { public array $status = []; diff --git a/src/Lib/ConsoleControllerTrait.php b/src/Lib/ConsoleControllerTrait.php index e5c1c9f..8c54a0b 100644 --- a/src/Lib/ConsoleControllerTrait.php +++ b/src/Lib/ConsoleControllerTrait.php @@ -6,15 +6,17 @@ use Psr\Container\ContainerInterface; use Storage\Session; +use Notes\Tell\Attribute\Language, + Notes\Route\Attribute\Object\Route; + +use Notes\Security\Attribute\{ Security, Taxus }; + use Picea; -/** - * @Language("lean.route") - * @RouteParam("methods" => [ 'GET', 'POST', 'DELETE' ], "base" => "/~") - * @Security('locked' => false) - * @Taxus("dev") - * #Taxus("admin") - */ +#[Language("lean.route")] +#[Security(locked: false)] +#[Taxus("dev")] +#[\Notes\Route\Attribute\Object\Route(method: [ 'GET', 'POST', 'DELETE'] , base: "/~")] trait ConsoleControllerTrait { use \Lean\ControllerTrait; diff --git a/view/lean-console/base/asset/lean.css b/view/lean-console/base/asset/lean.css index 931e47b..05a6fa8 100644 --- a/view/lean-console/base/asset/lean.css +++ b/view/lean-console/base/asset/lean.css @@ -10,7 +10,9 @@ [class^="btn-"], [class~=" btn-"] { display: inline-block; font-weight: 400; text-align: center; white-space: nowrap; vertical-align: middle; user-select: none; border: 1px solid transparent; padding: .375rem .75rem; font-size: 1rem; line-height: 1.5; border-radius: .25rem; cursor:pointer; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; background:rgba(0,0,0,0.3); color:rgba(255,255,255,0.8); } [class^="btn-"]:hover, [class~=" btn-"]:hover {border-color: rgba(0, 0, 0, 0.5);text-decoration: underline;} -.btn-red {background: rgba(255,0,0,0.5);color: rgba(255, 255, 255, 0.9);} +.btn-red {background: rgba(155,0,0,0.5);color: rgba(255, 255, 255, 0.9);} +.btn-green {background: rgba(0,155,0,0.5);color: rgba(255, 255, 255, 0.9);} +.btn-blue {background: rgba(0,0,155,0.5);color: rgba(255, 255, 255, 0.9);} code {white-space:pre;font-family:monospace;color: #e6e6e6;background: #343537;display: block;padding: 1rem;line-height: 1.5em;border: 1px solid #2e2e30;} h1 {font-size:2rem;color:#525960} @@ -40,4 +42,6 @@ summary {cursor:pointer;} #main-content {padding:4vh 2vw;border-top:2px solid #7d7d7d;width:100%;} #main-content section {border-radius:4px;box-shadow: 1px 1px 3px rgba(0,0,0,0.5)} #main-content section article {background:#fff;padding:2vh 1vw;} -#main-content section header {background:#e8e8e8;padding:2vh 1vw;} \ No newline at end of file +#main-content section header {background:#e8e8e8;padding:2vh 1vw;font-size:1.4em;color: #4b4848 +} +#main-content section footer {background:#f9f9f9;padding:2vh 1vw;} \ No newline at end of file diff --git a/view/lean-console/page/storage/database.phtml b/view/lean-console/page/storage/database.phtml index 3d8ddcd..01305ee 100644 --- a/view/lean-console/page/storage/database.phtml +++ b/view/lean-console/page/storage/database.phtml @@ -9,15 +9,10 @@ {% endsection %} {% section "content" %} -
- {% if $connections %} - {% foreach $connections as $connection %} + {% if $connections %} + {% foreach $connections as $connection %} +
{% php $conf = $connection->getConfiguration(); %} - -
-

{{ $connection->name }}

-
-
{% _ 'database.connection' %}
@@ -28,11 +23,11 @@
-
-
{{ $conf['adapter'] ?? '-' }}
-
{{ $conf['host'] ?? '-' }}:{{ $conf['port'] ?? '-' }}
-
{{ $conf['database'] ?? '-' }}
-
{{ $conf['username'] ?? '-' }}
+
{{ $connection->name }}
+
{{ $connection->adapter()::class }}
+
{{ $connection->adapter()->hostname ?? '-' }}:{{ $connection->adapter()->port ?? '-' }}
+
{{ $connection->adapter()->database ?? '-' }}
+
{{ $connection->adapter()->username ?? '-' }}
@@ -86,9 +81,9 @@ {% ui.endform %}
- {% endforeach %} - {% endif %} -
+
+ {% endforeach %} + {% endif %} {% endsection %} \ No newline at end of file diff --git a/view/lean-console/page/storage/database_import.phtml b/view/lean-console/page/storage/database_import.phtml new file mode 100644 index 0000000..34a1dd7 --- /dev/null +++ b/view/lean-console/page/storage/database_import.phtml @@ -0,0 +1,71 @@ +{% extends "lean-console/base/layout" %} + +{% language.set "lean.storage" %} + +{% title _("title") %} + +{% section "header" %} +
{% _ "page-title" %}
+{% endsection %} + +{% section "content" %} + {% if $connections %} + {% ui.form.post "database.import" %} +
+
Import data from a connection into another
+ +
+ {% if ! $context->source %} + {% php $select = array_combine(array_column($connections, 'name'), array_column($connections, 'name')) %} + +
+ Source connection: {% ui.select "source", $select %} +
+ +
+ Destination connection: {% ui.select "destination", $select %} +
+ {% else %} + {% ui.hidden 'source', $context->source %} + {% ui.hidden 'destination', $context->destination %} + +
+ COPY DATA FROM → TO: + {% php $dest = array_filter($migrations->entities, fn($e, $key) => $key::repository()->adapter->name === $context->destination, ARRAY_FILTER_USE_BOTH); %} + + {% foreach $dest as $key => $value %} +
+ {% ui.select "copy[$key]", [ null => '' ] + $context->sourceTables->buildArray('entityClass', 'entityClass') %} + + {{ sprintf('%s (%s)', $key, $value->tableName()) }} +
+ {% endforeach %} +
+ {% endif %} +
+ + +
+ {% ui.endform %} + {% else %} + No connection found + {% endif %} + + +{% endsection %} \ No newline at end of file