Tul xxx Tul
User / IP
:
216.73.216.227
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
comidarapidamaylor
/
components
/
Viewing: printer_functions.php
<?php function ensurePrinterSchema(PDO $conn): void { static $done = false; if ($done) { return; } try { $conn->exec( "CREATE TABLE IF NOT EXISTS `printers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, `system_name` varchar(255) DEFAULT NULL, `ticket_width` int(11) NOT NULL DEFAULT 58, `copies` int(11) NOT NULL DEFAULT 1, `auto_print` tinyint(1) NOT NULL DEFAULT 1, `is_active` tinyint(1) NOT NULL DEFAULT 1, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_printers_name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" ); $conn->exec( "CREATE TABLE IF NOT EXISTS `printer_jobs` ( `id` int(11) NOT NULL AUTO_INCREMENT, `printer_id` int(11) DEFAULT NULL, `source_type` enum('dine_in','delivery') NOT NULL, `order_id` int(11) NOT NULL, `order_number` int(11) DEFAULT NULL, `status` enum('pending','printed','error','skipped') NOT NULL DEFAULT 'pending', `payload` mediumtext, `error_message` text DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `printed_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_printer_jobs_printer` (`printer_id`), KEY `idx_printer_jobs_order` (`source_type`,`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" ); $printerColumnExists = (int) $conn->query( "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'products' AND COLUMN_NAME = 'printer_id'" )->fetchColumn(); if (!$printerColumnExists) { try { $conn->exec("ALTER TABLE `products` ADD COLUMN `printer_id` int(11) DEFAULT NULL AFTER `print_zone`"); } catch (Throwable $e) { $conn->exec("ALTER TABLE `products` ADD COLUMN `printer_id` int(11) DEFAULT NULL"); } } $idxExists = (int) $conn->query( "SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'products' AND INDEX_NAME = 'idx_products_printer_id'" )->fetchColumn(); if (!$idxExists) { try { $conn->exec("ALTER TABLE `products` ADD KEY `idx_products_printer_id` (`printer_id`)"); } catch (Throwable $ignored) { } } $printerCount = (int) $conn->query("SELECT COUNT(*) FROM `printers`")->fetchColumn(); if ($printerCount === 0) { $seedNames = []; try { $zones = $conn->query("SELECT name FROM `print_zones` WHERE is_active = 1 ORDER BY id ASC")->fetchAll(PDO::FETCH_COLUMN, 0); foreach ($zones as $zoneName) { $zoneName = trim((string) $zoneName); if ($zoneName !== '') { $seedNames[$zoneName] = $zoneName; } } } catch (Throwable $ignored) { } if (empty($seedNames)) { $seedNames = [ 'Cocina' => 'Cocina', 'Bebidas' => 'Bebidas', 'Bar' => 'Bar', ]; } $insert = $conn->prepare("INSERT IGNORE INTO `printers` (`name`, `system_name`, `ticket_width`, `copies`, `auto_print`, `is_active`) VALUES (?, '', 58, 1, 1, 1)"); foreach ($seedNames as $seedName) { $insert->execute([$seedName]); } } try { $conn->exec( "UPDATE `products` p INNER JOIN `printers` pr ON LOWER(TRIM(pr.name)) = LOWER(TRIM(p.print_zone)) SET p.printer_id = pr.id WHERE (p.printer_id IS NULL OR p.printer_id = 0) AND p.print_zone IS NOT NULL AND TRIM(p.print_zone) <> ''" ); } catch (Throwable $ignored) { } } catch (Throwable $ignored) { } $done = true; } function getPrinters(PDO $conn, bool $activeOnly = true): array { ensurePrinterSchema($conn); $sql = "SELECT * FROM `printers`"; if ($activeOnly) { $sql .= " WHERE is_active = 1"; } $sql .= " ORDER BY name ASC, id ASC"; try { $stmt = $conn->query($sql); return $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : []; } catch (Throwable $ignored) { return []; } } function normalizePrinterId(PDO $conn, $printerId): ?int { ensurePrinterSchema($conn); $printerId = (int) $printerId; if ($printerId <= 0) { return null; } try { $stmt = $conn->prepare("SELECT id FROM `printers` WHERE id = ? AND is_active = 1 LIMIT 1"); $stmt->execute([$printerId]); $found = (int) $stmt->fetchColumn(); return $found > 0 ? $found : null; } catch (Throwable $ignored) { return null; } } function getPrinterNameById(PDO $conn, ?int $printerId, string $default = ''): string { ensurePrinterSchema($conn); if (!$printerId || $printerId <= 0) { return $default; } try { $stmt = $conn->prepare("SELECT name FROM `printers` WHERE id = ? LIMIT 1"); $stmt->execute([$printerId]); $name = $stmt->fetchColumn(); $name = trim((string) $name); return $name !== '' ? $name : $default; } catch (Throwable $ignored) { return $default; } } function printerTextCenter(string $text, int $width): string { $text = trim($text); $len = strlen($text); if ($len >= $width) { return $text; } return str_repeat(' ', (int) floor(($width - $len) / 2)) . $text; } function printerTextWrap(string $text, int $width): array { $text = trim(preg_replace('/\s+/', ' ', $text)); if ($text === '') { return ['']; } $wrapped = wordwrap($text, $width, "\n", true); return explode("\n", $wrapped); } function buildKitchenTicketText(PDO $conn, string $sourceType, array $order, array $items, array $printer): string { $widthMm = (int) ($printer['ticket_width'] ?? 58); $width = $widthMm >= 80 ? 42 : 32; $separator = str_repeat('=', $width); $thinSeparator = str_repeat('-', $width); $businessName = function_exists('getBusinessName') ? getBusinessName($conn) : ''; if (trim($businessName) === '') { $businessName = 'Comanda'; } $orderNumber = (int) ($order['order_number'] ?? $order['id'] ?? 0); $title = $sourceType === 'delivery' ? 'PEDIDO DOMICILIO' : 'COMANDA'; $createdAt = trim((string) ($order['created_at'] ?? '')); if ($createdAt !== '') { try { $createdAt = (new DateTime($createdAt))->format('d/m/Y h:i A'); } catch (Throwable $ignored) { } } $lines = []; $lines[] = $separator; $lines[] = printerTextCenter($businessName, $width); $lines[] = printerTextCenter($title . ' #' . str_pad((string) $orderNumber, 4, '0', STR_PAD_LEFT), $width); $lines[] = $separator; if ($sourceType === 'delivery') { $origin = trim((string) ($order['source'] ?? '')); if ($origin !== '') { $lines[] = 'Origen: ' . ($origin === 'web' ? 'Web' : 'POS'); } $lines[] = 'Cliente: ' . trim((string) ($order['customer_name'] ?? '')); $phone = trim((string) ($order['phone'] ?? '')); if ($phone !== '') { $lines[] = 'Tel: ' . $phone; } $zone = trim((string) ($order['delivery_zone_name'] ?? '')); if ($zone !== '') { $lines[] = 'Zona: ' . $zone; } $address = trim((string) ($order['address'] ?? '')); if ($address !== '') { $lines[] = 'Dir:'; foreach (printerTextWrap($address, $width) as $part) { $lines[] = $part; } } } else { $table = trim((string) ($order['table_number'] ?? '')); if ($table !== '') { $lines[] = 'Mesa: ' . $table; } $customer = trim((string) ($order['customer_name'] ?? '')); if ($customer !== '') { $lines[] = 'Cliente: ' . $customer; } } if ($createdAt !== '') { $lines[] = 'Fecha: ' . $createdAt; } $printerName = trim((string) ($printer['name'] ?? '')); if ($printerName !== '') { $lines[] = 'Impresora: ' . $printerName; } $lines[] = $thinSeparator; foreach ($items as $item) { $qty = (int) ($item['quantity'] ?? $item['cantidad'] ?? 0); if ($qty <= 0) { $qty = 1; } $name = trim((string) ($item['product_name'] ?? $item['nombre'] ?? 'Producto')); $prefix = $qty . ' x '; $wrapped = printerTextWrap($name, max(10, $width - strlen($prefix))); $lines[] = $prefix . array_shift($wrapped); foreach ($wrapped as $part) { $lines[] = str_repeat(' ', strlen($prefix)) . $part; } } $notes = trim((string) ($order['notes'] ?? '')); if ($notes !== '') { $lines[] = $thinSeparator; $lines[] = 'Notas:'; foreach (printerTextWrap($notes, $width) as $part) { $lines[] = $part; } } $lines[] = $separator; $lines[] = ''; $lines[] = ''; return implode("\r\n", $lines); } function sendTextToConfiguredPrinter(array $printer, string $payload): array { $systemName = trim((string) ($printer['system_name'] ?? '')); if ($systemName === '') { return ['status' => 'skipped', 'message' => 'Falta el nombre del sistema de la impresora.']; } if (!function_exists('exec')) { return ['status' => 'error', 'message' => 'La funcion exec() no esta disponible en PHP.']; } $tmpBase = tempnam(sys_get_temp_dir(), 'cmd_'); if ($tmpBase === false) { return ['status' => 'error', 'message' => 'No se pudo crear el archivo temporal de impresion.']; } $filePath = $tmpBase . '.txt'; @rename($tmpBase, $filePath); if (@file_put_contents($filePath, $payload) === false) { @unlink($filePath); return ['status' => 'error', 'message' => 'No se pudo escribir el archivo temporal de impresion.']; } $copies = max(1, min(5, (int) ($printer['copies'] ?? 1))); $allOutput = []; $lastExitCode = 0; for ($i = 0; $i < $copies; $i++) { $output = []; $exitCode = 0; if (stripos(PHP_OS_FAMILY, 'Windows') !== false) { $cmd = 'print /D:' . escapeshellarg($systemName) . ' ' . escapeshellarg($filePath); } else { $cmd = 'lp -d ' . escapeshellarg($systemName) . ' ' . escapeshellarg($filePath); } @exec($cmd . ' 2>&1', $output, $exitCode); $lastExitCode = (int) $exitCode; $allOutput = array_merge($allOutput, $output); if ($lastExitCode !== 0) { break; } } @unlink($filePath); if ($lastExitCode !== 0) { $message = trim(implode(' ', array_filter(array_map('trim', $allOutput)))); if ($message === '') { $message = 'El comando de impresion devolvio codigo ' . $lastExitCode . '.'; } return ['status' => 'error', 'message' => $message]; } return ['status' => 'printed', 'message' => 'Impresion enviada.']; } function getOrderPrinterGroups(PDO $conn, string $sourceType, int $orderId, ?int $targetPrinterId = null): array { ensurePrinterSchema($conn); $sourceType = $sourceType === 'delivery' ? 'delivery' : 'dine_in'; if ($sourceType === 'delivery') { $orderStmt = $conn->prepare("SELECT * FROM `delivery_orders` WHERE id = ? LIMIT 1"); $itemsSql = "SELECT i.*, i.price AS unit_price, COALESCE(pr.id, pz.id) AS resolved_printer_id, COALESCE(pr.name, pz.name) AS printer_name, COALESCE(pr.system_name, pz.system_name) AS system_name, COALESCE(pr.ticket_width, pz.ticket_width, 58) AS ticket_width, COALESCE(pr.copies, pz.copies, 1) AS copies, COALESCE(pr.auto_print, pz.auto_print, 1) AS auto_print FROM `delivery_order_items` i LEFT JOIN `products` p ON p.id = i.product_id LEFT JOIN `printers` pr ON pr.id = p.printer_id AND pr.is_active = 1 LEFT JOIN `printers` pz ON (p.printer_id IS NULL OR p.printer_id = 0) AND LOWER(TRIM(pz.name)) = LOWER(TRIM(p.print_zone)) AND pz.is_active = 1 WHERE i.order_id = ? ORDER BY i.id ASC"; } else { $orderStmt = $conn->prepare("SELECT * FROM `dine_in_orders` WHERE id = ? LIMIT 1"); $itemsSql = "SELECT i.*, i.unit_price AS unit_price, COALESCE(pr.id, pz.id) AS resolved_printer_id, COALESCE(pr.name, pz.name) AS printer_name, COALESCE(pr.system_name, pz.system_name) AS system_name, COALESCE(pr.ticket_width, pz.ticket_width, 58) AS ticket_width, COALESCE(pr.copies, pz.copies, 1) AS copies, COALESCE(pr.auto_print, pz.auto_print, 1) AS auto_print FROM `dine_in_order_items` i LEFT JOIN `products` p ON p.id = i.product_id LEFT JOIN `printers` pr ON pr.id = p.printer_id AND pr.is_active = 1 LEFT JOIN `printers` pz ON (p.printer_id IS NULL OR p.printer_id = 0) AND LOWER(TRIM(pz.name)) = LOWER(TRIM(p.print_zone)) AND pz.is_active = 1 WHERE i.order_id = ? ORDER BY i.id ASC"; } $orderStmt->execute([$orderId]); $order = $orderStmt->fetch(PDO::FETCH_ASSOC); if (!$order) { return ['order' => null, 'groups' => [], 'unassigned' => 0]; } $itemsStmt = $conn->prepare($itemsSql); $itemsStmt->execute([$orderId]); $groups = []; $unassigned = 0; foreach ($itemsStmt->fetchAll(PDO::FETCH_ASSOC) as $item) { $printerId = (int) ($item['resolved_printer_id'] ?? 0); if ($printerId <= 0) { $unassigned++; $printerId = -1; // ID especial para agrupar los sin asignar } if ($targetPrinterId !== null && $targetPrinterId > 0 && $printerId !== $targetPrinterId) { continue; } if (!isset($groups[$printerId])) { if ($printerId === -1) { // Generar un ticket genĂ©rico para los no asignados $groups[$printerId] = [ 'printer' => [ 'id' => null, 'name' => 'General', 'system_name' => '', 'ticket_width' => 58, 'copies' => 1, 'auto_print' => 1, ], 'items' => [], ]; } else { $groups[$printerId] = [ 'printer' => [ 'id' => $printerId, 'name' => (string) ($item['printer_name'] ?? ''), 'system_name' => (string) ($item['system_name'] ?? ''), 'ticket_width' => (int) ($item['ticket_width'] ?? 58), 'copies' => (int) ($item['copies'] ?? 1), 'auto_print' => (int) ($item['auto_print'] ?? 1), ], 'items' => [], ]; } } $groups[$printerId]['items'][] = $item; } return ['order' => $order, 'groups' => array_values($groups), 'unassigned' => $unassigned]; } function dispatchOrderPrintJobs(PDO $conn, string $sourceType, int $orderId): array { ensurePrinterSchema($conn); $sourceType = $sourceType === 'delivery' ? 'delivery' : 'dine_in'; $summary = [ 'total' => 0, 'printed' => 0, 'skipped' => 0, 'errors' => 0, 'details' => [], ]; try { $data = getOrderPrinterGroups($conn, $sourceType, $orderId); $order = $data['order'] ?? null; if (!$order) { return $summary; } $insertJob = $conn->prepare( "INSERT INTO `printer_jobs` (printer_id, source_type, order_id, order_number, status, payload) VALUES (?, ?, ?, ?, 'pending', ?)" ); $updateJob = $conn->prepare( "UPDATE `printer_jobs` SET status = ?, error_message = ?, printed_at = ? WHERE id = ?" ); foreach (($data['groups'] ?? []) as $group) { $printer = $group['printer'] ?? []; $items = $group['items'] ?? []; if (empty($printer) || empty($items)) { continue; } $summary['total']++; $payload = buildKitchenTicketText($conn, $sourceType, $order, $items, $printer); $insertJob->execute([ (int) ($printer['id'] ?? 0), $sourceType, $orderId, (int) ($order['order_number'] ?? $orderId), $payload, ]); $jobId = (int) $conn->lastInsertId(); if ((int) ($printer['auto_print'] ?? 1) !== 1) { $status = 'skipped'; $message = 'Impresion automatica desactivada.'; } else { // UNIVERSAL CLOUD PRINTING: // En lugar de intentar imprimir por debajo usando exec (que falla en Hostinger), // dejamos el trabajo 'pending' y el frontend abrirĂ¡ la ventana emergente. $status = 'pending'; $message = 'Listo para imprimir via navegador.'; } $printedAt = null; $updateJob->execute([$status, $message, $printedAt, $jobId]); if ($status === 'pending') { $summary['printed']++; // Counted as 'printed' for backward compatibility in UI summaries } elseif ($status === 'skipped') { $summary['skipped']++; } else { $summary['errors']++; } $summary['details'][] = [ 'job_id' => $jobId, 'printer_id' => (int) ($printer['id'] ?? 0), 'printer_name' => (string) ($printer['name'] ?? ''), 'status' => $status, 'message' => $message, 'auto_print' => (int) ($printer['auto_print'] ?? 1) ]; } } catch (Throwable $e) { $summary['errors']++; $summary['details'][] = [ 'printer_id' => 0, 'printer_name' => '', 'status' => 'error', 'message' => 'No se pudo despachar la impresion.', ]; } return $summary; }
Coded With 💗 by
0x6ick