Kaikki viittaukset "Noxus Intra" vaihdettu muotoon "Noxus HUB" koko koodikannassa. Footer ja login-sivu näyttävät nyt "Noxus HUB © Empor Oy 2026". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
227 lines
8.3 KiB
PHP
227 lines
8.3 KiB
PHP
<?php
|
|
/**
|
|
* Noxus HUB — JSON → MySQL migraatioskripti
|
|
*
|
|
* Aja kerran: php migrate.php
|
|
* Lukee kaikki data/*.json -tiedostot ja siirtää ne MySQL-tietokantaan.
|
|
*/
|
|
|
|
// Näytä kaikki virheet
|
|
ini_set('display_errors', '1');
|
|
ini_set('display_startup_errors', '1');
|
|
error_reporting(E_ALL);
|
|
|
|
require_once __DIR__ . '/db.php';
|
|
|
|
echo "=== Noxus HUB: JSON → MySQL migraatio ===\n\n";
|
|
|
|
// Reset-tila: ?reset=1 tyhjentää taulut ensin
|
|
if (isset($_GET['reset']) || (isset($argv[1]) && $argv[1] === '--reset')) {
|
|
echo "0. RESET: Poistetaan vanhat taulut...\n";
|
|
$db = getDb();
|
|
$db->query("SET FOREIGN_KEY_CHECKS = 0");
|
|
$tables = ['files','ticket_rules','mailboxes','changelog','archives','ticket_tags',
|
|
'ticket_messages','tickets','leads','customer_connections','customers',
|
|
'login_attempts','reset_tokens','config','user_signatures','user_companies','users','company_domains','companies'];
|
|
foreach ($tables as $t) {
|
|
$db->query("DROP TABLE IF EXISTS `$t`");
|
|
}
|
|
$db->query("SET FOREIGN_KEY_CHECKS = 1");
|
|
echo " ✓ Taulut poistettu\n\n";
|
|
}
|
|
|
|
// 1. Luo taulut
|
|
echo "1. Luodaan tietokantarakenne...\n";
|
|
try {
|
|
initDatabase();
|
|
} catch (Throwable $e) {
|
|
echo "VIRHE taulujen luonnissa: " . $e->getMessage() . "\n";
|
|
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
|
exit(1);
|
|
}
|
|
echo " ✓ Taulut luotu\n\n";
|
|
|
|
$dataDir = __DIR__ . '/data';
|
|
|
|
// 2. Yritykset
|
|
echo "2. Siirretään yritykset...\n";
|
|
$companiesFile = $dataDir . '/companies.json';
|
|
$companies = file_exists($companiesFile) ? json_decode(file_get_contents($companiesFile), true) : [];
|
|
$companyCount = 0;
|
|
foreach ($companies as $c) {
|
|
dbSaveCompany($c);
|
|
$companyCount++;
|
|
echo " ✓ {$c['nimi']} (id: {$c['id']})\n";
|
|
}
|
|
echo " Yhteensä: $companyCount yritystä\n\n";
|
|
|
|
// 3. Käyttäjät
|
|
echo "3. Siirretään käyttäjät...\n";
|
|
$usersFile = $dataDir . '/users.json';
|
|
$users = file_exists($usersFile) ? json_decode(file_get_contents($usersFile), true) : [];
|
|
$userCount = 0;
|
|
foreach ($users as $u) {
|
|
dbSaveUser($u);
|
|
$userCount++;
|
|
echo " ✓ {$u['username']} ({$u['role']})\n";
|
|
}
|
|
echo " Yhteensä: $userCount käyttäjää\n\n";
|
|
|
|
// 4. Globaalit asetukset
|
|
echo "4. Siirretään globaalit asetukset...\n";
|
|
$configFile = $dataDir . '/config.json';
|
|
if (file_exists($configFile)) {
|
|
$config = json_decode(file_get_contents($configFile), true) ?: [];
|
|
dbSaveConfig($config);
|
|
echo " ✓ config.json siirretty\n";
|
|
}
|
|
echo "\n";
|
|
|
|
// 5. Salasanan palautustokenit
|
|
echo "5. Siirretään reset-tokenit...\n";
|
|
$tokensFile = $dataDir . '/reset_tokens.json';
|
|
if (file_exists($tokensFile)) {
|
|
$tokens = json_decode(file_get_contents($tokensFile), true) ?: [];
|
|
$db = getDb();
|
|
foreach ($tokens as $t) {
|
|
try {
|
|
$stmt = $db->prepare("INSERT IGNORE INTO reset_tokens (user_id, token, created_at) VALUES (?, ?, ?)");
|
|
$expires = $t['expires'] ?? time();
|
|
$created = date('Y-m-d H:i:s', $expires - 3600); // Arvio luontiajasta
|
|
$stmt->execute([$t['user_id'], $t['token'], $created]);
|
|
} catch (Exception $e) {
|
|
echo " ⚠ Token ohitettu: " . $e->getMessage() . "\n";
|
|
}
|
|
}
|
|
echo " ✓ " . count($tokens) . " tokenia\n";
|
|
}
|
|
echo "\n";
|
|
|
|
// 6. Yrityskohtainen data
|
|
echo "6. Siirretään yrityskohtainen data...\n";
|
|
$companiesDir = $dataDir . '/companies';
|
|
if (is_dir($companiesDir)) {
|
|
$dirs = array_filter(scandir($companiesDir), fn($d) => $d !== '.' && $d !== '..' && is_dir("$companiesDir/$d"));
|
|
|
|
foreach ($dirs as $companyId) {
|
|
$compDir = "$companiesDir/$companyId";
|
|
echo "\n === $companyId ===\n";
|
|
|
|
// Yrityksen config (postilaatikot, tikettisäännöt, api_key, cors_origins)
|
|
$compConfig = "$compDir/config.json";
|
|
if (file_exists($compConfig)) {
|
|
$cfg = json_decode(file_get_contents($compConfig), true) ?: [];
|
|
|
|
// Postilaatikot
|
|
$mailboxes = $cfg['mailboxes'] ?? [];
|
|
foreach ($mailboxes as $mb) {
|
|
dbSaveMailbox($companyId, $mb);
|
|
}
|
|
echo " ✓ " . count($mailboxes) . " postilaatikkoa\n";
|
|
|
|
// Tikettisäännöt
|
|
$rules = $cfg['ticket_rules'] ?? [];
|
|
foreach ($rules as $rule) {
|
|
dbSaveTicketRule($companyId, $rule);
|
|
}
|
|
echo " ✓ " . count($rules) . " tikettisääntöä\n";
|
|
|
|
// API-avain ja CORS
|
|
if (!empty($cfg['api_key'])) {
|
|
dbSetCompanyApiKey($companyId, $cfg['api_key']);
|
|
echo " ✓ API-avain\n";
|
|
}
|
|
if (!empty($cfg['cors_origins'])) {
|
|
dbSetCompanyCorsOrigins($companyId, $cfg['cors_origins']);
|
|
echo " ✓ CORS-asetukset\n";
|
|
}
|
|
}
|
|
|
|
// Asiakkaat
|
|
$custFile = "$compDir/customers.json";
|
|
if (file_exists($custFile)) {
|
|
$customers = json_decode(file_get_contents($custFile), true) ?: [];
|
|
foreach ($customers as $cust) {
|
|
// Migroi vanhat flat-kentät liittymiksi jos tarpeen
|
|
if (!isset($cust['liittymat'])) {
|
|
$cust['liittymat'] = [];
|
|
if (!empty($cust['asennusosoite'] ?? '') || !empty($cust['liittymanopeus'] ?? '')) {
|
|
$cust['liittymat'][] = [
|
|
'asennusosoite' => $cust['asennusosoite'] ?? '',
|
|
'postinumero' => $cust['postinumero'] ?? '',
|
|
'kaupunki' => $cust['kaupunki'] ?? '',
|
|
'liittymanopeus' => $cust['liittymanopeus'] ?? '',
|
|
'hinta' => $cust['hinta'] ?? 0,
|
|
'sopimuskausi' => $cust['sopimuskausi'] ?? '',
|
|
'alkupvm' => $cust['alkupvm'] ?? '',
|
|
];
|
|
}
|
|
}
|
|
dbSaveCustomer($companyId, $cust);
|
|
}
|
|
echo " ✓ " . count($customers) . " asiakasta\n";
|
|
}
|
|
|
|
// Liidit
|
|
$leadsFile = "$compDir/leads.json";
|
|
if (file_exists($leadsFile)) {
|
|
$leads = json_decode(file_get_contents($leadsFile), true) ?: [];
|
|
foreach ($leads as $lead) {
|
|
dbSaveLead($companyId, $lead);
|
|
}
|
|
echo " ✓ " . count($leads) . " liidiä\n";
|
|
}
|
|
|
|
// Tiketit
|
|
$ticketsFile = "$compDir/tickets.json";
|
|
if (file_exists($ticketsFile)) {
|
|
$tickets = json_decode(file_get_contents($ticketsFile), true) ?: [];
|
|
foreach ($tickets as $ticket) {
|
|
dbSaveTicket($companyId, $ticket);
|
|
}
|
|
echo " ✓ " . count($tickets) . " tikettiä\n";
|
|
}
|
|
|
|
// Arkisto
|
|
$archiveFile = "$compDir/archive.json";
|
|
if (file_exists($archiveFile)) {
|
|
$archives = json_decode(file_get_contents($archiveFile), true) ?: [];
|
|
foreach ($archives as $arc) {
|
|
if (!empty($arc['id'])) {
|
|
dbArchiveCustomer($companyId, $arc);
|
|
}
|
|
}
|
|
echo " ✓ " . count($archives) . " arkistoitua\n";
|
|
}
|
|
|
|
// Changelog
|
|
$logFile = "$compDir/changelog.json";
|
|
if (file_exists($logFile)) {
|
|
$logs = json_decode(file_get_contents($logFile), true) ?: [];
|
|
$db = getDb();
|
|
$stmt = $db->prepare("
|
|
INSERT IGNORE INTO changelog (id, company_id, timestamp, user, action, customer_id, customer_name, details)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
");
|
|
foreach ($logs as $log) {
|
|
$stmt->execute([
|
|
$log['id'] ?? bin2hex(random_bytes(8)),
|
|
$companyId,
|
|
$log['timestamp'] ?? date('Y-m-d H:i:s'),
|
|
$log['user'] ?? '',
|
|
$log['action'] ?? '',
|
|
$log['customer_id'] ?? '',
|
|
$log['customer_name'] ?? '',
|
|
$log['details'] ?? '',
|
|
]);
|
|
}
|
|
echo " ✓ " . count($logs) . " lokimerkintää\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
echo "\n=== Migraatio valmis! ===\n";
|
|
echo "\nSeuraavat vaiheet:\n";
|
|
echo "1. Testaa: php -r \"require 'db.php'; print_r(dbLoadCompanies());\"\n";
|
|
echo "2. Ota MySQL-pohjainen api.php käyttöön\n";
|