Page MenuHomePhorge

D4689.1775214035.diff
No OneTemporary

Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None

D4689.1775214035.diff

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
@@ -224,6 +224,18 @@
return true;
}
+ /**
+ * Checks that a model is soft-deletable
+ *
+ * @param string $class Model class name
+ *
+ * @return bool
+ */
+ protected function isSoftDeletable($class)
+ {
+ return class_exists($class) && method_exists($class, 'forceDelete');
+ }
+
/**
* Return a string for output, with any additional attributes specified as well.
*
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
@@ -2,8 +2,6 @@
namespace App\Console;
-use Illuminate\Database\Eloquent\SoftDeletes;
-
/**
* This abstract class provides a means to treat objects in our model using CRUD.
*/
@@ -19,9 +17,7 @@
$this->objectName
);
- $classes = class_uses_recursive($this->objectClass);
-
- if (in_array(SoftDeletes::class, $classes)) {
+ if ($this->isSoftDeletable($this->objectClass)) {
$this->signature .= " {--with-deleted : Consider deleted {$this->objectName}s}";
}
diff --git a/src/app/Console/ObjectListCommand.php b/src/app/Console/ObjectListCommand.php
--- a/src/app/Console/ObjectListCommand.php
+++ b/src/app/Console/ObjectListCommand.php
@@ -2,8 +2,6 @@
namespace App\Console;
-use Illuminate\Database\Eloquent\SoftDeletes;
-
/**
* This abstract class provides a means to treat objects in our model using CRUD, with the exception that
* this particular abstract class lists objects.
@@ -22,9 +20,7 @@
$this->signature .= "{$this->objectName}s";
}
- $classes = class_uses_recursive($this->objectClass);
-
- if (in_array(SoftDeletes::class, $classes)) {
+ if ($this->isSoftDeletable($this->objectClass)) {
$this->signature .= " {--with-deleted : Include deleted {$this->objectName}s}";
}
@@ -41,10 +37,7 @@
*/
public function handle()
{
- $classes = class_uses_recursive($this->objectClass);
-
- // @phpstan-ignore-next-line
- if (in_array(SoftDeletes::class, $classes) && $this->option('with-deleted')) {
+ if ($this->isSoftDeletable($this->objectClass) && $this->option('with-deleted')) {
$objects = $this->objectClass::withTrashed();
} else {
$objects = new $this->objectClass();
diff --git a/src/app/Console/ObjectRelationListCommand.php b/src/app/Console/ObjectRelationListCommand.php
--- a/src/app/Console/ObjectRelationListCommand.php
+++ b/src/app/Console/ObjectRelationListCommand.php
@@ -2,6 +2,7 @@
namespace App\Console;
+use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Str;
/**
@@ -24,6 +25,13 @@
*/
protected $objectRelationArgs = [];
+ /**
+ * The "relation" model class.
+ *
+ * @var string
+ */
+ protected $objectRelationClass;
+
/**
* Supplement the base command constructor with a derived or generated signature and
* description.
@@ -42,6 +50,14 @@
$this->objectName
);
+ if (empty($this->objectRelationClass)) {
+ $this->objectRelationClass = "App\\" . rtrim(ucfirst($this->objectRelation), 's');
+ }
+
+ if ($this->isSoftDeletable($this->objectRelationClass)) {
+ $this->signature .= " {--with-deleted : Include deleted objects}";
+ }
+
$this->signature .= " {--attr=* : Attributes other than the primary unique key to include}";
parent::__construct();
@@ -59,7 +75,8 @@
$object = $this->getObject(
$this->objectClass,
$argument,
- $this->objectTitle
+ $this->objectTitle,
+ true
);
if (!$object) {
@@ -81,6 +98,11 @@
($result instanceof \Illuminate\Database\Eloquent\Relations\Relation)
|| ($result instanceof \Illuminate\Database\Eloquent\Builder)
) {
+ // @phpstan-ignore-next-line
+ if ($this->isSoftDeletable($this->objectRelationClass) && $this->option('with-deleted')) {
+ $result->withoutGlobalScope(SoftDeletingScope::class);
+ }
+
$result = $result->get();
}
diff --git a/src/tests/Feature/Console/User/UsersTest.php b/src/tests/Feature/Console/User/UsersTest.php
--- a/src/tests/Feature/Console/User/UsersTest.php
+++ b/src/tests/Feature/Console/User/UsersTest.php
@@ -2,10 +2,30 @@
namespace Tests\Feature\Console\User;
+use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
class UsersTest extends TestCase
{
+ /**
+ * {@inheritDoc}
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->deleteTestUser('user@force-delete.com');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function tearDown(): void
+ {
+ $this->deleteTestUser('user@force-delete.com');
+
+ parent::tearDown();
+ }
/**
* Test command runs
*/
@@ -26,5 +46,27 @@
$this->assertStringContainsString("ned@kolab.org", $output);
$this->assertStringContainsString("joe@kolab.org", $output);
$this->assertStringContainsString("jack@kolab.org", $output);
+
+ // Test behaviour with deleted users
+ Queue::fake();
+
+ // Note: User:users() uses entitlements to get the owned users,
+ // so we add a single entitlement, then we can soft-delete the user
+ $user = $this->getTestUser('user@force-delete.com');
+ $storage = \App\Sku::withEnvTenantContext()->where('title', 'storage')->first();
+ $user->assignSku($storage, 1);
+ $user->delete();
+
+ $code = \Artisan::call("user:users {$user->email} --attr=email");
+ $output = trim(\Artisan::output());
+
+ $this->assertSame(0, $code);
+ $this->assertSame('', trim($output));
+
+ $code = \Artisan::call("user:users {$user->email} --with-deleted --attr=email");
+ $output = trim(\Artisan::output());
+
+ $this->assertSame(0, $code);
+ $this->assertSame("{$user->id} {$user->email}", trim($output));
}
}

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 11:00 AM (6 h, 26 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18823734
Default Alt Text
D4689.1775214035.diff (6 KB)

Event Timeline