vendor/sentry/sentry/src/Integration/IntegrationRegistry.php line 58

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Sentry\Integration;
  4. use Psr\Log\LoggerInterface;
  5. use Sentry\Options;
  6. /**
  7. * @internal
  8. */
  9. final class IntegrationRegistry
  10. {
  11. /**
  12. * @var self|null The current instance
  13. */
  14. private static $instance;
  15. /**
  16. * @var array<class-string<IntegrationInterface>, bool> The registered integrations
  17. */
  18. private $integrations = [];
  19. private function __construct()
  20. {
  21. }
  22. /**
  23. * Gets the current singleton instance or creates a new one if it didn't
  24. * exists yet.
  25. */
  26. public static function getInstance(): self
  27. {
  28. if (null === self::$instance) {
  29. self::$instance = new self();
  30. }
  31. return self::$instance;
  32. }
  33. /**
  34. * Setups the integrations according to the given options. For each integration
  35. * the {@see IntegrationInterface::setupOnce()} method will be called only once
  36. * during the application lifetime.
  37. *
  38. * @param Options $options The SDK client options
  39. *
  40. * @return array<class-string<IntegrationInterface>, IntegrationInterface>
  41. */
  42. public function setupIntegrations(Options $options, LoggerInterface $logger): array
  43. {
  44. $integrations = [];
  45. foreach ($this->getIntegrationsToSetup($options) as $integration) {
  46. $integrations[\get_class($integration)] = $integration;
  47. $this->setupIntegration($integration, $logger);
  48. }
  49. return $integrations;
  50. }
  51. private function setupIntegration(IntegrationInterface $integration, LoggerInterface $logger): void
  52. {
  53. $integrationName = \get_class($integration);
  54. if (isset($this->integrations[$integrationName])) {
  55. return;
  56. }
  57. $integration->setupOnce();
  58. $this->integrations[$integrationName] = true;
  59. $logger->debug(sprintf('The "%s" integration has been installed.', $integrationName));
  60. }
  61. /**
  62. * @return IntegrationInterface[]
  63. */
  64. private function getIntegrationsToSetup(Options $options): array
  65. {
  66. $integrations = [];
  67. $defaultIntegrations = $this->getDefaultIntegrations($options);
  68. $userIntegrations = $options->getIntegrations();
  69. if (\is_array($userIntegrations)) {
  70. $userIntegrationsClasses = array_map('get_class', $userIntegrations);
  71. $pickedIntegrationsClasses = [];
  72. foreach ($defaultIntegrations as $defaultIntegration) {
  73. $integrationClassName = \get_class($defaultIntegration);
  74. if (!\in_array($integrationClassName, $userIntegrationsClasses, true) && !isset($pickedIntegrationsClasses[$integrationClassName])) {
  75. $integrations[] = $defaultIntegration;
  76. $pickedIntegrationsClasses[$integrationClassName] = true;
  77. }
  78. }
  79. foreach ($userIntegrations as $userIntegration) {
  80. $integrationClassName = \get_class($userIntegration);
  81. if (!isset($pickedIntegrationsClasses[$integrationClassName])) {
  82. $integrations[] = $userIntegration;
  83. $pickedIntegrationsClasses[$integrationClassName] = true;
  84. }
  85. }
  86. } else {
  87. $integrations = $userIntegrations($defaultIntegrations);
  88. if (!\is_array($integrations)) {
  89. throw new \UnexpectedValueException(sprintf('Expected the callback set for the "integrations" option to return a list of integrations. Got: "%s".', get_debug_type($integrations)));
  90. }
  91. }
  92. return $integrations;
  93. }
  94. /**
  95. * @return IntegrationInterface[]
  96. */
  97. private function getDefaultIntegrations(Options $options): array
  98. {
  99. if (!$options->hasDefaultIntegrations()) {
  100. return [];
  101. }
  102. $integrations = [
  103. new RequestIntegration(),
  104. new TransactionIntegration(),
  105. new FrameContextifierIntegration(),
  106. new EnvironmentIntegration(),
  107. new ModulesIntegration(),
  108. ];
  109. if (null !== $options->getDsn()) {
  110. array_unshift($integrations, new ExceptionListenerIntegration(), new ErrorListenerIntegration(), new FatalErrorListenerIntegration());
  111. }
  112. return $integrations;
  113. }
  114. }