<?php
declare(strict_types=1);
namespace SlimStat\Dependencies\BrowscapPHP;
use SlimStat\Dependencies\BrowscapPHP\Cache\BrowscapCache;
use SlimStat\Dependencies\BrowscapPHP\Cache\BrowscapCacheInterface;
use SlimStat\Dependencies\BrowscapPHP\Formatter\FormatterInterface;
use SlimStat\Dependencies\BrowscapPHP\Helper\Quoter;
use SlimStat\Dependencies\BrowscapPHP\Parser\ParserInterface;
use SlimStat\Dependencies\Psr\Log\LoggerInterface;
use SlimStat\Dependencies\Psr\SimpleCache\CacheInterface;
use stdClass;
use UnexpectedValueException;
use function is_string;
use function sprintf;
/**
* Browscap.ini parsing class with caching and update capabilities
*/
final class Browscap implements BrowscapInterface
{
/**
* Parser to use
*/
private ?ParserInterface $parser = null;
/**
* Formatter to use
*/
private FormatterInterface $formatter;
/**
* The cache instance
*/
private BrowscapCacheInterface $cache;
private LoggerInterface $logger;
/**
* @throws void
*/
public function __construct(CacheInterface $cache, LoggerInterface $logger)
{
$this->cache = new BrowscapCache($cache, $logger);
$this->logger = $logger;
$this->formatter = new Formatter\PhpGetBrowser();
}
/**
* Set theformatter instance to use for the getBrowser() result
*
* @throws void
*/
public function setFormatter(Formatter\FormatterInterface $formatter): void
{
$this->formatter = $formatter;
}
/**
* Sets the parser instance to use
*
* @throws void
*/
public function setParser(ParserInterface $parser): void
{
$this->parser = $parser;
}
/**
* returns an instance of the used parser class
*
* @throws void
*/
public function getParser(): ParserInterface
{
if ($this->parser === null) {
$patternHelper = new Parser\Helper\GetPattern($this->cache, $this->logger);
$dataHelper = new Parser\Helper\GetData($this->cache, $this->logger, new Quoter());
$this->parser = new Parser\Ini($patternHelper, $dataHelper, $this->formatter);
}
return $this->parser;
}
/**
* parses the given user agent to get the information about the browser
*
* if no user agent is given, it uses {@see \SlimStat\Dependencies\BrowscapPHP\Helper\Support} to get it
*
* @param string $userAgent the user agent string
*
* @return stdClass the object containing the browsers details.
*
* @throws Exception
*/
public function getBrowser(?string $userAgent = null): stdClass
{
if ($this->cache->getVersion() === null) {
// there is no active/warm cache available
throw new Exception('there is no active cache available, please use the BrowscapUpdater and run the update command');
}
// Automatically detect the useragent
if (! is_string($userAgent)) {
$support = new Helper\Support($_SERVER);
$userAgent = $support->getUserAgent();
}
try {
// try to get browser data
$formatter = $this->getParser()->getBrowser($userAgent);
} catch (UnexpectedValueException $e) {
$this->logger->error(sprintf('could not parse useragent "%s"', $userAgent));
$formatter = null;
}
// if return is still NULL, updates are disabled... in this
// case we return an empty formatter instance
if ($formatter === null) {
$formatter = $this->formatter;
}
return $formatter->getData();
}
}