Rev 339 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php
declare(strict_types=1);
namespace LeadersLinked\Plugin;
use Laminas\Mvc\Controller\Plugin\AbstractPlugin;
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Authentication\AuthenticationService;
use LeadersLinked\Model\Device;
use LeadersLinked\Mapper\DeviceMapper;
use LeadersLinked\Model\UserType;
use LeadersLinked\Mapper\NetworkMapper;
class CurrentNetworkPlugin extends AbstractPlugin
{
/**
*
* @var \LeadersLinked\Plugin\CurrentNetworkPlugin
*/
private static $_instance;
/**
*
* @var AdapterInterface $adapter
*/
private $adapter;
/**
*
* @var boolean
*/
private $hasNetwork;
/**
*
* @return \LeadersLinked\Model\Network
*/
private $network;
/**
*
* @var string
*/
private $hostname;
/**
*
* @param AdapterInterface $adapter
* @return \LeadersLinked\Plugin\CurrentNetworkPlugin
*/
public static function getInstance($adapter)
{
if(self::$_instance == null) {
self::$_instance = new CurrentNetworkPlugin($adapter);
}
return self::$_instance;
}
/**
*
* @param AdapterInterface $adapter
*/
private function __construct($adapter)
{
$this->adapter = $adapter;
$this->hasNetwork = false;
$networkMapper = NetworkMapper::getInstance($adapter);
// Primero, intentamos determinar la red a partir de la URI de la solicitud.
// Esto es útil para los servicios internos o las llamadas a la API que pueden no tener un encabezado Host/Origin claro.
$request_uri = empty($_SERVER['REQUEST_URI']) ? '' : $_SERVER['REQUEST_URI'];
if($request_uri) {
if(substr($request_uri, 0, 1) == '/') {
$request_uri = substr($request_uri, 1);
}
$parts = explode('/', $request_uri);
// Si la URI comienza con 'services', asumimos que es una llamada interna y cargamos la red predeterminada.
if($parts[0] == 'services') {
$this->network = $networkMapper->fetchOneByDefault();
if($this->network) {
$this->hostname = $this->network->main_hostname;
$this->hasNetwork = true;
}
}
}
// Si no se encontró una red a través de la URI, intentamos determinarla a partir del nombre de host.
// Esto es para las solicitudes front-end estándar del navegador.
if(!$this->hasNetwork) {
// Intentamos obtener el nombre de host de varias cabeceras HTTP en orden de preferencia.
// HTTP_ORIGIN es el más fiable para las solicitudes de API (CORS).
$hostname = empty($_SERVER['HTTP_ORIGIN']) ? '' : $_SERVER['HTTP_ORIGIN'];
if(empty($hostname)) {
// HTTP_REFERER es una alternativa si el origen no está presente.
$hostname = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
if(empty($hostname)) {
// HTTP_HOST es el último recurso, que indica la máquina host de la solicitud.
$hostname = empty($_SERVER['HTTP_HOST']) ? '' : $_SERVER['HTTP_HOST'];
}
}
// Limpiamos el nombre de host eliminando el protocolo.
$hostname = trim(str_replace(['https://', 'http://'], '', $hostname));
//echo $hostname; exit;
// Manejamos los casos en los que el nombre de host puede incluir una ruta.
$parts = explode('/', $hostname);
$hostname = $parts > 1 ? $parts[0] : $hostname;
// Buscamos la red en la base de datos utilizando el nombre de host limpio.
$networkMapper = NetworkMapper::getInstance($adapter);
$this->network = $networkMapper->fetchOneByHostnameForFrontend($hostname);
if($this->network) {
// Si se encuentra una red, determinamos si el host coincide con el host principal o con un host alternativo.
$this->hostname = $this->network->main_hostname == $hostname ? $this->network->main_hostname : $this->network->alternative_hostname;
$this->hasNetwork = true;
}
}
}
/**
*
* @return \LeadersLinked\Model\Network
*/
public function getNetwork()
{
if($this->hasNetwork) {
return $this->network;
} else {
return null;
}
}
/**
*
* @return int
*/
public function getNetworkId()
{
if($this->hasNetwork) {
return $this->network->id;
} else {
return 0;
}
}
/**
*
* @return boolean
*/
public function hasNetwork()
{
return $this->hasNetwork;
}
public function getHostname() : string
{
return $this->hostname;
}
public function fetchDefaultNetwork()
{
$networkMapper = NetworkMapper::getInstance($this->adapter);
$this->network = $networkMapper->fetchOneByDefault();
if($this->network) {
$this->hasNetwork = true;
$this->hostname = $this->network->main_hostname;
}
}
}