getWithFilmography($id); if (!$cast) { return null; } $cast['adult_specifics'] = $this->getAdultSpecifics($id); return $cast; } public function getAdultSpecifics(?int $castId): array|false { $stmt = $this->pdo->prepare("SELECT * FROM adult_cast_specifics WHERE cast_id = ?"); $stmt->execute([$castId]); return $stmt->fetch(); } public function createWithAdultSpecifics(array $data): int { ApiLogger::getInstance()->logDebug("AdultCast createWithAdultSpecifics called with data: " . json_encode($data)); $name = $data['name'] ?? null; if (!$name) { throw new Exception('Name is required'); } // cleanname generieren $cleanname = generateCleanName($name); // Process photo field (base64 to file path) $data = $this->processPhotoField($data); // Zuerst Basis-Cast erstellen $castData = [ 'name' => $name, 'cleanname' => $cleanname, 'photo' => $data['photo'] ?? null, 'bio' => $data['bio'] ?? null, 'birthDate' => $data['birthDate'] ?? null, 'birthPlace' => $data['birthPlace'] ?? null ]; $castId = (int)$this->create($castData); ApiLogger::getInstance()->logDebug("AdultCast createWithAdultSpecifics: Base cast created with id: $castId"); // Occupations speichern if (isset($data['occupations']) && is_array($data['occupations'])) { ApiLogger::getInstance()->logDebug("AdultCast createWithAdultSpecifics: Saving occupations: " . json_encode($data['occupations'])); $this->saveRelatedItems('occupations', $castId, $data['occupations'], 'cast_id'); } // Adult-spezifische Daten speichern if (isset($data['adult_specifics']) && is_array($data['adult_specifics'])) { ApiLogger::getInstance()->logDebug("AdultCast createWithAdultSpecifics: Saving adult_specifics"); $this->saveAdultSpecifics($castId, $data['adult_specifics']); } else { ApiLogger::getInstance()->logDebug("AdultCast createWithAdultSpecifics: No adult_specifics found in data"); } return $castId; } public function updateWithAdultSpecifics(int $id, array $data): bool { ApiLogger::getInstance()->logDebug("AdultCast updateWithAdultSpecifics called with id: $id, data: " . json_encode($data)); // Set update flag for image replacement $this->isUpdate = true; $this->castId = $id; // Process photo field (base64 to file path) $data = $this->processPhotoField($data); // Basis-Cast aktualisieren $castData = []; foreach (['name', 'photo', 'bio', 'birthDate', 'birthPlace'] as $field) { if (array_key_exists($field, $data)) { $castData[$field] = $data[$field]; } } if (!empty($castData)) { ApiLogger::getInstance()->logDebug("AdultCast updateWithAdultSpecifics: Updating base cast data: " . json_encode($castData)); $this->update($id, $castData); } // Occupations aktualisieren if (isset($data['occupations']) && is_array($data['occupations'])) { ApiLogger::getInstance()->logDebug("AdultCast updateWithAdultSpecifics: Updating occupations: " . json_encode($data['occupations'])); $this->pdo->prepare("DELETE FROM occupations WHERE cast_id = ?")->execute([$id]); $this->saveRelatedItems('occupations', $id, $data['occupations'], 'cast_id'); } // Adult-spezifische Daten aktualisieren if (isset($data['adult_specifics']) && is_array($data['adult_specifics'])) { ApiLogger::getInstance()->logDebug("AdultCast updateWithAdultSpecifics: Saving adult_specifics"); ApiLogger::getInstance()->logDebug("AdultCast updateWithAdultSpecifics: adult_specifics data: " . json_encode($data['adult_specifics'])); $this->saveAdultSpecifics($id, $data['adult_specifics']); } else { ApiLogger::getInstance()->logDebug("AdultCast updateWithAdultSpecifics: No adult_specifics found in data"); } return true; } protected function saveAdultSpecifics(int $castId, array $specifics): void { ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics called for cast_id: $castId"); ApiLogger::getInstance()->logDebug("Specifics data: " . json_encode($specifics)); // Prüfen ob bereits Eintrag existiert $stmt = $this->pdo->prepare("SELECT * FROM adult_cast_specifics WHERE cast_id = ?"); $stmt->execute([$castId]); $existing = $stmt->fetch(); ApiLogger::getInstance()->logDebug("Existing entry: " . ($existing ? 'yes' : 'no')); $fields = ['bust_size', 'cup_size', 'waist_size', 'hip_size', 'height', 'weight', 'hair_color', 'eye_color', 'ethnicity', 'tattoos', 'piercings', 'measurements', 'shoe_size']; if ($existing) { // Update ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Existing entry found, doing UPDATE"); $updateFields = []; $params = []; foreach ($fields as $field) { if (array_key_exists($field, $specifics)) { $updateFields[] = "$field = ?"; $params[] = $specifics[$field]; ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Found field $field with value: " . json_encode($specifics[$field] ?? 'null')); } } ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Update fields: " . implode(', ', $updateFields)); ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Total update fields count: " . count($updateFields)); if (!empty($updateFields)) { $params[] = $castId; $query = "UPDATE adult_cast_specifics SET " . implode(', ', $updateFields) . " WHERE cast_id = ?"; ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Executing query: $query"); ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: With params: " . json_encode($params)); $stmt = $this->pdo->prepare($query); try { $stmt->execute($params); ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: UPDATE successful"); } catch (Exception $e) { // Fehler loggen ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics Error: " . $e->getMessage()); ApiLogger::getInstance()->logDebug("Query: $query"); ApiLogger::getInstance()->logDebug("Params: " . json_encode($params)); } } else { ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: No fields to update"); } } else { // Insert ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: No existing entry, doing INSERT"); $insertFields = []; $values = []; $params = []; $insertFields[] = 'cast_id'; $values[] = '?'; $params[] = $castId; foreach ($fields as $field) { if (array_key_exists($field, $specifics)) { $insertFields[] = $field; $values[] = '?'; $params[] = $specifics[$field]; ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Found field $field with value: " . json_encode($specifics[$field] ?? 'null')); } } ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Insert fields: " . implode(', ', $insertFields)); ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Total fields count: " . count($insertFields)); if (count($insertFields) > 1) { $query = "INSERT INTO adult_cast_specifics (" . implode(', ', $insertFields) . ") VALUES (" . implode(', ', $values) . ")"; ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Executing query: $query"); ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: With params: " . json_encode($params)); $stmt = $this->pdo->prepare($query); try { $stmt->execute($params); ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: INSERT successful"); } catch (Exception $e) { // Fehler loggen ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics Error: " . $e->getMessage()); ApiLogger::getInstance()->logDebug("Query: " . $query); ApiLogger::getInstance()->logDebug("Params: " . json_encode($params)); } } else { // Keine Felder zum Speichern ApiLogger::getInstance()->logDebug("AdultCast saveAdultSpecifics: Keine Felder zum Speichern für cast_id $castId"); } } } public function deleteAdultSpecifics(?int $castId): bool { $stmt = $this->pdo->prepare("DELETE FROM adult_cast_specifics WHERE cast_id = ?"); $stmt->execute([$castId]); return $stmt->rowCount() > 0; } public function searchAdultActors(array $filters = [], int $page = 1, int $limit = 2000000000): array { // Adult Actors mit Specifics suchen $query = " SELECT cs.*, acs.bust_size, acs.cup_size, acs.waist_size, acs.hip_size, acs.height, acs.weight, acs.hair_color, acs.eye_color, acs.ethnicity FROM cast_staff cs LEFT JOIN adult_cast_specifics acs ON cs.id = acs.cast_id WHERE acs.cast_id IS NOT NULL "; $params = []; if (isset($filters['search'])) { $query .= " AND cs.name LIKE ?"; $params[] = "%" . $filters['search'] . "%"; } if (isset($filters['ethnicity'])) { $query .= " AND acs.ethnicity = ?"; $params[] = $filters['ethnicity']; } if (isset($filters['hair_color'])) { $query .= " AND acs.hair_color = ?"; $params[] = $filters['hair_color']; } $query .= " ORDER BY cs.createdAt DESC"; $offset = ($page - 1) * $limit; $query .= " LIMIT " . (int)2000000000000 . " OFFSET " . (int)$offset; $stmt = $this->pdo->prepare($query); $stmt->execute($params); $items = $stmt->fetchAll(); ApiLogger::getInstance()->logDebug("AdultCast searchAdultActors: Found " . count($items) . " cast members"); foreach ($items as $item) { ApiLogger::getInstance()->logDebug("AdultCast searchAdultActors: Cast ID {$item['id']} - {$item['name']}"); } // Occupations und Filmography für jeden laden foreach ($items as &$item) { $item['occupations'] = $this->getRelatedItems('occupations', $item['id'], 'cast_id'); // Add filmography information $item['filmography'] = $this->getMediaForCast($item['id']); // Extract unique media types $mediaTypes = array_unique(array_column($item['filmography'], 'category')); $item['media_types'] = array_values($mediaTypes); ApiLogger::getInstance()->logDebug("AdultCast searchAdultActors: Cast ID {$item['id']} has " . count($item['filmography']) . " filmography items"); } // Total count $countQuery = " SELECT COUNT(*) FROM cast_staff cs INNER JOIN adult_cast_specifics acs ON cs.id = acs.cast_id WHERE 1=1 "; $countParams = []; if (isset($filters['search'])) { $countQuery .= " AND cs.name LIKE ?"; $countParams[] = "%" . $filters['search'] . "%"; } if (isset($filters['ethnicity'])) { $countQuery .= " AND acs.ethnicity = ?"; $countParams[] = $filters['ethnicity']; } if (isset($filters['hair_color'])) { $countQuery .= " AND acs.hair_color = ?"; $countParams[] = $filters['hair_color']; } $countStmt = $this->pdo->prepare($countQuery); $countStmt->execute($countParams); $total = $countStmt->fetchColumn(); return [ 'items' => $items, 'total' => $total, 'page' => $page, 'limit' => $limit ]; } }