TunnelStoreProvisioner expands bare hosts to http:// for unsecure and https:// for optional secure; full URLs still work. Tunnel block strips scheme for prefill display. Update tunnel template copy, Index error text, and README/docs.
132 lines
3.5 KiB
PHP
132 lines
3.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace MageSail\Magesail\Block\Adminhtml;
|
|
|
|
use Magento\Backend\Block\Template;
|
|
use Magento\Backend\Block\Template\Context;
|
|
use MageSail\Magesail\Model\TunnelStatus;
|
|
use MageSail\Magesail\Model\TunnelStoreProvisioner;
|
|
|
|
class Tunnel extends Template
|
|
{
|
|
private const LOG_TAIL_BYTES = 8192;
|
|
private const LOG_TAIL_LINES = 40;
|
|
|
|
public function __construct(
|
|
Context $context,
|
|
private readonly TunnelStatus $tunnelStatus,
|
|
private readonly TunnelStoreProvisioner $tunnelStoreProvisioner,
|
|
array $data = []
|
|
) {
|
|
parent::__construct($context, $data);
|
|
}
|
|
|
|
/**
|
|
* @return array{running: bool, pid: int|null, key: string|null}
|
|
*/
|
|
public function getTunnelStatus(): array
|
|
{
|
|
return $this->tunnelStatus->getStatus();
|
|
}
|
|
|
|
/**
|
|
* Persisted tunnel store (present while tunnel is configured; may exist briefly before PID appears).
|
|
*
|
|
* @return array{store_id: int, store_code: string, unsecure_base_url: string, secure_base_url: string, use_secure_urls: bool}|null
|
|
*/
|
|
public function getTunnelStoreState(): ?array
|
|
{
|
|
return $this->tunnelStoreProvisioner->getPersistedState();
|
|
}
|
|
|
|
public function getTunnelStoreCodeConstant(): string
|
|
{
|
|
return TunnelStoreProvisioner::STORE_CODE;
|
|
}
|
|
|
|
/**
|
|
* Strip scheme for display so Admin shows hostname-only; persisted URLs stay full in state.
|
|
*/
|
|
public function getTunnelHostDisplay(?string $baseUrl): string
|
|
{
|
|
if ($baseUrl === null || $baseUrl === '') {
|
|
return '';
|
|
}
|
|
$parts = parse_url($baseUrl);
|
|
if ($parts === false || empty($parts['host'])) {
|
|
return $baseUrl;
|
|
}
|
|
$out = $parts['host'];
|
|
if (!empty($parts['port'])) {
|
|
$out .= ':' . $parts['port'];
|
|
}
|
|
if (!empty($parts['path']) && $parts['path'] !== '/' && $parts['path'] !== '') {
|
|
$out .= rtrim($parts['path'], '/');
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
public function getConfigUrl(): string
|
|
{
|
|
return $this->getUrl('adminhtml/system_config/edit/section/magesail');
|
|
}
|
|
|
|
public function getStatusUrl(): string
|
|
{
|
|
return $this->getUrl('*/*/status');
|
|
}
|
|
|
|
public function getIndexUrl(): string
|
|
{
|
|
return $this->getUrl('*/*/index');
|
|
}
|
|
|
|
public function getLogtailUrl(): string
|
|
{
|
|
return $this->getUrl('*/*/logtail');
|
|
}
|
|
|
|
public function getFormKey(): string
|
|
{
|
|
return $this->formKey->getFormKey();
|
|
}
|
|
|
|
public function getLogFilePath(): string
|
|
{
|
|
return $this->tunnelStatus->getLogFilePath();
|
|
}
|
|
|
|
/**
|
|
* @return string[]
|
|
*/
|
|
public function getRecentLogLines(): array
|
|
{
|
|
$path = $this->tunnelStatus->getLogFilePath();
|
|
if (!\is_readable($path)) {
|
|
return [];
|
|
}
|
|
$size = filesize($path);
|
|
if ($size === false || $size === 0) {
|
|
return [];
|
|
}
|
|
$fp = fopen($path, 'rb');
|
|
if ($fp === false) {
|
|
return [];
|
|
}
|
|
$start = max(0, $size - self::LOG_TAIL_BYTES);
|
|
fseek($fp, $start);
|
|
if ($start > 0) {
|
|
fgets($fp);
|
|
}
|
|
$chunk = stream_get_contents($fp) ?: '';
|
|
fclose($fp);
|
|
$lines = preg_split('/\R/', $chunk) ?: [];
|
|
$lines = array_values(array_filter($lines, static fn ($l) => $l !== ''));
|
|
if (\count($lines) > self::LOG_TAIL_LINES) {
|
|
$lines = \array_slice($lines, -self::LOG_TAIL_LINES);
|
|
}
|
|
return $lines;
|
|
}
|
|
}
|