Skip to content

Commit

Permalink
Allow override of some configuration per store (#155)
Browse files Browse the repository at this point in the history
Co-authored-by: Bruno Fache <[email protected]>
  • Loading branch information
indykoning and bruno-blackbird authored Dec 12, 2024
1 parent 13747c7 commit b4fd7e1
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 74 deletions.
93 changes: 57 additions & 36 deletions Helper/Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Framework\App\State;
use Magento\Framework\DB\Adapter\TableNotFoundException;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\RuntimeException;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use RuntimeException;
use Throwable;

class Data extends AbstractHelper
Expand Down Expand Up @@ -83,23 +84,23 @@ public function __construct(
*/
public function getDSN()
{
return $this->config['dsn'];
return $this->collectModuleConfig()['dsn'];
}

/**
* Whether tracing is enabled.
*/
public function isTracingEnabled(): bool
{
return $this->config['tracing_enabled'] ?? false;
return $this->collectModuleConfig()['tracing_enabled'] ?? false;
}

/**
* Get sample rate for tracing.
*/
public function getTracingSampleRate(): float
{
return (float) ($this->config['tracing_sample_rate'] ?? 0.2);
return (float) ($this->collectModuleConfig()['tracing_sample_rate'] ?? 0.2);
}

/**
Expand All @@ -117,19 +118,21 @@ public function getDisabledDefaultIntegrations(): array
*/
public function getIgnoreJsErrors()
{
$list = $this->config['ignore_js_errors'];
$list = $this->collectModuleConfig()['ignore_js_errors'];

if ($list === null) {
return null;
}

try {
$list = is_array($this->config['ignore_js_errors'])
? $this->config['ignore_js_errors']
: $this->serializer->unserialize($this->config['ignore_js_errors']);
$config = $this->collectModuleConfig();
$list = is_array($config['ignore_js_errors'])
? $config['ignore_js_errors']
: $this->serializer->unserialize($config['ignore_js_errors']);
} catch (InvalidArgumentException $e) {
throw new RuntimeException(
'Sentry configuration error: `ignore_js_errors` has to be an array or `null`. Given type: '.gettype($list) // phpcs:ignore
__('Sentry configuration error: `ignore_js_errors` has to be an array or `null`. Given type: %s', gettype($list)), // phpcs:ignore
$e
);
}

Expand All @@ -143,7 +146,7 @@ public function getIgnoreJsErrors()
*/
public function getJsSdkVersion(): string
{
return $this->config['js_sdk_version'] ?: SentryScript::CURRENT_VERSION;
return $this->collectModuleConfig()['js_sdk_version'] ?: SentryScript::CURRENT_VERSION;
}

/**
Expand All @@ -153,7 +156,7 @@ public function getJsSdkVersion(): string
*/
public function getEnvironment()
{
return $this->config['environment'];
return $this->collectModuleConfig()['environment'] ?? 'default';
}

/**
Expand Down Expand Up @@ -186,34 +189,45 @@ public function getGeneralConfig($code, $storeId = null)
return $this->getConfigValue(static::XML_PATH_SRS.$code, $storeId);
}

/**
* Get the store id of the current store.
*
* @return int
*/
public function getStoreId(): int
{
return $this->getStore()?->getId() ?? 0;
}

/**
* Gather all configuration.
*
* @return array
*/
public function collectModuleConfig(): array
{
if (isset($this->config['enabled'])) {
return $this->config;
$storeId = $this->getStoreId();
if (isset($this->config[$storeId]['enabled'])) {
return $this->config[$storeId];
}

try {
$this->config['enabled'] = $this->scopeConfig->getValue('sentry/environment/enabled')
$this->config[$storeId]['enabled'] = $this->scopeConfig->getValue('sentry/environment/enabled', ScopeInterface::SCOPE_STORE)
?? $this->deploymentConfig->get('sentry') !== null;
} catch (TableNotFoundException $e) {
$this->config['enabled'] = null;
} catch (TableNotFoundException|FileSystemException|RuntimeException $e) {
$this->config[$storeId]['enabled'] = null;
}

foreach ($this->configKeys as $value) {
try {
$this->config[$value] = $this->scopeConfig->getValue('sentry/environment/'.$value)
$this->config[$storeId][$value] = $this->scopeConfig->getValue('sentry/environment/'.$value, ScopeInterface::SCOPE_STORE)
?? $this->deploymentConfig->get('sentry/'.$value);
} catch (TableNotFoundException $e) {
$this->config[$value] = null;
} catch (TableNotFoundException|FileSystemException|RuntimeException $e) {
$this->config[$storeId][$value] = null;
}
}

return $this->config;
return $this->config[$storeId];
}

/**
Expand All @@ -234,8 +248,9 @@ public function isActive(): bool
public function isActiveWithReason(): array
{
$reasons = [];
$emptyConfig = empty($this->config);
$configEnabled = array_key_exists('enabled', $this->config) && $this->config['enabled'];
$config = $this->collectModuleConfig();
$emptyConfig = empty($config);
$configEnabled = isset($config['enabled']) && $config['enabled'];
$dsnNotEmpty = $this->getDSN();
$productionMode = ($this->isProductionMode() || $this->isOverwriteProductionMode());

Expand Down Expand Up @@ -282,11 +297,13 @@ public function getAppState(): string
*/
public function isOverwriteProductionMode(): bool
{
return array_key_exists('mage_mode_development', $this->config) && $this->config['mage_mode_development'];
$config = $this->collectModuleConfig();

return isset($config['mage_mode_development']) && $config['mage_mode_development'];
}

/**
* Get the current magento version.
* Get the current magento version.
*
* @return string
*/
Expand All @@ -310,7 +327,7 @@ public function getStore()
*/
public function isPhpTrackingEnabled(): bool
{
return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'enable_php_tracking');
return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'enable_php_tracking', ScopeInterface::SCOPE_STORE);
}

/**
Expand All @@ -320,15 +337,15 @@ public function isPhpTrackingEnabled(): bool
*/
public function useScriptTag(): bool
{
return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'enable_script_tag');
return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'enable_script_tag', ScopeInterface::SCOPE_STORE);
}

