Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for Livewire 3 #798

Merged
merged 14 commits into from
Nov 16, 2023
3 changes: 2 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,9 @@ jobs:
- name: Install Composer dependencies
run: |
# friendsofphp/php-cs-fixer: No need for this package to run phpunit and it conflicts with older Laravel versions
# livewire/livewire: Only supported on Laravel 7.0 and above
# laravel/folio: Only supported on PHP 8.1 + Laravel 10.0 and above
composer remove friendsofphp/php-cs-fixer laravel/folio --dev --no-interaction --no-update
composer remove friendsofphp/php-cs-fixer livewire/livewire laravel/folio --dev --no-interaction --no-update

# Require the correct versions we want to run phpunit for
composer require \
Expand Down
1 change: 1 addition & 0 deletions composer.json
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do this mostly for the types, so we can get autocomplete working and make phpstan a little happier without many exclusions.

Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"require-dev": {
"phpunit/phpunit": "^8.4 | ^9.3",
"laravel/framework": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0",
"livewire/livewire": "^2.0 | ^3.0",
"orchestra/testbench": "^4.7 | ^5.1 | ^6.0 | ^7.0 | ^8.0",
"friendsofphp/php-cs-fixer": "^3.11",
"mockery/mockery": "^1.3",
Expand Down
25 changes: 0 additions & 25 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -90,31 +90,6 @@ parameters:
count: 1
path: src/Sentry/Laravel/EventHandler.php

-
message: "#^Parameter \\$component of method Sentry\\\\Laravel\\\\Features\\\\LivewirePackageIntegration\\:\\:handleComponentBoot\\(\\) has invalid type Livewire\\\\Component\\.$#"
count: 1
path: src/Sentry/Laravel/Features/LivewirePackageIntegration.php

-
message: "#^Parameter \\$component of method Sentry\\\\Laravel\\\\Features\\\\LivewirePackageIntegration\\:\\:handleComponentBooted\\(\\) has invalid type Livewire\\\\Component\\.$#"
count: 1
path: src/Sentry/Laravel/Features/LivewirePackageIntegration.php

-
message: "#^Parameter \\$component of method Sentry\\\\Laravel\\\\Features\\\\LivewirePackageIntegration\\:\\:handleComponentDehydrate\\(\\) has invalid type Livewire\\\\Component\\.$#"
count: 1
path: src/Sentry/Laravel/Features/LivewirePackageIntegration.php

-
message: "#^Parameter \\$component of method Sentry\\\\Laravel\\\\Features\\\\LivewirePackageIntegration\\:\\:handleComponentMount\\(\\) has invalid type Livewire\\\\Component\\.$#"
count: 1
path: src/Sentry/Laravel/Features/LivewirePackageIntegration.php

-
message: "#^Parameter \\$livewireManager of method Sentry\\\\Laravel\\\\Features\\\\LivewirePackageIntegration\\:\\:onBoot\\(\\) has invalid type Livewire\\\\LivewireManager\\.$#"
count: 1
path: src/Sentry/Laravel/Features/LivewirePackageIntegration.php

-
message: "#^Parameter \\$request of method Sentry\\\\Laravel\\\\Features\\\\LivewirePackageIntegration\\:\\:handleComponentBooted\\(\\) has invalid type Livewire\\\\Request\\.$#"
count: 1
Expand Down
101 changes: 92 additions & 9 deletions src/Sentry/Laravel/Features/LivewirePackageIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
namespace Sentry\Laravel\Features;

use Livewire\Component;
use Livewire\EventBus;
use Livewire\LivewireManager;
use Livewire\Request;
use Sentry\Breadcrumb;
use Sentry\Laravel\Integration;
use Sentry\SentrySdk;
use Sentry\State\Scope;
use Sentry\Tracing\Span;
use Sentry\Tracing\SpanContext;
use Sentry\Tracing\TransactionSource;
Expand All @@ -16,8 +18,6 @@
{
private const FEATURE_KEY = 'livewire';

private const COMPONENT_SPAN_OP = 'ui.livewire.component';

/** @var array<Span> */
private $spanStack = [];

Expand All @@ -32,11 +32,56 @@
}

public function onBoot(LivewireManager $livewireManager): void
{
if (class_exists(EventBus::class)) {
cleptric marked this conversation as resolved.
Show resolved Hide resolved
$this->registerLivewireThreeEventListeners($livewireManager);

return;
}

$this->registerLivewireTwoEventListeners($livewireManager);
}

Check warning on line 43 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L42-L43

Added lines #L42 - L43 were not covered by tests

private function registerLivewireThreeEventListeners(LivewireManager $livewireManager): void
{
$livewireManager->listen('mount', function ($component, array $data) {
if ($this->isTracingFeatureEnabled(self::FEATURE_KEY)) {
$this->handleComponentBoot($component);

Check warning on line 49 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L48-L49

Added lines #L48 - L49 were not covered by tests
}

if ($this->isBreadcrumbFeatureEnabled(self::FEATURE_KEY)) {
$this->handleComponentMount($component, $data);

Check warning on line 53 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L52-L53

Added lines #L52 - L53 were not covered by tests
}
});

$livewireManager->listen('hydrate', function ($component, array $data) {
if ($this->isTracingFeatureEnabled(self::FEATURE_KEY)) {
$this->handleComponentBoot($component);

Check warning on line 59 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L58-L59

Added lines #L58 - L59 were not covered by tests
}

if ($this->isBreadcrumbFeatureEnabled(self::FEATURE_KEY)) {
$this->handleComponentHydrate($component, $data);

Check warning on line 63 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L62-L63

Added lines #L62 - L63 were not covered by tests
}
});

if ($this->isTracingFeatureEnabled(self::FEATURE_KEY)) {
$livewireManager->listen('dehydrate', [$this, 'handleComponentDehydrate']);
}

if ($this->isBreadcrumbFeatureEnabled(self::FEATURE_KEY)) {
$livewireManager->listen('call', [$this, 'handleComponentCall']);
}
}

Check warning on line 74 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L74

Added line #L74 was not covered by tests

private function registerLivewireTwoEventListeners(LivewireManager $livewireManager): void

Check warning on line 76 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L76

Added line #L76 was not covered by tests
{
$livewireManager->listen('component.booted', [$this, 'handleComponentBooted']);

if ($this->isTracingFeatureEnabled(self::FEATURE_KEY)) {
$livewireManager->listen('component.boot', [$this, 'handleComponentBoot']);
$livewireManager->listen('component.boot', function ($component) {
$this->handleComponentBoot($component);
});

Check warning on line 83 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L81-L83

Added lines #L81 - L83 were not covered by tests

$livewireManager->listen('component.dehydrate', [$this, 'handleComponentDehydrate']);
}

Expand All @@ -45,8 +90,23 @@
}
}

