Files
2026-04-28 21:15:09 +03:00

335 lines
11 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// PHP'nin maksimum çalışma süresini artır
set_time_limit(0); // Sınırsız çalışma süresi ayarla
ini_set('memory_limit', '512M'); // Bellek limitini artır
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Illuminate\Support\Facades\Artisan;
// .env dosyasından veritabanı bilgilerini alın
$user = env("DB_USERNAME");
$password = env("DB_PASSWORD");
$database = env("DB_DATABASE");
$delimiter = ";";
if(!getesit("delimiter", ""))
{
$delimiter = get("delimiter");
}
if(getesit("file_type", "xlsx"))
{
$delimiter = "\t";
}
// Eğer veritabanı bilgileri boş gelirse yapılandırma önbelleğini temizle
if (empty($user) || empty($password) || empty($database)) {
// Config cache'i temizle
Artisan::call('config:clear');
// Cache temizlendikten sonra tekrar env değerlerini al
$user = env("DB_USERNAME");
$password = env("DB_PASSWORD");
$database = env("DB_DATABASE");
}
$columns = "*";
// Bu alanlar Excel'de metin olarak kalmalı (ör: 1/1 gibi değerler için)
$forceStringFields = [
'quantity_of_iso',
'outer_diameter_1',
'outer_diameter_2',
'wall_thickness_1',
'wall_thickness_2',
'total_wdi',
'total_complated_wdi',
'total_shop_wdi',
'total_complated_shop_wdi',
'total_field_wdi',
'total_complated_field_wdi',
'remaining_wdi',
'fluid_code',
'diameter',
];
// Bu alanlar decimal değerlerini virgüllü formatta export etmeli
$forceVirgulFields = [
'nps_1',
'nps_2',
];
if(!getesit("columns", ""))
{
$columns = get("columns");
$columns = base64_decode($columns);
// Sütunları virgülle ayır
$columnsArray = explode(',', $columns);
// Sütun adlarını tırnak içine al
$columnsArray = array_map(function($column) {
$column = trim($column);
return "COALESCE(`" . $column . "`, '') $column"; // Sütun adlarını tırnak içine al
}, $columnsArray);
// Tırnak içine alınmış sütunları tekrar virgüllerle birleştir
$columns = implode(',', $columnsArray);
}
$tableName = get("table_name");
$moduleFileName = get("module");
// Apply employer view filters for weldlog-employer-view module
$whereClause = "";
if($moduleFileName === 'weldlog-employer-view' && $tableName === 'weld_logs') {
// Filter 1: Exclude records with repair_status = 'Repair' in repair_logs
$repairFilter = "NOT EXISTS (
SELECT 1 FROM repair_logs
WHERE repair_logs.iso_number = weld_logs.iso_number
AND repair_logs.new_joint_no = weld_logs.no_of_the_joint_as_per_as_built_survey
AND repair_logs.repair_status = 'Repair'
)";
// Filter 2: Only acceptable NDT results (Accept / Годен, empty, or NULL)
$ndtFields = [
'vt_result',
'rt_result',
'ut_result',
'pt_result',
'mt_result',
'pmi_result',
'ferrite_result',
'ht_result'
];
$ndtFilters = [];
foreach ($ndtFields as $field) {
$ndtFilters[] = "({$field} IN ('Accept / Годен', '') OR {$field} IS NULL)";
}
$ndtFilter = implode(' AND ', $ndtFilters);
$whereClause = " WHERE ({$repairFilter}) AND ({$ndtFilter})";
}
// Create standardized filename: "ProjectCode_ModuleName_Date_Time"
$projectNumber = setting('project_number') ?: 'QMS';
$currentDateTime = now();
$dateStr = $currentDateTime->format('d.m.Y');
$timeStr = $currentDateTime->format('H.i');
$fileName = $projectNumber . '_' . $moduleFileName . '_' . $dateStr . '_' . $timeStr;
// Kayıt yapılacak dosya yolu
$csvPath = storage_path($fileName . '.csv');
@unlink($csvPath);
// MySQL komutunu tanımlayın (sudo olmadan)
$query = "SELECT $columns FROM $tableName" . $whereClause;
// İsteğe bağlı olarak çok büyük veri setlerinde LIMIT eklemek isteyebilirsiniz
// Kullanıcı arayüzünden bir limit parametresi alabilir veya varsayılan bir limit belirleyebilirsiniz
$limit = get("limit", 0); // Varsayılan olarak 0 (tüm veriyi getirir)
if ($limit > 0) {
$query .= " LIMIT $limit";
}
$query .= ";";
// CSV dosyasını başlat
file_put_contents($csvPath, "\xEF\xBB\xBF"); // UTF-8 BOM
// Excel uyumluluğu için tüm alanları tırnak içine al
$excelCompatible = true;
// Doğrudan mysql komutunu çalıştırarak sonuçları CSV formatında alacağız
$mysqlCmd = "/usr/bin/mysql -u " . escapeshellarg($user) .
" -p" . escapeshellarg($password) .
" -D " . escapeshellarg($database) .
" --default-character-set=utf8mb4" .
" -B" . // Batch mode (tab-separated)
" -N" . // No column names
" -e " . escapeshellarg("SET NAMES utf8mb4; $query") .
" 2>/dev/null";
// mysql komutunu çalıştır ve sonuçları satır satır oku
$mysqlHandle = popen($mysqlCmd, 'r');
// Sütun adlarını ayarlamak için işlem yapalım
$csvHeaderColumns = [];
if(!getesit("columns", "")) {
// Özel sütun seçimi varsa, bu sütunların adlarını kullan
$headerColumnsArr = explode(',', base64_decode(get("columns")));
// Sütun adlarını temizle (COALESCE ifadelerini kaldır)
foreach($headerColumnsArr as $colName) {
$colName = trim($colName);
// COALESCE(`column`, '') column formatındaysa, sadece column kısmını al
if(preg_match('/^.*`([^`]+)`.*$/', $colName, $matches)) {
$csvHeaderColumns[] = $matches[1];
} else {
// Değilse doğrudan ismi kullan
$csvHeaderColumns[] = $colName;
}
}
} else {
// Tüm sütunları kullanıyorsa, veritabanından al
$tableInfoCmd = "/usr/bin/mysql -u " . escapeshellarg($user) .
" -p" . escapeshellarg($password) .
" -D " . escapeshellarg($database) .
" --default-character-set=utf8mb4" .
" -e " . escapeshellarg("SHOW COLUMNS FROM $tableName") .
" 2>/dev/null";
// Sütun adlarını al
exec($tableInfoCmd, $columnInfoOutput);
// İlk satırı atla (başlık satırı)
for ($i = 1; $i < count($columnInfoOutput); $i++) {
$parts = preg_split('/\s+/', trim($columnInfoOutput[$i]), 2);
if (!empty($parts[0])) {
$csvHeaderColumns[] = $parts[0];
}
}
}
// Sütun adlarını CSV dosyasına yaz
if (!empty($csvHeaderColumns)) {
// CSV formatında tırnak kullanarak başlık satırını oluştur
// fputcsv ile güvenli CSV header yazma (otomatik escaping)
$csvFile = fopen($csvPath, 'a');
fputcsv($csvFile, $csvHeaderColumns, $delimiter, '"');
fclose($csvFile);
}
// Verileri satır satır oku ve dosyaya yaz
while (($line = fgets($mysqlHandle)) !== false) {
// Satırın sonundaki satır sonu karakterini kaldır
$line = rtrim($line);
// Satırı tab karakterlerine göre böl
$fields = explode("\t", $line);
// Tarih formatlarını düzelt ve decimal alanları virgüllü yap
foreach ($fields as $i => &$field) {
// Eğer bu alan forceStringFields içindeyse, değeri ="değer" olarak yaz
if (isset($csvHeaderColumns[$i]) && in_array($csvHeaderColumns[$i], $forceStringFields)) {
$field = '="' . str_replace('"', '""', $field) . '"';
}
// Eğer bu alan forceVirgulFields içindeyse, decimal değerleri virgüllü yap
elseif (isset($csvHeaderColumns[$i]) && in_array($csvHeaderColumns[$i], $forceVirgulFields)) {
if (!empty($field) && is_numeric($field) && strpos($field, '.') !== false) {
$field = str_replace('.', ',', $field);
}
} else {
// Tarih formatını değiştir
$field = preg_replace_callback(
'/^(\d{4})-(\d{2})-(\d{2})$/',
function ($matches) {
return $matches[3] . '.' . $matches[2] . '.' . $matches[1]; // dd.mm.yyyy formatına
},
$field
);
}
}
$fields = str_replace("\\\\", "\\", $fields);
// fputcsv ile güvenli CSV yazma (otomatik escaping - sütun kaymasını önler)
$csvFile = fopen($csvPath, 'a');
fputcsv($csvFile, $fields, $delimiter, '"');
fclose($csvFile);
}
// mysql process'i kapat
pclose($mysqlHandle);
$fileType = "csv";
if(getesit("file_type", "xlsx"))
{
// XLSX dönüşümü öncesi belleği temizle
gc_collect_cycles();
try {
// LibreOffice ile CSV'den XLSX'e dönüştürme
$outputDir = storage_path();
$outputFilename = "$fileName.xlsx";
// LibreOffice için filtreleme seçenekleri:
// 9 = Tab karakteri ayırıcı olarak kullanıldığını belirt
// 0 = Metin sınırlayıcı karakteri kullanılmadığını belirt (veya ihtiyaca göre değiştirilebilir)
// 76 = Karakter seti (UTF-8)
// 1 = İlk satır başlık
$shellCmd = "libreoffice --headless --infilter=\"Text - txt - csv (StarCalc):9,0,76,1\" --convert-to xlsx --outdir " .
escapeshellarg($outputDir) . " " . escapeshellarg($csvPath) . " 2>&1";
// Komutu çalıştır
$output = [];
$returnCode = 0;
exec($shellCmd, $output, $returnCode);
// Hata kontrolü
if ($returnCode !== 0) {
throw new Exception("LibreOffice conversion failed: " . implode("\n", $output));
}
// LibreOffice dönüştürme işlemi tamamlandıktan sonra, dosyanın doğru adını bulalım
$csvBaseName = basename($csvPath);
$csvFileNameWithoutExt = pathinfo($csvBaseName, PATHINFO_FILENAME);
$expectedXlsxPath = $outputDir . '/' . $csvFileNameWithoutExt . '.xlsx';
// Eğer beklenen dosya yoksa, orijinal dosya adıyla tekrar deneyelim
if (!file_exists($expectedXlsxPath)) {
$expectedXlsxPath = $outputDir . '/' . $fileName . '.xlsx';
}
// Son dosya yolunu saklayalım
$xlsxOutputPath = $expectedXlsxPath;
$fileType = "xlsx";
} catch (Exception $e) {
// XLSX dönüşümü başarısız olursa, CSV dosyasını sunalım
$xlsxResult = ['error' => $e->getMessage()];
$fileType = "csv";
}
}
// CSV dosyasını kontrol et - çok büyükse bile LibreOffice ile dönüştürmeyi dene
$fileSize = filesize($csvPath);
$maxSize = 100 * 1024 * 1024; // 100MB - LibreOffice daha büyük dosyaları işleyebilir
// Çok büyük dosyalar için uyarı logla ama yine de dönüştürmeyi dene
if ($fileSize > $maxSize && $fileType == "xlsx") {
// Büyük dosya işleme durumunu loglayabilirsiniz
error_log("Warning: Processing large file ($fileName.csv) of size " . round($fileSize / (1024 * 1024), 2) . " MB");
}
if(isset($xlsxResult['error']))
{
// Hata durumunda CSV dosyasını sun
error_log("XLSX conversion error: " . $xlsxResult['error']);
yonlendir(url("storage/$fileName.csv"));
} else {
if ($fileType == "xlsx") {
// Dosya adından storage path kısmını çıkar, sadece relatif yolu ve dosya adını al
$relativePath = str_replace(storage_path(), '', $xlsxOutputPath);
// Başındaki slash'ı kaldır
$relativePath = ltrim($relativePath, '/');
yonlendir(url("storage/$relativePath"));
} else {
yonlendir(url("storage/$fileName.$fileType"));
}
}
// İşlem tamamlandıktan sonra belleği temizle
gc_collect_cycles();
// Geçici dosyaları temizle
if ($fileType == "xlsx" && file_exists($csvPath)) {
@unlink($csvPath); // XLSX oluşturulduysa CSV'yi silebiliriz
}
?>