/**
* Whether to enable session replay.
*/
public function useSessionReplay(): bool
{
return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'enable_session_replay');
return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'enable_session_replay', ScopeInterface::SCOPE_STORE);
}

/**
Expand Down Expand Up @@ -390,7 +407,7 @@ public function showScriptTagInThisBlock($blockName): bool
*/
public function getLogrocketKey()
{
return $this->config['logrocket_key'];
return $this->collectModuleConfig()['logrocket_key'];
}

/**
Expand All @@ -401,7 +418,7 @@ public function getLogrocketKey()
public function useLogrocket(): bool
{
return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'use_logrocket') &&
array_key_exists('logrocket_key', $this->config) &&
isset($this->collectModuleConfig()['logrocket_key']) &&
$this->getLogrocketKey() !== null;
}

Expand All @@ -413,7 +430,8 @@ public function useLogrocket(): bool
public function useLogrocketIdentify(): bool
{
return $this->scopeConfig->isSetFlag(
static::XML_PATH_SRS.'logrocket_identify'
static::XML_PATH_SRS.'logrocket_identify',
ScopeInterface::SCOPE_STORE
);
}

Expand All @@ -425,7 +443,8 @@ public function useLogrocketIdentify(): bool
public function stripStaticContentVersion(): bool
{
return $this->scopeConfig->isSetFlag(
static::XML_PATH_SRS_ISSUE_GROUPING.'strip_static_content_version'
static::XML_PATH_SRS_ISSUE_GROUPING.'strip_static_content_version',
ScopeInterface::SCOPE_STORE
);
}

Expand All @@ -437,7 +456,8 @@ public function stripStaticContentVersion(): bool
public function stripStoreCode(): bool
{
return $this->scopeConfig->isSetFlag(
static::XML_PATH_SRS_ISSUE_GROUPING.'strip_store_code'
static::XML_PATH_SRS_ISSUE_GROUPING.'strip_store_code',
ScopeInterface::SCOPE_STORE
);
}

Expand All @@ -448,7 +468,7 @@ public function stripStoreCode(): bool
*/
public function getErrorExceptionReporting(): int
{
return (int) ($this->config['errorexception_reporting'] ?? E_ALL);
return (int) ($this->collectModuleConfig()['errorexception_reporting'] ?? E_ALL);
}