public function handleComponentBoot(Component $component): void
public function handleComponentCall(Component $component, string $method, array $data): void

Check warning on line 93 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L93

Added line #L93 was not covered by tests
{
Integration::addBreadcrumb(new Breadcrumb(
Breadcrumb::LEVEL_INFO,
Breadcrumb::TYPE_DEFAULT,
'livewire',
"Component call: {$component->getName()}::{$method}",
$data
));
}

Check warning on line 102 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L95-L102

Added lines #L95 - L102 were not covered by tests

public function handleComponentBoot(Component $component, ?string $method = null): void

Check warning on line 104 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L104

Added line #L104 was not covered by tests
{
if ($this->isLivewireRequest()) {
$this->updateTransactionName($component->getName());

Check warning on line 107 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L106-L107

Added lines #L106 - L107 were not covered by tests
}

$currentSpan = SentrySdk::getCurrentHub()->getSpan();

if ($currentSpan === null) {
Expand All @@ -56,8 +116,12 @@
$this->spanStack[] = $currentSpan;

$context = new SpanContext;
$context->setOp(self::COMPONENT_SPAN_OP);
$context->setDescription($component->getName());
$context->setOp('ui.livewire.component');
$context->setDescription(
empty($method)
? $component->getName()
: "{$component->getName()}::{$method}"
);

Check warning on line 124 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L119-L124

Added lines #L119 - L124 were not covered by tests

$componentSpan = $currentSpan->startChild($context);

Expand Down Expand Up @@ -92,10 +156,21 @@
}

if ($this->isTracingFeatureEnabled(self::FEATURE_KEY)) {
$this->updateTransactionName($component::getName());
$this->updateTransactionName($component->getName());

Check warning on line 159 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L159

Added line #L159 was not covered by tests
}
}

public function handleComponentHydrate(Component $component, array $data): void

Check warning on line 163 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L163

Added line #L163 was not covered by tests
{
Integration::addBreadcrumb(new Breadcrumb(
Breadcrumb::LEVEL_INFO,
Breadcrumb::TYPE_DEFAULT,
'livewire',
"Component hydrate: {$component->getName()}",
$data
));
}

Check warning on line 172 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L165-L172

Added lines #L165 - L172 were not covered by tests

public function handleComponentDehydrate(Component $component): void
{
$currentSpan = SentrySdk::getCurrentHub()->getSpan();
Expand All @@ -113,7 +188,9 @@

private function updateTransactionName(string $componentName): void
{
$transaction = SentrySdk::getCurrentHub()->getTransaction();
$hub = SentrySdk::getCurrentHub();

Check warning on line 191 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L191

Added line #L191 was not covered by tests

$transaction = $hub->getTransaction();

Check warning on line 193 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L193

Added line #L193 was not covered by tests

if ($transaction === null) {
return;
Expand All @@ -125,6 +202,12 @@
$transaction->getMetadata()->setSource(TransactionSource::custom());

Integration::setTransaction($transactionName);

$hub->configureScope(function (Scope $scope) {
$livewireManager = $this->container()->make(LivewireManager::class);

Check warning on line 207 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L206-L207

Added lines #L206 - L207 were not covered by tests

$scope->setTag('livewire.original_url', $livewireManager->originalUrl());
cleptric marked this conversation as resolved.
Show resolved Hide resolved
});

Check warning on line 210 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L209-L210

Added lines #L209 - L210 were not covered by tests
}

private function isLivewireRequest(): bool
Expand All @@ -137,7 +220,7 @@
return false;
}

return $request->header('x-livewire') === 'true';
return $request->hasHeader('x-livewire');

Check warning on line 223 in src/Sentry/Laravel/Features/LivewirePackageIntegration.php

View check run for this annotation

Codecov / codecov/patch

src/Sentry/Laravel/Features/LivewirePackageIntegration.php#L223

Added line #L223 was not covered by tests
} catch (\Throwable $e) {
// If the request cannot be resolved, it's probably not a Livewire request.
return false;
Expand Down