<?php
 namespace App\Core\Product; use App\Models\ClientProduct; use Illuminate\Support\Facades\Log; class ModuleParamsBuilder { public static function build(ClientProduct $cp, array $extras = []): array { $cp->loadMissing([ 'client.country', 'product', 'server', 'configOptionValues.option', 'configOptionValues.selectedValue', 'configFieldValues.customField', ]); $client = $cp->client; $product = $cp->product; $server = $cp->server; $currentPassword = self::safeDecrypt($cp->password); $moduleConfig = $product && $product->module ? $product->getModuleConfigArray($product->module) : []; $package = self::resolvePackage($moduleConfig); $params = [ 'service_id' => $cp->id, 'client_product_id' => $cp->id, 'status' => $cp->status, 'domain' => $cp->domain, 'username' => $cp->username, 'password' => $currentPassword, 'account_id' => $cp->module_handler_id, 'module_handler_id' => $cp->module_handler_id, 'module_data' => is_array($cp->module_data) ? $cp->module_data : [], 'vm_id' => (is_array($cp->module_data) ? ($cp->module_data['vm_id'] ?? null) : null) ?? $cp->module_handler_id, 'billing_cycle' => $cp->billingcycle, 'quantity' => $cp->quantity, 'dedicated_ip' => $cp->dedicated_ip, 'notes' => $cp->notes, 'create_date' => optional($cp->create_date)?->format('Y-m-d'), 'next_due_date' => optional($cp->next_due_date)?->format('Y-m-d'), 'expire_date' => optional($cp->expire_date)?->format('Y-m-d'), 'activation_date' => optional($cp->activation_date)?->format('Y-m-d H:i:s'), 'suspend_date' => optional($cp->suspend_date)?->format('Y-m-d H:i:s'), 'email' => $client?->email, 'first_name' => $client?->first_name, 'last_name' => $client?->last_name, 'client_id' => $client?->id, 'client_email' => $client?->email, 'client_first_name' => $client?->first_name, 'client_last_name' => $client?->last_name, 'client_company' => $client?->company_name, 'client_phone' => $client?->phone, 'client_address1' => $client?->address1, 'client_address2' => $client?->address2, 'client_city' => $client?->city_id, 'client_state' => $client?->state, 'client_postcode' => $client?->postcode, 'client_country_id' => $client?->country_id, 'client_country_code' => $client?->country?->a2_iso, 'client_language_id' => $client?->language_id, 'client_currency_id' => $client?->currency_id, 'client_group_id' => $client?->group_id, 'product_id' => $product?->id, 'product_name' => $product?->name, 'product_type' => $product?->type, 'product_module' => $product?->module, 'product_slug' => $product?->slug, 'product_group_id' => $product?->group_id, 'server_id' => $cp->server_id, 'server' => $server ? [ 'id' => $server->id, 'name' => $server->name, 'hostname' => $server->hostname, 'ip_address' => $server->ip_address, 'port' => $server->port, 'module' => $server->module, 'username' => $server->username, 'password' => self::safeDecrypt($server->password), 'status' => $server->status, 'maximum_hosts' => $server->maximum_hosts, 'current_hosts' => $server->current_hosts, ] : null, 'custom_fields' => $cp->configFieldValues ->map(fn ($cfv) => [ 'field_id' => $cfv->option_id, 'field_name' => $cfv->customField?->label ?? $cfv->customField?->name, 'value' => $cfv->value, ]) ->values() ->toArray(), 'config_options' => $cp->configOptionValues ->map(fn ($cov) => [ 'option_id' => $cov->option_id, 'option_name' => $cov->option?->name, 'value_id' => $cov->value, 'value_name' => $cov->selectedValue?->value, 'group_id' => $cov->group_id, ]) ->values() ->toArray(), 'module_config' => $moduleConfig, ]; if ($package !== '') { $params['package'] = $package; $params['plan'] = $package; } return array_merge($params, $extras); } private static function resolvePackage(array $moduleConfig): string { $keys = ['package', 'plan', 'package_name', 'plan_name', 'default_package', 'default_plan', 'whm_package_name']; foreach ($keys as $key) { if (isset($moduleConfig[$key]) && is_scalar($moduleConfig[$key]) && trim((string) $moduleConfig[$key]) !== '') { return trim((string) $moduleConfig[$key]); } } return ''; } private static function safeDecrypt(?string $value): ?string { if (empty($value)) { return null; } try { return decrypt($value); } catch (\Throwable $e) { return $value; } } } 