ikinci temizlik tamamlandı
This commit is contained in:
@@ -0,0 +1,334 @@
|
||||
<?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
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user