Changeset View
Changeset View
Standalone View
Standalone View
src/app/Console/Command.php
<?php | <?php | ||||
namespace App\Console; | namespace App\Console; | ||||
class Command extends \Illuminate\Console\Command | use Illuminate\Support\Facades\DB; | ||||
abstract class Command extends \Illuminate\Console\Command | |||||
{ | { | ||||
/** | /** | ||||
* Annotate this command as being dangerous for any potential unintended consequences. | |||||
* | |||||
* Commands are considered dangerous if; | |||||
* | |||||
* * observers are deliberately not triggered, meaning that the deletion of an object model that requires the | |||||
* associated observer to clean some things up, or charge a wallet or something, are deliberately not triggered, | |||||
* | |||||
* * deletion of objects and their relations rely on database foreign keys with obscure cascading, | |||||
* | |||||
* * a command will result in the permanent, irrecoverable loss of data. | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
protected $dangerous = false; | |||||
/** | |||||
* Find the domain. | * Find the domain. | ||||
* | * | ||||
* @param string $domain Domain ID or namespace | * @param string $domain Domain ID or namespace | ||||
* @param bool $withDeleted Include deleted | |||||
* | * | ||||
* @return \App\Domain|null | * @return \App\Domain|null | ||||
*/ | */ | ||||
public function getDomain($domain) | public function getDomain($domain, $withDeleted = false) | ||||
{ | { | ||||
return $this->getObject(\App\Domain::class, $domain, 'namespace'); | return $this->getObject(\App\Domain::class, $domain, 'namespace', $withDeleted); | ||||
} | } | ||||
/** | /** | ||||
* Find an object. | * Find an object. | ||||
* | * | ||||
* @param string $objectClass The name of the class | * @param string $objectClass The name of the class | ||||
* @param string $objectIdOrTitle The name of a database field to match. | * @param string $objectIdOrTitle The name of a database field to match. | ||||
* @param string|null $objectTitle An additional database field to match. | * @param string|null $objectTitle An additional database field to match. | ||||
* @param bool $withDeleted Act as if --with-deleted was used | |||||
* | * | ||||
* @return mixed | * @return mixed | ||||
*/ | */ | ||||
public function getObject($objectClass, $objectIdOrTitle, $objectTitle) | public function getObject($objectClass, $objectIdOrTitle, $objectTitle = null, $withDeleted = false) | ||||
{ | { | ||||
if ($this->hasOption('with-deleted') && $this->option('with-deleted')) { | if (!$withDeleted) { | ||||
$object = $objectClass::withTrashed()->find($objectIdOrTitle); | $withDeleted = $this->hasOption('with-deleted') && $this->option('with-deleted'); | ||||
} else { | |||||
$object = $objectClass::find($objectIdOrTitle); | |||||
} | } | ||||
$object = $this->getObjectModel($objectClass, $withDeleted)->find($objectIdOrTitle); | |||||
if (!$object && !empty($objectTitle)) { | if (!$object && !empty($objectTitle)) { | ||||
if ($this->hasOption('with-deleted') && $this->option('with-deleted')) { | $object = $this->getObjectModel($objectClass, $withDeleted) | ||||
$object = $objectClass::withTrashed()->where($objectTitle, $objectIdOrTitle)->first(); | ->where($objectTitle, $objectIdOrTitle)->first(); | ||||
} | |||||
return $object; | |||||
} | |||||
/** | |||||
* Returns a preconfigured Model object for a specified class. | |||||
* | |||||
* @param string $objectClass The name of the class | |||||
* @param bool $withDeleted Include withTrashed() query | |||||
* | |||||
* @return mixed | |||||
*/ | |||||
protected function getObjectModel($objectClass, $withDeleted = false) | |||||
{ | |||||
if ($withDeleted) { | |||||
$model = $objectClass::withTrashed(); | |||||
} else { | } else { | ||||
$object = $objectClass::where($objectTitle, $objectIdOrTitle)->first(); | $model = new $objectClass(); | ||||
} | } | ||||
$modelsWithTenant = [ | |||||
\App\Discount::class, | |||||
\App\Domain::class, | |||||
\App\Group::class, | |||||
\App\Package::class, | |||||
\App\Plan::class, | |||||
\App\Sku::class, | |||||
\App\User::class, | |||||
]; | |||||
$modelsWithOwner = [ | |||||
\App\Wallet::class, | |||||
]; | |||||
$tenant_id = \config('app.tenant_id'); | |||||
// Add tenant filter | |||||
if (in_array($objectClass, $modelsWithTenant)) { | |||||
$model = $model->withEnvTenant(); | |||||
} elseif (in_array($objectClass, $modelsWithOwner)) { | |||||
$model = $model->whereExists(function ($query) use ($tenant_id) { | |||||
$query->select(DB::raw(1)) | |||||
->from('users') | |||||
->whereRaw('wallets.user_id = users.id') | |||||
->whereRaw('users.tenant_id ' . ($tenant_id ? "= $tenant_id" : 'is null')); | |||||
}); | |||||
} | } | ||||
return $object; | // TODO: tenant check for Entitlement, Transaction, etc. | ||||
return $model; | |||||
} | } | ||||
/** | /** | ||||
* Find the user. | * Find the user. | ||||
* | * | ||||
* @param string $user User ID or email | * @param string $user User ID or email | ||||
* @param bool $withDeleted Include deleted | |||||
* | * | ||||
* @return \App\User|null | * @return \App\User|null | ||||
*/ | */ | ||||
public function getUser($user) | public function getUser($user, $withDeleted = false) | ||||
{ | { | ||||
return $this->getObject(\App\User::class, $user, 'email'); | return $this->getObject(\App\User::class, $user, 'email', $withDeleted); | ||||
} | } | ||||
/** | /** | ||||
* Find the wallet. | * Find the wallet. | ||||
* | * | ||||
* @param string $wallet Wallet ID | * @param string $wallet Wallet ID | ||||
* | * | ||||
* @return \App\Wallet|null | * @return \App\Wallet|null | ||||
*/ | */ | ||||
public function getWallet($wallet) | public function getWallet($wallet) | ||||
{ | { | ||||
return $this->getObject(\App\Wallet::class, $wallet, null); | return $this->getObject(\App\Wallet::class, $wallet, null); | ||||
} | } | ||||
public function handle() | |||||
{ | |||||
if ($this->dangerous) { | |||||
$this->warn( | |||||
"This command is a dangerous scalpel command with potentially significant unintended consequences" | |||||
); | |||||
$confirmation = $this->confirm("Are you sure you understand what's about to happen?"); | |||||
if (!$confirmation) { | |||||
$this->info("Better safe than sorry."); | |||||
return false; | |||||
} | |||||
$this->info("Vámonos!"); | |||||
} | |||||
return true; | |||||
} | |||||
/** | /** | ||||
* Return a string for output, with any additional attributes specified as well. | * Return a string for output, with any additional attributes specified as well. | ||||
* | * | ||||
* @param mixed $entry An object | * @param mixed $entry An object | ||||
* | * | ||||
* @return string | * @return string | ||||
*/ | */ | ||||
protected function toString($entry) | protected function toString($entry) | ||||
Show All 34 Lines |