Files
kupshop/bundles/KupShop/KupShopBundle/Util/RequestUtil.php
2025-08-02 16:30:27 +02:00

180 lines
5.7 KiB
PHP

<?php
namespace KupShop\KupShopBundle\Util;
use Blackfire\ClientConfiguration;
use KupShop\KupShopBundle\Context\DomainContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
class RequestUtil
{
private const BOT_IDENTIFIERS = [
'bot',
'slurp',
'crawler',
'spider',
'curl',
'facebook',
'fetch',
];
public function isRobot(Request $request): bool
{
$userAgent = strtolower($request->headers->get('User-Agent'));
foreach (self::BOT_IDENTIFIERS as $identifier) {
if (strpos($userAgent, $identifier) !== false) {
return true;
}
}
return false;
}
public function modifyQueryParameters(Request $request, callable $queryCallback): bool
{
parse_str($request->server->get('QUERY_STRING'), $queryParameters);
$queryParameters = $queryCallback($queryParameters);
$request->server->set('QUERY_STRING', http_build_query($queryParameters));
$request->initialize($request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request->files->all(), $request->server->all(), $request->getContent());
return false;
}
public function setPathInfo(Request $request, string $newPathInfo)
{
$request->server->set('REQUEST_URI', $newPathInfo);
$request->initialize($request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request->files->all(), $request->server->all(), $request->getContent());
}
/** Return request controller split into parts - controller, action.
*
* @return string
*/
public function getController(Request $request)
{
$controller = $request->attributes->get('_controller');
if (is_array($controller)) {
return $controller[0];
}
return $controller;
}
/** Return request controller split into parts - controller, action.
*
* @return array
*/
public function getControllerInfo(Request $request)
{
$controller = $this->getController($request);
if (strpos($controller, '::') !== false) {
$parts = explode('::', $controller);
return [
'action' => $parts[1],
'controllerFull' => $parts[0],
'controller' => strtolower(str_replace('Controller', '', basename(str_replace('\\', '/', $parts[0])))),
];
}
if (strpos($controller, ':') !== false) {
$parts = explode(':', $controller);
return [
'action' => $parts[1],
'controllerFull' => $parts[0],
'controller' => basename(str_replace('.', '/', $parts[0])),
];
}
return [
'action' => $controller,
'controllerFull' => $controller,
'controller' => $controller,
];
}
public function getControllerFromEvent(ControllerEvent $event)
{
$controller = $event->getController();
$actionName = null;
if (is_array($controller)) {
$actionName = $controller[1] ?? 'unknown';
$controller = $controller[0];
}
$className = get_class($controller) ?? 'unknown';
$actionName = $actionName ?: '__invoke';
return [$className, $actionName];
}
public function addTransactionInfo(Request $request, array $infos): void
{
$transaction = [...$request->attributes->get('wpj_transaction', []), ...$infos];
$request->attributes->set('wpj_transaction', $transaction);
$transactionString = join('|', $transaction);
$monitoredStrings = explode("\n", \Settings::getDefault()->blackfire_profiles ?? '');
if (in_array($transactionString, $monitoredStrings) && class_exists(\Blackfire\Client::class)) {
try {
$config = new ClientConfiguration();
$config->setClientId('2bbb0e6d-c183-424b-a3bf-dca8b1745714');
$config->setClientToken('40cd833768e57650a52ae556f5dfaf090af99307158248adc926898eb743023c');
$blackfire = new \Blackfire\Client($config);
$config = new \Blackfire\Profile\Configuration();
// set the profile title
$config->setTitle(getShopName().': '.$transactionString);
// attach some metadata to the profile
$config->setMetadata('pull-request', '42');
// By default, profiles created with the SDK won't appear in the profiles list.
// Disable "skip_timeline" if you want your profiles to be listed anyway.
// "false" must be passed as a string. "0" is valid as well.
$config->setMetadata('skip_timeline', 'false');
// Save probe as global to keep it alive until end of requests
$GLOBALS['probe'] = $blackfire->createProbe($config);
} catch (\Throwable $e) {
// Ignore Blackfire profiling exception
}
}
}
public function getTransactionInfo(Request $request): array
{
return $request->attributes->get('wpj_transaction', []);
}
public function getTransactionInfoString(Request $request): string
{
return join('|', $this->getTransactionInfo($request));
}
public function isSafeRedirectUrl($url): bool
{
if (StringUtil::startsWith($url, '/')) {
return true;
}
$domain = parse_url($url, PHP_URL_HOST);
if (in_array($domain, Contexts::get(DomainContext::class)->getSupported())) {
return true;
}
return false;
}
}