diff --git a/plugins/tasks/Extractor.php b/plugins/tasks/Extractor.php index 1ad125ed5bfe514198182a28be13b2ad817882d4..1faaa337eac2f295ce667c7a0a0ceb6b73fe4518 100644 --- a/plugins/tasks/Extractor.php +++ b/plugins/tasks/Extractor.php @@ -79,8 +79,8 @@ class Extractor implements EndpointInterface // Get main task CN for filename $mainTaskCn = $this->getMainTaskCn($task['fdtasksgranularmaster'][0]); - // Determine filename with main task name and date with hours - $date = date('Y-m-d_H-i-s'); + // Determine filename with main task name and date with hour (no minutes or seconds) + $date = date('Y-m-d_H'); // Using only year-month-day_hour format $filename = isset($data['filename']) ? $path . $data['filename'] . '_' . $date . '.' . $format : $path . $mainTaskCn . '_' . $date . '.' . $format; @@ -183,47 +183,99 @@ class Extractor implements EndpointInterface * @param string $filename * @return bool * @throws Exception - * Note: Export user attributes to CSV. + * Note: Export user attributes to CSV, preventing duplicate UIDs and handling new attributes. */ private function exportToCsv(array $userAttributes, string $filename): bool { - $fileExists = file_exists($filename); - $handle = fopen($filename, 'a'); - - if ($handle === false) { - throw new Exception("Could not open file: $filename"); + if (empty($userAttributes)) { + return true; // No attributes to write } - try { - if (empty($userAttributes)) { - return true; // No attributes to write + $user = $userAttributes[0]; + $userData = []; + $allColumns = []; + $existingData = []; + $uidKey = 'uid'; // The attribute to check for duplicates + $newUserUid = ''; + + // Extract UID and prepare user data + foreach ($user as $attribute => $values) { + if (is_array($values)) { + foreach ($values as $key => $value) { + if (is_numeric($key)) { + $userData[$attribute] = $value; + $allColumns[$attribute] = true; // Use as associative array to avoid duplicates + + if (strtolower($attribute) === $uidKey) { + $newUserUid = $value; + } + + break; // Only take the first value for simplicity + } + } } - - $user = $userAttributes[0]; - $columns = []; - $data = []; - - // Prepare columns and data - foreach ($user as $attribute => $values) { - if (is_array($values)) { - foreach ($values as $key => $value) { - if (is_numeric($key)) { - $columns[] = $attribute; - $data[] = $value; - break; // Only take the first value for simplicity + } + + // If no UID found, generate a random one + if (empty($newUserUid)) { + $newUserUid = 'user_' . uniqid(); + $userData[$uidKey] = $newUserUid; + $allColumns[$uidKey] = true; + } + + // Read existing file if it exists + if (file_exists($filename)) { + $handle = fopen($filename, 'r'); + if ($handle !== false) { + // Read headers + $headers = fgetcsv($handle); + if ($headers !== false) { + // Add existing headers to all columns + foreach ($headers as $header) { + $allColumns[$header] = true; + } + + // Read existing data + while (($row = fgetcsv($handle)) !== false) { + $rowData = []; + foreach ($headers as $index => $header) { + $rowData[$header] = $row[$index] ?? ''; + } + // Only add to existing data if it's not the same UID as new user + if (isset($rowData[$uidKey]) && $rowData[$uidKey] !== $newUserUid) { + $existingData[] = $rowData; } } } + fclose($handle); } + } + + // Convert all columns associative array to indexed array + $finalColumns = array_keys($allColumns); + + // Add new user data to existing data + $existingData[] = $userData; + + // Write to file + $handle = fopen($filename, 'w'); // 'w' to overwrite with complete data + if ($handle === false) { + throw new Exception("Could not open file: $filename"); + } + + try { + // Write headers + fputcsv($handle, $finalColumns); - // Write header if file is new - if (!$fileExists) { - fputcsv($handle, $columns); + // Write data rows + foreach ($existingData as $row) { + $outputRow = []; + foreach ($finalColumns as $column) { + $outputRow[] = $row[$column] ?? ''; // Use empty string if attribute not found + } + fputcsv($handle, $outputRow); } - // Write data - fputcsv($handle, $data); - return true; } finally { fclose($handle); @@ -234,17 +286,31 @@ class Extractor implements EndpointInterface * @param array $userAttributes * @param string $filename * @return bool - * Note: Export user attributes to JSON. + * Note: Export user attributes to JSON with duplicate UID handling. */ private function exportToJson(array $userAttributes, string $filename): bool { $existingData = []; + $uidKey = 'uid'; + $newUserUid = ''; + + // Get UID of new user + if (!empty($userAttributes[0][$uidKey][0])) { + $newUserUid = $userAttributes[0][$uidKey][0]; + } // Read existing data if file exists if (file_exists($filename)) { $existingJson = file_get_contents($filename); if (!empty($existingJson)) { - $existingData = json_decode($existingJson, true) ?? []; + $jsonData = json_decode($existingJson, true) ?? []; + + // Filter out any entries with the same UID + foreach ($jsonData as $entry) { + if (!isset($entry[$uidKey][0]) || $entry[$uidKey][0] !== $newUserUid) { + $existingData[] = $entry; + } + } } } @@ -259,17 +325,35 @@ class Extractor implements EndpointInterface * @param array $userAttributes * @param string $filename * @return bool - * Note: Export user attributes to XML. + * Note: Export user attributes to XML with duplicate UID handling. */ private function exportToXml(array $userAttributes, string $filename): bool { $dom = new DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = true; + $uidKey = 'uid'; + $newUserUid = ''; - // Create root element if file doesn't exist + // Get UID of new user + if (!empty($userAttributes[0][$uidKey][0])) { + $newUserUid = $userAttributes[0][$uidKey][0]; + } + + // Create or load XML document if (file_exists($filename)) { $dom->load($filename); $root = $dom->documentElement; + + // Remove any existing user with the same UID + if (!empty($newUserUid)) { + $xpath = new DOMXPath($dom); + $users = $xpath->query("/users/user[{$uidKey}='{$newUserUid}']"); + if ($users->length > 0) { + foreach ($users as $user) { + $root->removeChild($user); + } + } + } } else { $root = $dom->createElement('users'); $dom->appendChild($root);