option('apply'); $only = $this->option('server') !== null ? (int) $this->option('server') : null; $rows = DB::table('site_server') ->select('id', 'domain', 'site_id', 'server_id', 'stream', 'stream_tv') ->when($only, fn ($query) => $query->where('server_id', '=', $only)) ->orderBy('server_id') ->orderBy('site_id') ->get(); if ($rows->isEmpty()) { $this->info('Nenhuma linha em site_server' . ($only ? ' para o servidor ' . $only : '') . '.'); return 0; } $empty = $rows->filter(fn ($row) => $this->isEmpty($row->stream) || $this->isEmpty($row->stream_tv)); $this->line('Linhas em site_server: ' . $rows->count()); $this->line('Com stream ou stream_tv vazio: ' . $empty->count()); $this->newLine(); $filled = 0; $missing = []; $different = []; $failed = []; foreach ($rows->groupBy('server_id') as $server => $group) { $server = (int) $server; $connection = 'mysql_site_' . $server; if (! config('database.connections.' . $connection)) { $failed[] = 'Servidor ' . $server . ': conexão ' . $connection . ' não existe em config/database.php'; continue; } try { $sites = $this->sitesOf($connection, $group->pluck('site_id')->all()); } catch (Throwable $e) { $failed[] = 'Servidor ' . $server . ': ' . $e->getMessage(); continue; } foreach ($group as $row) { $site = $sites[(int) $row->site_id] ?? null; if (! $site) { if ($this->isEmpty($row->stream) && $this->isEmpty($row->stream_tv)) { $missing[] = $this->label($row) . ': não existe em sites do servidor ' . $server; } continue; } $port = (int) ($site->stream_port ?? 0); $isTv = (string) ($site->stream_tv ?? '0') === '1'; $tvName = trim((string) ($site->stream_tv_name ?? '')); $values = []; if ($this->isEmpty($row->stream) && $port > 0) { $values['stream'] = (string) $port; } if ($this->isEmpty($row->stream_tv) && $isTv && $tvName !== '') { $values['stream_tv'] = $tvName; } /* already filled and disagreeing with the server: only reported */ if (! $this->isEmpty($row->stream) && $port > 0 && (string) $row->stream !== (string) $port) { $different[] = $this->label($row) . ': stream ' . $row->stream . ' aqui, ' . $port . ' no servidor'; } if (! $this->isEmpty($row->stream_tv) && $tvName !== '' && (string) $row->stream_tv !== $tvName) { $different[] = $this->label($row) . ': stream_tv ' . $row->stream_tv . ' aqui, ' . $tvName . ' no servidor'; } if (! $values) { if ($this->isEmpty($row->stream) && ! $isTv) { $missing[] = $this->label($row) . ': sem stream_port no servidor ' . $server; } continue; } $this->line(($apply ? 'Preenche ' : 'Preencheria ') . $this->label($row) . ' -> ' . json_encode($values, JSON_UNESCAPED_UNICODE)); if ($apply) { DB::table('site_server')->where('id', '=', $row->id)->update($values); } $filled++; } } $this->report('Sem correspondência', $missing); $this->report('Valor diferente do servidor (não alterado)', $different); $this->report('Servidores não consultados', $failed); $this->newLine(); if ($apply) { $this->info('Linhas alteradas: ' . $filled); } else { $this->info('Linhas a alterar: ' . $filled . '. Nada foi gravado, rode com --apply para gravar.'); } return $failed ? 1 : 0; } /** sites of one server, by id, read in chunks so a big server does not load at once. */ private function sitesOf(string $connection, array $ids): array { $sites = []; foreach (array_chunk(array_unique(array_map('intval', $ids)), self::CHUNK) as $part) { $found = DB::connection($connection) ->table('sites') ->select('id', 'stream_port', 'stream_tv', 'stream_tv_name') ->whereIn('id', $part) ->get(); foreach ($found as $site) { $sites[(int) $site->id] = $site; } } return $sites; } private function isEmpty($value): bool { return $value === null || trim((string) $value) === ''; } private function label($row): string { return 'site ' . $row->site_id . ' servidor ' . $row->server_id . ' (' . $row->domain . ')'; } private function report(string $title, array $lines): void { if (! $lines) { return; } $this->newLine(); $this->warn($title . ': ' . count($lines)); foreach (array_slice($lines, 0, 50) as $line) { $this->line(' ' . $line); } if (count($lines) > 50) { $this->line(' ... e mais ' . (count($lines) - 50) . '.'); } } }