/**
Expand All @@ -458,12 +478,13 @@ public function getErrorExceptionReporting(): int
*/
public function getIgnoreExceptions(): array
{
if (is_array($this->config['ignore_exceptions'])) {
return $this->config['ignore_exceptions'];
$config = $this->collectModuleConfig();
if (is_array($config['ignore_exceptions'])) {
return $config['ignore_exceptions'];
}

try {
return $this->serializer->unserialize($this->config['ignore_exceptions']);
return $this->serializer->unserialize($config['ignore_exceptions']);
} catch (InvalidArgumentException $e) {
return [];
}
Expand Down
45 changes: 30 additions & 15 deletions Model/SentryInteraction.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Magento\Framework\App\Area;
use Magento\Framework\App\State;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\ObjectManager\ConfigInterface;
use ReflectionClass;
use Sentry\State\Scope;

Expand All @@ -29,10 +30,12 @@ class SentryInteraction
/**
* SentryInteraction constructor.
*
* @param State $appState
* @param State $appState
* @param ConfigInterface $omConfigInterface
*/
public function __construct(
private State $appState
private State $appState,
private ConfigInterface $omConfigInterface
) {
}

Expand Down Expand Up @@ -61,6 +64,26 @@ public function canGetUserContext()
}
}

/**
* Get a class instance, but only if it is already available within the objectManager.
*
* @param string $class The classname of the type you want from the objectManager.
*/
public function getObjectIfInitialized($class): ?object
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$reflectionClass = new ReflectionClass($objectManager);
$sharedInstances = $reflectionClass->getProperty('_sharedInstances');
$sharedInstances->setAccessible(true);
$class = $this->omConfigInterface->getPreference($class);

if (!array_key_exists(ltrim($class, '\\'), $sharedInstances->getValue($objectManager))) {
return null;
}

return $objectManager->get($class);
}

/**
* Attempt to get userContext from the objectManager, so we don't request it too early.
*/
Expand All @@ -70,9 +93,7 @@ public function getUserContext(): ?UserContextInterface
return $this->userContext;
}

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

return $this->userContext = $objectManager->get(UserContextInterface::class);
return $this->userContext = $this->getObjectIfInitialized(UserContextInterface::class);
}

/**
Expand All @@ -97,17 +118,11 @@ private function getSessionUserData()
return [];
}

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$reflectionClass = new ReflectionClass($objectManager);
$sharedInstances = $reflectionClass->getProperty('_sharedInstances');
$sharedInstances->setAccessible(true);

if ($this->appState->getAreaCode() === Area::AREA_ADMINHTML) {
if (!array_key_exists(ltrim(AdminSession::class, '\\'), $sharedInstances->getValue($objectManager))) {
// Don't intitialise session if it has not already been started, this causes problems with dynamic resources.
$adminSession = $this->getObjectIfInitialized(AdminSession::class);
if ($adminSession === null) {
return [];
}
$adminSession = $objectManager->get(AdminSession::class);

if ($adminSession->isLoggedIn()) {
return [
Expand All @@ -119,10 +134,10 @@ private function getSessionUserData()
}

if ($this->appState->getAreaCode() === Area::AREA_FRONTEND) {
if (!array_key_exists(ltrim(CustomerSession::class, '\\'), $sharedInstances->getValue($objectManager))) {
$customerSession = $this->getObjectIfInitialized(CustomerSession::class);
if ($customerSession === null) {
return [];
}
$customerSession = $objectManager->get(CustomerSession::class);

if ($customerSession->isLoggedIn()) {
return [
Expand Down
Loading

0 comments on commit b4fd7e1

Please sign in to comment.