92 lines
3.3 KiB
PHP
92 lines
3.3 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace MageSail\Magesail\Plugin\Store;
|
|
|
|
use Magento\Framework\App\Request\Http;
|
|
use Magento\Framework\App\RequestInterface;
|
|
use Magento\Framework\UrlInterface;
|
|
use Magento\Store\Model\Store;
|
|
use MageSail\Magesail\Model\TunnelRequestDetector;
|
|
use MageSail\Magesail\Model\TunnelStoreState;
|
|
|
|
/**
|
|
* With tunnel proxy, HTTP_HOST is dev.myshop.local but store base URLs point at production (e.g. s1.x64.world).
|
|
* Rewrite scheme/host for page/link base URLs only — never for static/media/js or asset bases break (404).
|
|
* When persisted tunnel base URLs use a different path than production (e.g. no /pub/), use the tunnel path so
|
|
* backend URI validation matches the browser.
|
|
*/
|
|
class TunnelStoreBaseUrlPlugin
|
|
{
|
|
public function __construct(
|
|
private readonly RequestInterface $request,
|
|
private readonly TunnelRequestDetector $tunnelRequestDetector,
|
|
private readonly TunnelStoreState $tunnelStoreState
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @param Store $subject
|
|
* @param string $result
|
|
* @return string
|
|
*/
|
|
public function afterGetBaseUrl(Store $subject, $result, $type = null, $secure = null)
|
|
{
|
|
if (!$this->request instanceof Http || $result === '' || $result === null) {
|
|
return $result;
|
|
}
|
|
$effectiveType = $type ?? UrlInterface::URL_TYPE_LINK;
|
|
if (!\in_array($effectiveType, [
|
|
UrlInterface::URL_TYPE_LINK,
|
|
UrlInterface::URL_TYPE_DIRECT_LINK,
|
|
UrlInterface::URL_TYPE_WEB,
|
|
], true)) {
|
|
return $result;
|
|
}
|
|
if ($this->tunnelRequestDetector->getTunnelStoreCode($this->request) === null) {
|
|
return $result;
|
|
}
|
|
$parts = parse_url($result);
|
|
if ($parts === false || empty($parts['host'])) {
|
|
return $result;
|
|
}
|
|
$requestHost = $this->request->getHttpHost();
|
|
if ($requestHost === '' || strcasecmp((string) $parts['host'], $requestHost) === 0) {
|
|
return $result;
|
|
}
|
|
$scheme = $this->request->isSecure() ? 'https' : 'http';
|
|
$path = $this->pathForTunnelRewrite($scheme, $parts['path'] ?? '/');
|
|
$query = isset($parts['query']) ? '?' . $parts['query'] : '';
|
|
$fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : '';
|
|
return $scheme . '://' . $requestHost . $path . $query . $fragment;
|
|
}
|
|
|
|
/**
|
|
* Prefer path from persisted tunnel base URL (matches holesail vhost) when production base path differs.
|
|
*/
|
|
private function pathForTunnelRewrite(string $scheme, string $fallbackPath): string
|
|
{
|
|
$state = $this->tunnelStoreState->read();
|
|
if ($state === null) {
|
|
return $fallbackPath;
|
|
}
|
|
$preferSecure = $scheme === 'https';
|
|
$ref = $preferSecure ? $state['secure_base_url'] : $state['unsecure_base_url'];
|
|
if (trim($ref) === '') {
|
|
$ref = $preferSecure ? $state['unsecure_base_url'] : $state['secure_base_url'];
|
|
}
|
|
if (trim($ref) === '') {
|
|
return $fallbackPath;
|
|
}
|
|
$parsed = parse_url($ref);
|
|
if ($parsed === false) {
|
|
return $fallbackPath;
|
|
}
|
|
$path = $parsed['path'] ?? '';
|
|
if ($path === '' || $path === null) {
|
|
return '/';
|
|
}
|
|
return $path;
|
|
}
|
|
}
|