mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-15 17:22:34 -04:00
127 lines
3.8 KiB
PHP
127 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands\Cloud;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use RuntimeException;
|
|
use Throwable;
|
|
|
|
class ExportUsers extends Command
|
|
{
|
|
protected $signature = 'cloud:export-users';
|
|
|
|
protected $description = 'Export subscribed and unsubscribed verified Coolify Cloud users to separate CSV files';
|
|
|
|
/**
|
|
* The import format of the email platform. cloud:cleanup-unsubscribed-teams writes deleted users in the same format.
|
|
*/
|
|
public const CSV_HEADER = [
|
|
'email',
|
|
'first_name',
|
|
'last_name',
|
|
'lifetime_value_currency',
|
|
'lifetime_value_amount',
|
|
'utm_campaign',
|
|
'utm_source',
|
|
'utm_medium',
|
|
'utm_content',
|
|
'utm_term',
|
|
'phone',
|
|
];
|
|
|
|
public function handle(): int
|
|
{
|
|
if (! isCloud()) {
|
|
$this->error('This command can only be run on Coolify Cloud.');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$backups = Storage::disk('backups');
|
|
$backups->delete('cloud-users.csv');
|
|
|
|
$subscribedPath = $backups->path('cloud-users-subscribed.csv');
|
|
$unsubscribedPath = $backups->path('cloud-users-unsubscribed.csv');
|
|
$subscribedOutput = fopen($subscribedPath, 'wb');
|
|
|
|
if ($subscribedOutput === false) {
|
|
$this->error("Unable to open {$subscribedPath} for writing.");
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$unsubscribedOutput = fopen($unsubscribedPath, 'wb');
|
|
|
|
if ($unsubscribedOutput === false) {
|
|
fclose($subscribedOutput);
|
|
$this->error("Unable to open {$unsubscribedPath} for writing.");
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$subscribedCount = 0;
|
|
$unsubscribedCount = 0;
|
|
|
|
try {
|
|
self::writeCsvRow($subscribedOutput, self::CSV_HEADER);
|
|
self::writeCsvRow($unsubscribedOutput, self::CSV_HEADER);
|
|
|
|
foreach (User::query()
|
|
->select(['id', 'email', 'name'])
|
|
->where('id', '!=', 0)
|
|
->whereNotNull('email_verified_at')
|
|
->withExists([
|
|
'teams as is_subscribed' => fn ($query) => $query
|
|
->whereRelation('subscription', 'stripe_invoice_paid', true),
|
|
])
|
|
->lazyById(500) as $user) {
|
|
$row = self::csvRow($user);
|
|
|
|
if ($user->is_subscribed) {
|
|
self::writeCsvRow($subscribedOutput, $row);
|
|
$subscribedCount++;
|
|
} else {
|
|
self::writeCsvRow($unsubscribedOutput, $row);
|
|
$unsubscribedCount++;
|
|
}
|
|
}
|
|
} catch (Throwable $exception) {
|
|
$this->error("Unable to export users: {$exception->getMessage()}");
|
|
|
|
return self::FAILURE;
|
|
} finally {
|
|
fclose($subscribedOutput);
|
|
fclose($unsubscribedOutput);
|
|
}
|
|
|
|
$this->info("Exported {$subscribedCount} subscribed verified users to {$subscribedPath}");
|
|
$this->info("Exported {$unsubscribedCount} unsubscribed verified users to {$unsubscribedPath}");
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @return list<string>
|
|
*/
|
|
public static function csvRow(User $user): array
|
|
{
|
|
$nameParts = preg_split('/\s+/u', trim((string) $user->name), 2) ?: [];
|
|
[$firstName, $lastName] = array_pad($nameParts, 2, '');
|
|
|
|
return [$user->email, $firstName, $lastName, '', '', '', '', '', '', '', ''];
|
|
}
|
|
|
|
/**
|
|
* @param resource $output
|
|
* @param array<int, mixed> $fields
|
|
*/
|
|
public static function writeCsvRow($output, array $fields): void
|
|
{
|
|
if (fputcsv($output, $fields, ',', '"', '') === false) {
|
|
throw new RuntimeException('Unable to write the CSV file.');
|
|
}
|
|
}
|
|
}
|