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

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 (self::$instance === null) {
  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. $installed = [];
  46. foreach ($this->getIntegrationsToSetup($options) as $integration) {
  47. $integrationName = \get_class($integration);
  48. $integrations[$integrationName] = $integration;
  49. if ($this->setupIntegration($integration, $options)) {
  50. $installed[] = $integrationName;
  51. }
  52. }
  53. if (\count($installed) > 0) {
  54. $logger->debug(\sprintf('The "%s" integration(s) have been installed.', implode(', ', $installed)));
  55. }
  56. return $integrations;
  57. }
  58. private function setupIntegration(IntegrationInterface $integration, Options $options): bool
  59. {
  60. $integrationName = \get_class($integration);
  61. if (isset($this->integrations[$integrationName])) {
  62. return false;
  63. }
  64. if ($integration instanceof OptionAwareIntegrationInterface) {
  65. $integration->setOptions($options);
  66. }
  67. $integration->setupOnce();
  68. $this->integrations[$integrationName] = true;
  69. return true;
  70. }
  71. /**
  72. * @return IntegrationInterface[]
  73. */
  74. private function getIntegrationsToSetup(Options $options): array
  75. {
  76. $integrations = [];
  77. $defaultIntegrations = $this->getDefaultIntegrations($options);
  78. $userIntegrations = $options->getIntegrations();
  79. if (\is_array($userIntegrations)) {
  80. $userIntegrationsClasses = array_map('get_class', $userIntegrations);
  81. $pickedIntegrationsClasses = [];
  82. foreach ($defaultIntegrations as $defaultIntegration) {
  83. $integrationClassName = \get_class($defaultIntegration);
  84. if (!\in_array($integrationClassName, $userIntegrationsClasses, true) && !isset($pickedIntegrationsClasses[$integrationClassName])) {
  85. $integrations[] = $defaultIntegration;
  86. $pickedIntegrationsClasses[$integrationClassName] = true;
  87. }
  88. }
  89. foreach ($userIntegrations as $userIntegration) {
  90. $integrationClassName = \get_class($userIntegration);
  91. if (!isset($pickedIntegrationsClasses[$integrationClassName])) {
  92. $integrations[] = $userIntegration;
  93. $pickedIntegrationsClasses[$integrationClassName] = true;
  94. }
  95. }
  96. } else {
  97. $integrations = $userIntegrations($defaultIntegrations);
  98. if (!\is_array($integrations)) {
  99. throw new \UnexpectedValueException(\sprintf('Expected the callback set for the "integrations" option to return a list of integrations. Got: "%s".', get_debug_type($integrations)));
  100. }
  101. }
  102. return $integrations;
  103. }
  104. /**
  105. * @return IntegrationInterface[]
  106. */
  107. private function getDefaultIntegrations(Options $options): array
  108. {
  109. if (!$options->hasDefaultIntegrations()) {
  110. return [];
  111. }
  112. $integrations = [
  113. new RequestIntegration(),
  114. new TransactionIntegration(),
  115. new FrameContextifierIntegration(),
  116. new EnvironmentIntegration(),
  117. new ModulesIntegration(),
  118. ];
  119. if ($options->getDsn() !== null || $options->isSpotlightEnabled()) {
  120. array_unshift($integrations, new ExceptionListenerIntegration(), new ErrorListenerIntegration(), new FatalErrorListenerIntegration());
  121. }
  122. return $integrations;
  123. }
  124. }