Files
mivo/app/Controllers/QuickPrintController.php

272 lines
10 KiB
PHP

<?php
namespace App\Controllers;
use App\Core\Controller;
use App\Models\Config;
use App\Models\QuickPrintModel;
use App\Models\VoucherTemplateModel;
use App\Libraries\RouterOSAPI;
use App\Core\Middleware;
use App\Helpers\EncryptionHelper;
class QuickPrintController extends Controller {
public function __construct() {
Middleware::auth();
}
// Dashboard: List Cards
public function index($session) {
$qpModel = new QuickPrintModel();
$configModel = new Config();
$creds = $configModel->getSession($session);
$routerId = $creds['id'] ?? null;
// If no ID (Legacy), fallback to empty list or handle gracefully.
// For now, we assume ID exists as per migration plan.
$packages = $routerId ? $qpModel->getAllByRouterId($routerId) : [];
$data = [
'session' => $session,
'packages' => $packages
];
// Note: View will be 'quick_print/index'
return $this->view('quick_print/index', $data);
}
// List/Manage Packages (CRUD)
public function manage($session) {
$qpModel = new QuickPrintModel();
$configModel = new Config();
$creds = $configModel->getSession($session);
$routerId = $creds['id'] ?? null;
$packages = $routerId ? $qpModel->getAllByRouterId($routerId) : [];
$profiles = [];
if ($creds) {
$API = new RouterOSAPI();
$password = $creds['password'];
if (isset($creds['source']) && $creds['source'] === 'legacy') {
$password = RouterOSAPI::decrypt($password);
}
if ($API->connect($creds['ip'], $creds['user'], $password)) {
$profiles = $API->comm("/ip/hotspot/user/profile/print");
$API->disconnect();
}
}
$data = [
'session' => $session,
'packages' => $packages,
'profiles' => $profiles
];
return $this->view('quick_print/list', $data);
}
// CRUD: Store
public function store() {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return;
$session = $_POST['session'] ?? '';
$configModel = new Config();
$creds = $configModel->getSession($session);
$routerId = $creds['id'] ?? 0;
$data = [
'router_id' => $routerId,
'session_name' => $session,
'name' => $_POST['name'] ?? 'Package',
'server' => $_POST['server'] ?? 'all',
'profile' => $_POST['profile'] ?? 'default',
'prefix' => $_POST['prefix'] ?? '',
'char_length' => $_POST['char_length'] ?? 4,
'price' => $_POST['price'] ?? 0,
'selling_price' => $_POST['selling_price'] ?? ($_POST['price'] ?? 0),
'time_limit' => $_POST['time_limit'] ?? '',
'data_limit' => $_POST['data_limit'] ?? '',
'comment' => $_POST['comment'] ?? '',
'color' => $_POST['color'] ?? 'bg-blue-500'
];
$qpModel = new QuickPrintModel();
$qpModel->add($data);
\App\Helpers\FlashHelper::set('success', 'toasts.package_saved', 'toasts.package_saved_desc', [], true);
header("Location: /" . $session . "/quick-print/manage");
exit;
}
// CRUD: Update
public function update() {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return;
$session = $_POST['session'] ?? '';
$id = $_POST['id'] ?? '';
if (empty($id)) {
\App\Helpers\FlashHelper::set('error', 'common.error', 'toasts.error_missing_id', [], true);
header("Location: /" . $session . "/quick-print/manage");
exit;
}
$data = [
'name' => $_POST['name'] ?? 'Package',
'profile' => $_POST['profile'] ?? 'default',
'prefix' => $_POST['prefix'] ?? '',
'char_length' => $_POST['char_length'] ?? 4,
'price' => $_POST['price'] ?? 0,
'selling_price' => $_POST['selling_price'] ?? ($_POST['price'] ?? 0),
'time_limit' => $_POST['time_limit'] ?? '',
'data_limit' => $_POST['data_limit'] ?? '',
'comment' => $_POST['comment'] ?? '',
'color' => $_POST['color'] ?? 'bg-blue-500'
];
$qpModel = new QuickPrintModel();
$qpModel->update($id, $data); // Assuming update method exists in simple JSON model
\App\Helpers\FlashHelper::set('success', 'toasts.package_updated', 'toasts.package_updated_desc', [], true);
header("Location: /" . $session . "/quick-print/manage");
exit;
}
// CRUD: Delete
public function delete() {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return;
$session = $_POST['session'] ?? '';
$id = $_POST['id'] ?? '';
$qpModel = new QuickPrintModel();
$qpModel->delete($id);
\App\Helpers\FlashHelper::set('success', 'toasts.package_deleted', 'toasts.package_deleted_desc', [], true);
header("Location: /" . $session . "/quick-print/manage");
exit;
}
// ACTION: Generate User & Print
public function printPacket($session, $id) {
// 1. Get Package Details
$qpModel = new QuickPrintModel();
$package = $qpModel->getById($id);
if (!$package) {
die("Package not found");
}
// 2. Generate Credentials
$prefix = $package['prefix'];
$length = $package['char_length'];
$charSet = '1234567890abcdefghijklmnopqrstuvwxyz'; // Simple lowercase + num
$rand = substr(str_shuffle($charSet), 0, $length);
$username = $prefix . $rand;
$password = $username; // Default: user=pass (User Mode) - Can be improved later
// 3. Connect to Mikrotik & Add User
$configModel = new Config();
$creds = $configModel->getSession($session);
if (!$creds) die("Session error");
$API = new RouterOSAPI();
$password_router = $creds['password'];
if (isset($creds['source']) && $creds['source'] === 'legacy') {
$password_router = RouterOSAPI::decrypt($password_router);
}
if ($API->connect($creds['ip'], $creds['user'], $password_router)) {
$userData = [
'name' => $username,
'password' => $password,
'profile' => $package['profile'],
'comment' => $package['comment'] . " [QP]" // Mark as QuickPrint
];
// Limits
if(!empty($package['time_limit'])) $userData['limit-uptime'] = $package['time_limit'];
if(!empty($package['data_limit'])) {
// Check if M or G
// Simple logic for now, assuming raw if number, or passing string if Mikrotik accepts it (usually requires bytes)
// Let's assume user inputs "100M" or "1G" which usually needs parsing.
// For now, let's assume input is NUMBER in MB as per standard Mivo practice, OR generic string.
// We'll pass as is for strings, or multiply if strictly numeric?
// Let's rely on standard Mikrotik parsing if string passed, or convert.
// Mivo usually uses dropdown "MB/GB".
// Implementing simple conversion:
$val = intval($package['data_limit']);
if (strpos(strtolower($package['data_limit']), 'g') !== false) {
$userData['limit-bytes-total'] = $val * 1024 * 1024 * 1024;
} else {
$userData['limit-bytes-total'] = $val * 1024 * 1024; // Default MB
}
}
$API->comm("/ip/hotspot/user/add", $userData);
$API->disconnect();
} else {
\App\Helpers\FlashHelper::set('error', 'Connection Failed', 'Could not connect to router at ' . $creds['ip']);
header('Location: ' . ($_SERVER['HTTP_REFERER'] ?? '/' . $session . '/quick-print/manage'));
exit;
}
// 4. Render Template
$tplModel = new VoucherTemplateModel();
$templates = $tplModel->getAll();
$currentTemplate = $_GET['template'] ?? 'default';
$templateContent = '';
$viewName = 'print/default';
if ($currentTemplate !== 'default') {
$tpl = $tplModel->getById($currentTemplate);
if ($tpl) {
$templateContent = $tpl['content'];
$viewName = 'print/custom';
} else {
$currentTemplate = 'default';
}
}
// Calculate bytes for display
$dlVal = intval($package['data_limit']);
$bytes = (strpos(strtolower($package['data_limit']), 'g') !== false) ? $dlVal * 1024*1024*1024 : $dlVal * 1024*1024;
$userDataValues = [
'username' => $username,
'password' => $password,
'price' => $package['price'],
'validity' => $package['time_limit'],
'timelimit' => \App\Helpers\HotspotHelper::formatValidity($package['time_limit']),
'datalimit' => \App\Helpers\HotspotHelper::formatBytes($bytes),
'profile' => $package['profile'],
'comment' => 'Quick Print',
'hotspotname' => $creds['hotspot_name'],
'dns_name' => $creds['dns_name'],
'login_url' => (preg_match("~^(?:f|ht)tps?://~i", $creds['dns_name']) ? $creds['dns_name'] : "http://" . $creds['dns_name']) . "/login"
];
// --- Logo Handling ---
$logoModel = new \App\Models\Logo();
$logos = $logoModel->getAll();
$logoMap = [];
foreach ($logos as $l) {
$logoMap[$l['id']] = $l['path'];
}
$data = [
'users' => [$userDataValues],
'templates' => $templates,
'currentTemplate' => $currentTemplate,
'templateContent' => $templateContent,
'session' => $session,
'logoMap' => $logoMap
];
return $this->view($viewName, $data);
}
}