"; } logMsg("CRON SCRIPT START"); logMsg("BASE_DIR: " . __DIR__); logMsg("TASK DIR: " . $taskDir); logMsg("DOWNLOAD DIR: " . $downloadDir); if (!is_dir($downloadDir)) { logMsg("Download directory does not exist. Creating..."); mkdir($downloadDir, 0755, true); } function doRequest($data, $filename, $username, $password) { logMsg("Starting API request"); logMsg("CSV target: " . $filename); $response = sendAPICompanySearchRequest($username, $password, $data); $responseObject = json_decode($response, true); if (!is_array($responseObject)) { logMsg("ERROR: API response is not valid JSON"); logMsg("Raw response: " . htmlspecialchars($response)); return ['status' => 'error', 'writtenRows' => 0]; } if (array_key_exists("error", $responseObject)) { $errorCode = $responseObject['error']['code'] ?? ''; if ($errorCode === 'API.ZFR.SEARCH.NORESULT') { logMsg("API returned no results. Treating as empty search result."); return ['status' => 'empty', 'writtenRows' => 0]; } logMsg("ERROR: API returned error"); logMsg("API error response: " . htmlspecialchars(json_encode($responseObject))); return ['status' => 'error', 'writtenRows' => 0]; } if (!isset($responseObject['list']) || !is_array($responseObject['list'])) { logMsg("ERROR: API response has no valid list"); logMsg("API response: " . htmlspecialchars(json_encode($responseObject))); return ['status' => 'error', 'writtenRows' => 0]; } $companies = $responseObject['list']; logMsg("Companies found in this request: " . count($companies)); if (count($companies) === 0) { logMsg("No companies found in this request."); return ['status' => 'empty', 'writtenRows' => 0]; } $isNewFile = !file_exists($filename); $file = fopen($filename, $isNewFile ? 'w' : 'a'); if (!$file) { logMsg("ERROR: Could not open CSV file for writing"); return ['status' => 'error', 'writtenRows' => 0]; } if ($isNewFile) { logMsg("Creating new CSV file with header"); fputcsv($file, [ 'name', 'careOf', 'street', 'houseNumber', 'swissZipCode', 'city', 'uid', 'legalSeat', 'legalForm', 'status', 'sogcDate', 'deletionDate' ], ',', '"', "\\"); } else { logMsg("Appending to existing CSV file"); } $writtenRows = 0; foreach ($companies as $company) { if (!isset($company['uid'])) { logMsg("WARNING: Company entry without UID skipped"); continue; } $companyInfoResponse = sendAPICompanyInfoRequest($username, $password, $company['uid']); $companyInfo = json_decode($companyInfoResponse, true); if (!isset($companyInfo[0]) || !is_array($companyInfo[0])) { logMsg("WARNING: Could not load company info for UID: " . $company['uid']); logMsg("Company info response: " . htmlspecialchars($companyInfoResponse)); continue; } $companyFullData = $companyInfo[0]; fputcsv($file, [ $companyFullData['name'] ?? '', $companyFullData['address']['careOf'] ?? '', $companyFullData['address']['street'] ?? '', $companyFullData['address']['houseNumber'] ?? '', $companyFullData['address']['swissZipCode'] ?? '', $companyFullData['address']['city'] ?? '', $companyFullData['uid'] ?? '', $companyFullData['legalSeat'] ?? '', $companyFullData['legalForm']['name']['de'] ?? '', $companyFullData['status'] ?? '', $companyFullData['sogcDate'] ?? '', $companyFullData['deletionDate'] ?? '' ], ',', '"', "\\"); $writtenRows++; } fclose($file); logMsg("Rows written to CSV in this request: " . $writtenRows); logMsg("CSV exists after writing: " . (file_exists($filename) ? "YES" : "NO")); logMsg("CSV size after writing: " . (file_exists($filename) ? filesize($filename) : 0) . " bytes"); if ($writtenRows === 0) { logMsg("ERROR: Search returned companies, but no rows could be written."); return ['status' => 'error', 'writtenRows' => 0]; } if (!empty($responseObject['hasMoreResults'])) { $nextOffset = ($responseObject['maxOffset'] ?? 0) + 50; logMsg("More results available. Next offset: " . $nextOffset); return [ 'status' => 'more', 'nextOffset' => $nextOffset, 'writtenRows' => $writtenRows ]; } logMsg("No more results. Request completed."); return [ 'status' => 'done', 'writtenRows' => $writtenRows ]; } while ($latesEndTime - time() > 30) { if (!is_dir($taskDir)) { logMsg("Task directory does not exist"); break; } $taskfiles = scandir($taskDir); $taskfiles = array_diff($taskfiles, ['.', '..']); $taskfiles = array_filter($taskfiles, function ($taskfile) use ($taskDir) { return is_file($taskDir . '/' . $taskfile) && pathinfo($taskfile, PATHINFO_EXTENSION) === 'json'; }); sort($taskfiles); logMsg("Task files found: " . count($taskfiles)); if (count($taskfiles) === 0) { logMsg("Nothing to do. Sleeping 10 seconds."); sleep(10); continue; } $taskFileName = $taskfiles[0]; $taskFilePath = $taskDir . '/' . $taskFileName; if (intval(explode("-", $taskFileName)[0]) + $minTaskOldness >= time()) { logMsg("Task is too new. Waiting."); sleep(10); continue; } logMsg("Processing task: " . $taskFileName); $taskString = file_get_contents($taskFilePath); $task = json_decode($taskString, true); if (!is_array($task)) { logMsg("ERROR: Task file is not valid JSON. Deleting task."); unlink($taskFilePath); continue; } if (!isset($task['email']) || empty($task['email'])) { logMsg("ERROR: Task has no email. Deleting task."); unlink($taskFilePath); continue; } if (!isset($task['requests']) || !is_array($task['requests'])) { logMsg("ERROR: Task has no valid requests array. Deleting task."); unlink($taskFilePath); continue; } if (!isset($task['stats']) || !is_array($task['stats'])) { $task['stats'] = [ 'totalWrittenRows' => 0, 'emptyRequests' => 0, 'completedRequests' => 0, 'failedRequests' => 0 ]; } $csvFile = str_replace(".json", ".csv", $downloadDir . '/' . $taskFileName); $csvUrl = $downloadUrlBase . '/' . basename($csvFile); if (count($task['requests']) > 0) { $result = doRequest($task['requests'][0], $csvFile, $username, $password); if (isset($result['writtenRows'])) { $task['stats']['totalWrittenRows'] += $result['writtenRows']; } if ($result['status'] === 'more') { $task['requests'][0]['offset'] = $result['nextOffset']; logMsg("Request updated with next offset"); } elseif ($result['status'] === 'done') { $task['stats']['completedRequests']++; array_shift($task['requests']); logMsg("Request completed and removed from task"); } elseif ($result['status'] === 'empty') { $task['stats']['emptyRequests']++; $task['stats']['completedRequests']++; array_shift($task['requests']); logMsg("Request had no results and was removed from task"); } else { $task['stats']['failedRequests']++; file_put_contents($taskFilePath, json_encode($task)); logMsg("ERROR: Request failed. Task will NOT be deleted and email will NOT be sent."); break; } file_put_contents($taskFilePath, json_encode($task)); logMsg("Task file updated."); logMsg("Total written rows so far: " . $task['stats']['totalWrittenRows']); logMsg("Empty requests so far: " . $task['stats']['emptyRequests']); logMsg("Completed requests so far: " . $task['stats']['completedRequests']); continue; } logMsg("All requests completed. Preparing email."); logMsg("Total written rows: " . ($task['stats']['totalWrittenRows'] ?? 0)); logMsg("Empty requests: " . ($task['stats']['emptyRequests'] ?? 0)); logMsg("Completed requests: " . ($task['stats']['completedRequests'] ?? 0)); logMsg("Failed requests: " . ($task['stats']['failedRequests'] ?? 0)); logMsg("Final CSV path: " . $csvFile); logMsg("Final CSV URL: " . $csvUrl); logMsg("CSV exists before email: " . (file_exists($csvFile) ? "YES" : "NO")); logMsg("CSV size before email: " . (file_exists($csvFile) ? filesize($csvFile) : 0) . " bytes"); $totalWrittenRows = $task['stats']['totalWrittenRows'] ?? 0; if ($totalWrittenRows === 0) { logMsg("All requests completed but no rows were exported. Sending no-results email."); sendEmail( $task['email'], "Ihre Suche hat leider keine Ergebnisse geliefert, die exportiert werden konnten.", $smtppassword ); unlink($taskFilePath); logMsg("Task file deleted after no-results email."); continue; } if (!file_exists($csvFile) || filesize($csvFile) === 0) { logMsg("ERROR: CSV file missing or empty, although rows were counted. Email will NOT be sent."); break; } logMsg("CSV exists and contains exported rows. Sending email with download link."); sendEmail( $task['email'], $csvUrl, $smtppassword ); unlink($taskFilePath); logMsg("Task file deleted after successful email."); } logMsg("CRON SCRIPT END"); ?>