Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117924032
D4388.1775441879.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
12 KB
Referenced Files
None
Subscribers
None
D4388.1775441879.diff
View Options
diff --git a/src/app/Console/Command.php b/src/app/Console/Command.php
--- a/src/app/Console/Command.php
+++ b/src/app/Console/Command.php
@@ -199,6 +199,11 @@
return $this->getObject(\App\Wallet::class, $wallet, null);
}
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
public function handle()
{
if ($this->dangerous) {
diff --git a/src/app/Console/Commands/Scalpel/TenantSetting/CreateCommand.php b/src/app/Console/Commands/Scalpel/TenantSetting/CreateCommand.php
--- a/src/app/Console/Commands/Scalpel/TenantSetting/CreateCommand.php
+++ b/src/app/Console/Commands/Scalpel/TenantSetting/CreateCommand.php
@@ -6,6 +6,8 @@
class CreateCommand extends ObjectCreateCommand
{
+ protected $hidden = true;
+
protected $commandPrefix = 'scalpel';
protected $objectClass = \App\TenantSetting::class;
protected $objectName = 'tenant-setting';
diff --git a/src/app/Console/Commands/Scalpel/TenantSetting/UpdateCommand.php b/src/app/Console/Commands/Scalpel/TenantSetting/UpdateCommand.php
--- a/src/app/Console/Commands/Scalpel/TenantSetting/UpdateCommand.php
+++ b/src/app/Console/Commands/Scalpel/TenantSetting/UpdateCommand.php
@@ -6,6 +6,8 @@
class UpdateCommand extends ObjectUpdateCommand
{
+ protected $hidden = true;
+
protected $commandPrefix = 'scalpel';
protected $objectClass = \App\TenantSetting::class;
protected $objectName = 'tenant-setting';
diff --git a/src/app/Console/Commands/Scalpel/Wallet/SettingsCommand.php b/src/app/Console/Commands/Scalpel/Wallet/SettingsCommand.php
--- a/src/app/Console/Commands/Scalpel/Wallet/SettingsCommand.php
+++ b/src/app/Console/Commands/Scalpel/Wallet/SettingsCommand.php
@@ -6,6 +6,8 @@
class SettingsCommand extends ObjectRelationListCommand
{
+ protected $hidden = true;
+
protected $commandPrefix = 'scalpel';
protected $objectClass = \App\Wallet::class;
protected $objectName = 'wallet';
diff --git a/src/app/Console/Commands/Scalpel/WalletSetting/CreateCommand.php b/src/app/Console/Commands/Scalpel/WalletSetting/CreateCommand.php
--- a/src/app/Console/Commands/Scalpel/WalletSetting/CreateCommand.php
+++ b/src/app/Console/Commands/Scalpel/WalletSetting/CreateCommand.php
@@ -6,6 +6,8 @@
class CreateCommand extends ObjectCreateCommand
{
+ protected $hidden = true;
+
protected $commandPrefix = 'scalpel';
protected $objectClass = \App\WalletSetting::class;
protected $objectName = 'wallet-setting';
diff --git a/src/app/Console/Commands/Scalpel/WalletSetting/UpdateCommand.php b/src/app/Console/Commands/Scalpel/WalletSetting/UpdateCommand.php
--- a/src/app/Console/Commands/Scalpel/WalletSetting/UpdateCommand.php
+++ b/src/app/Console/Commands/Scalpel/WalletSetting/UpdateCommand.php
@@ -6,6 +6,8 @@
class UpdateCommand extends ObjectUpdateCommand
{
+ protected $hidden = true;
+
protected $commandPrefix = 'scalpel';
protected $objectClass = \App\WalletSetting::class;
protected $objectName = 'wallet-setting';
diff --git a/src/app/Console/ObjectCommand.php b/src/app/Console/ObjectCommand.php
--- a/src/app/Console/ObjectCommand.php
+++ b/src/app/Console/ObjectCommand.php
@@ -2,8 +2,6 @@
namespace App\Console;
-use Illuminate\Support\Facades\Cache;
-
abstract class ObjectCommand extends Command
{
/**
diff --git a/src/app/Console/ObjectCreateCommand.php b/src/app/Console/ObjectCreateCommand.php
--- a/src/app/Console/ObjectCreateCommand.php
+++ b/src/app/Console/ObjectCreateCommand.php
@@ -25,7 +25,7 @@
parent::__construct();
}
- public function getProperties()
+ protected function getProperties()
{
if (!empty($this->properties)) {
return $this->properties;
@@ -44,19 +44,13 @@
/**
* Execute the console command.
- *
- * @return mixed
*/
public function handle()
{
- $this->getProperties();
-
- $class = new $this->objectClass();
-
- $object = $this->objectClass::create($this->properties);
+ $object = $this->objectClass::create($this->getProperties());
if ($object) {
- $this->info($object->{$class->getKeyName()});
+ $this->info($object->{$object->getKeyName()});
} else {
$this->error("Object could not be created.");
}
diff --git a/src/app/Console/ObjectDeleteCommand.php b/src/app/Console/ObjectDeleteCommand.php
--- a/src/app/Console/ObjectDeleteCommand.php
+++ b/src/app/Console/ObjectDeleteCommand.php
@@ -3,7 +3,6 @@
namespace App\Console;
use Illuminate\Database\Eloquent\SoftDeletes;
-use Illuminate\Support\Facades\Schema;
/**
* This abstract class provides a means to treat objects in our model using CRUD.
@@ -20,20 +19,6 @@
$this->objectName
);
- $class = new $this->objectClass();
-
- try {
- foreach (Schema::getColumnListing($class->getTable()) as $column) {
- if ($column == "id") {
- continue;
- }
-
- $this->signature .= " {--{$column}=}";
- }
- } catch (\Exception $e) {
- \Log::error("Could not extract options: {$e->getMessage()}");
- }
-
$classes = class_uses_recursive($this->objectClass);
if (in_array(SoftDeletes::class, $classes)) {
@@ -43,29 +28,6 @@
parent::__construct();
}
- public function getProperties()
- {
- if (!empty($this->properties)) {
- return $this->properties;
- }
-
- $class = new $this->objectClass();
-
- $this->properties = [];
-
- foreach (Schema::getColumnListing($class->getTable()) as $column) {
- if ($column == "id") {
- continue;
- }
-
- if (($value = $this->option($column)) !== null) {
- $this->properties[$column] = $value;
- }
- }
-
- return $this->properties;
- }
-
/**
* Execute the console command.
*
diff --git a/src/app/Console/ObjectUpdateCommand.php b/src/app/Console/ObjectUpdateCommand.php
--- a/src/app/Console/ObjectUpdateCommand.php
+++ b/src/app/Console/ObjectUpdateCommand.php
@@ -2,9 +2,6 @@
namespace App\Console;
-use Illuminate\Database\Eloquent\SoftDeletes;
-use Illuminate\Support\Facades\Schema;
-
/**
* This abstract class provides a means to treat objects in our model using CRUD.
*/
@@ -20,29 +17,66 @@
$this->objectName
);
- $class = new $this->objectClass();
+ // This constructor is called for every ObjectUpdateCommand command,
+ // no matter which command is being executed. We should not use database
+ // access from here. And it should be as fast as possible.
- try {
- foreach (Schema::getColumnListing($class->getTable()) as $column) {
- if ($column == "id") {
- continue;
- }
+ $class = new $this->objectClass();
- $this->signature .= " {--{$column}=}";
+ foreach ($this->getClassProperties() as $property) {
+ if ($property == 'id') {
+ continue;
}
- } catch (\Exception $e) {
- \Log::error("Could not extract options: {$e->getMessage()}");
- }
- $classes = class_uses_recursive($this->objectClass);
+ $this->signature .= " {--{$property}=}";
+ }
- if (in_array(SoftDeletes::class, $classes)) {
+ if (method_exists($class, 'restore')) {
$this->signature .= " {--with-deleted : Include deleted {$this->objectName}s}";
}
parent::__construct();
}
+ /**
+ * Get all properties (sql table columns) of the model class
+ */
+ protected function getClassProperties(): array
+ {
+ // We are not using table information schema, because it makes
+ // all artisan commands slow. We depend on the @property definitions
+ // in the class documentation comment.
+
+ $reflector = new \ReflectionClass($this->objectClass);
+ $list = [];
+
+ if (preg_match_all('/@property\s+([^$\s]+)\s+\$([a-z_]+)/', $reflector->getDocComment(), $matches)) {
+ foreach ($matches[1] as $key => $type) {
+ $type = preg_replace('/[\?]/', '', $type);
+ if (preg_match('/^(int|string|float|bool|\\Carbon\\Carbon)$/', $type)) {
+ $list[] = $matches[2][$key];
+ }
+ }
+ }
+
+ // Add created_at, updated_at, deleted_at where applicable
+ if ($this->commandPrefix == 'scalpel') {
+ $class = new $this->objectClass();
+
+ if ($class->timestamps && !in_array('created_at', $list)) {
+ $list[] = 'created_at';
+ }
+ if ($class->timestamps && !in_array('updated_at', $list)) {
+ $list[] = 'updated_at';
+ }
+ if (method_exists($class, 'restore') && !in_array('deleted_at', $list)) {
+ $list[] = 'deleted_at';
+ }
+ }
+
+ return $list;
+ }
+
public function getProperties()
{
if (!empty($this->properties)) {
@@ -53,13 +87,13 @@
$this->properties = [];
- foreach (Schema::getColumnListing($class->getTable()) as $column) {
- if ($column == "id") {
+ foreach ($this->getClassProperties() as $property) {
+ if ($property == 'id') {
continue;
}
- if (($value = $this->option($column)) !== null) {
- $this->properties[$column] = $value;
+ if (($value = $this->option($property)) !== null) {
+ $this->properties[$property] = $value;
}
}
@@ -83,15 +117,13 @@
}
foreach ($this->getProperties() as $property => $value) {
- if ($property == "deleted_at" && $value == "null") {
+ if ($property == 'deleted_at' && $value === 'null') {
$value = null;
}
$object->{$property} = $value;
}
- $object->timestamps = false;
-
if ($this->commandPrefix == 'scalpel') {
$object->saveQuietly();
} else {
diff --git a/src/tests/Feature/Console/Scalpel/Domain/UpdateCommandTest.php b/src/tests/Feature/Console/Scalpel/Domain/UpdateCommandTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Feature/Console/Scalpel/Domain/UpdateCommandTest.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Tests\Feature\Console\Scalpel\Domain;
+
+use App\Domain;
+use Tests\TestCase;
+
+class UpdateCommandTest extends TestCase
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->deleteTestDomain('domain-delete.com');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function tearDown(): void
+ {
+ $this->deleteTestDomain('domain-delete.com');
+ $this->deleteTestDomain('domain-delete-mod.com');
+
+ parent::tearDown();
+ }
+
+ /**
+ * Test the command execution
+ */
+ public function testHandle(): void
+ {
+ // Test unknown domain
+ $this->artisan("scalpel:domain:update unknown")
+ ->assertExitCode(1)
+ ->expectsOutput("No such domain unknown");
+
+ $domain = $this->getTestDomain('domain-delete.com', [
+ 'status' => Domain::STATUS_NEW,
+ 'type' => Domain::TYPE_HOSTED,
+ ]);
+
+ // Test successful update
+ $this->artisan("scalpel:domain:update {$domain->id}"
+ . " --namespace=domain-delete-mod.com --type=" . Domain::TYPE_PUBLIC)
+ ->assertExitCode(0);
+
+ $domain->refresh();
+
+ $this->assertSame('domain-delete-mod.com', $domain->namespace);
+ $this->assertSame(Domain::TYPE_PUBLIC, $domain->type);
+
+ // Test --help argument
+ $code = \Artisan::call("scalpel:domain:update --help");
+ $output = trim(\Artisan::output());
+
+ $this->assertStringContainsString('--with-deleted', $output);
+ $this->assertStringContainsString('--namespace[=NAMESPACE]', $output);
+ $this->assertStringContainsString('--type[=TYPE]', $output);
+ $this->assertStringContainsString('--status[=STATUS]', $output);
+ $this->assertStringContainsString('--tenant_id[=TENANT_ID]', $output);
+ $this->assertStringContainsString('--created_at[=CREATED_AT]', $output);
+ $this->assertStringContainsString('--updated_at[=UPDATED_AT]', $output);
+ $this->assertStringContainsString('--deleted_at[=DELETED_AT]', $output);
+ $this->assertStringNotContainsString('--id', $output);
+ }
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 2:17 AM (7 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18826050
Default Alt Text
D4388.1775441879.diff (12 KB)
Attached To
Mode
D4388: Make Artisan to not require database connection when not needed, other improvements
Attached
Detach File
Event Timeline