$disk) { // Ensure $disk is an array if (!is_array($disk)) { $this->apiOutput(400, ['error' => "Disk entry is not an array"]); } $requiredFields = ['disk_name', 'disk_space', 'disk_used', 'disk_location']; foreach ($requiredFields as $field) { if (!array_key_exists($field, $disk)) { $this->apiOutput(400, ['error' => "Missing required field '$field' in disk information"]); } switch ($field) { case 'disk_used': case 'disk_space': $disks[$index][$field] = $this->validateSingleData($disk[$field], ['type' => 'float']); break; case 'disk_location': case 'disk_name': $disks[$index][$field] = $this->validateSingleData($disk[$field], ['type' => 'string']); break; } } } try { return json_encode($disks, JSON_THROW_ON_ERROR); } catch (JsonException $e) { $this->apiOutput(400, ['error' => "Failed to encode disk data to JSON: " . $e->getMessage()]); } } public function updateServer() { if (isset($this->data['company_uuid'])) { if (strlen($this->data['company_uuid']) == 0) { $this->data['company_uuid'] = NULL; } } $fields = [ 'company_uuid', 'server_vm_id', 'server_vm_host_id', 'server_vm_host_name', 'server_power_state', 'server_state', 'server_hostname', 'server_os', 'server_cpu', 'server_memory', 'server_memory_demand', 'server_disks', 'server_ipv4', 'server_ipv6', 'server_vm_generation', 'server_vm_snapshot', 'server_licenses', 'server_backup', 'server_description' ]; $insertFields = ['server_uuid']; $insertValues = ['UUID()']; $bindParams = []; foreach ($fields as $field) { if (array_key_exists($field, $this->data)) { $insertFields[] = $field; $insertValues[] = ":$field"; $bindParams[":$field"] = $this->data[$field]; // can be NULL } } # Always include server_create_timestamp and server_modified_timestamp $insertFields[] = 'server_create_timestamp'; $insertValues[] = ':server_create_timestamp'; $bindParams[':server_create_timestamp'] = time(); $insertFields[] = 'server_modified_timestamp'; $insertValues[] = ':server_modified_timestamp'; $bindParams[':server_modified_timestamp'] = time(); $query = "INSERT INTO servers (" . implode(',', $insertFields) . ") VALUES (" . implode(',', $insertValues) . ") ON DUPLICATE KEY UPDATE "; # Build the ON DUPLICATE KEY UPDATE, only foor fields that exist $updateParts = []; foreach ($insertFields as $field) { if (!in_array($field, ['server_create_timestamp', 'server_uuid'])) { $updateParts[] = "$field = VALUES($field)"; } } $query .= implode(", ", $updateParts); $stmt = $GLOBALS['pdo']->prepare($query); if (!$stmt->execute($bindParams)) { $this->apiOutput(400, ['error' => "Failed to insert server into database"]); } } private function validateLicenseData($server_vm_id, $server_licenses) { $server_vm_id = $this->validateSingleData($server_vm_id, ['type' => 'string']); $server_licenses_posted = $this->validateSingleData($server_licenses, ['type' => 'array']); $query = "SELECT server_licenses FROM servers WHERE server_vm_id = ?"; $stmt = $this->prepareStatement($query); $stmt->bind_param("s", $server_vm_id); $this->executeStatement($stmt); $result = $stmt->get_result(); $server_licenses_db = $result->fetch_assoc(); $server_licenses_db = $server_licenses_db['server_licenses'] ?? null; $server_licenses_db_new = []; if (!empty($server_licenses_db)) { $decoded = json_decode($server_licenses_db, true); if (is_array($decoded)) { foreach ($decoded as $item) { foreach ($item as $key => $value) { $server_licenses_db_new[$key] = $value; } } } } foreach ($server_licenses_posted as $item) { foreach ($item as $rawKey => $value) { $prefix = substr($rawKey, 0, 1); $license = substr($rawKey, 1); if ($prefix === '+') { $server_licenses_db_new[$license] = $value; } if ($prefix === '-') { unset($server_licenses_db_new[$license]); } } } $server_licenses_db_new_final = []; foreach ($server_licenses_db_new as $key => $value) { $server_licenses_db_new_final[] = [$key => $value]; } return empty($server_licenses_db_new_final) ? '[]' : json_encode($server_licenses_db_new_final); } private function validateBackupData($server_vm_id, $server_backup) { $server_vm_id = $this->validateSingleData($server_vm_id, ['type' => 'string']); $server_backup_posted = $this->validateSingleData($server_backup, ['type' => 'array']); $query = "SELECT server_backup FROM servers WHERE server_vm_id = ?"; $stmt = $this->prepareStatement($query); $stmt->bind_param("s", $server_vm_id); $this->executeStatement($stmt); $result = $stmt->get_result(); $server_backup_db = $result->fetch_assoc(); $server_backup_db = $server_backup_db['server_backup'] ?? null; $server_backup_db_new = []; if (!empty($server_backup_db)) { $decoded = json_decode($server_backup_db, true); if (is_array($decoded)) { foreach ($decoded as $item) { foreach ($item as $key => $value) { $server_backup_db_new[$key] = $value; } } } } foreach ($server_backup_posted as $item) { foreach ($item as $rawKey => $value) { $prefix = substr($rawKey, 0, 1); $backup = substr($rawKey, 1); if ($prefix === '+') { $server_backup_db_new[$backup] = $value; } if ($prefix === '-') { unset($server_backup_db_new[$backup]); } } } $server_backup_db_new_final = []; foreach ($server_backup_db_new as $key => $value) { $server_backup_db_new_final[] = [$key => $value]; } return empty($server_backup_db_new_final) ? '[]' : json_encode($server_backup_db_new_final); } public function processServerData($server, $requiredFields, $optionalFields) { // since the disk data is sent as an array we need to check it seperatly from the other data validations if (!empty($server['server_disks']) && is_array($server['server_disks'])) { $server['server_disks'] = $this->validateDiskData($server['server_disks']); } else { unset($server['server_disks']); } if (!empty($server['server_licenses']) && is_array($server['server_licenses'])) { $server['server_licenses'] = $this->validateLicenseData($server['server_vm_id'], $server['server_licenses']); } else { unset($server['server_licenses']); } if (!empty($server['server_backup']) && is_array($server['server_backup'])) { $server['server_backup'] = $this->validateBackupData($server['server_vm_id'], $server['server_backup']); } else { unset($server['server_backup']); } foreach (['server_ipv4', 'server_ipv6'] as $key) { if (!empty($server[$key]) && is_array($server[$key])) { $server[$key] = json_encode($server[$key]); } else { unset($server[$key]); } } $this->postedData = $server; $this->validateData($requiredFields, $optionalFields); $this->updateServer(); } public function deleteServer() { $query = "DELETE FROM servers WHERE server_uuid = ?"; $stmt = $this->prepareStatement($query); $stmt->bind_param('s', $this->data['server_uuid']); $this->executeStatement($stmt); $stmt->close(); $this->apiOutput(200, ['success' => 'Server removed']); } }