PHPackages                             akaunting/laravel-mutable-observer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. akaunting/laravel-mutable-observer

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

akaunting/laravel-mutable-observer
==================================

Mutable observer package for Laravel

3.0.0(6mo ago)11194.9k↑18.9%5[1 issues](https://github.com/akaunting/laravel-mutable-observer/issues)[2 PRs](https://github.com/akaunting/laravel-mutable-observer/pulls)MITPHPPHP ^8.0|^8.1|^8.2|^8.3|^8.4CI passing

Since Feb 23Pushed 3w ago4 watchersCompare

[ Source](https://github.com/akaunting/laravel-mutable-observer)[ Packagist](https://packagist.org/packages/akaunting/laravel-mutable-observer)[ RSS](/packages/akaunting-laravel-mutable-observer/feed)WikiDiscussions master Synced 4d ago

READMEChangelog (4)Dependencies (7)Versions (9)Used By (0)

Mutable Observer Package for Laravel
====================================

[](#mutable-observer-package-for-laravel)

[![Latest Version on Packagist](https://camo.githubusercontent.com/677182ef8d5ebb014806e58a21955ee2d1b160a6d4305e8e8ab9fa9ba4e74407/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616b61756e74696e672f6c61726176656c2d6d757461626c652d6f627365727665722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akaunting/laravel-mutable-observer)[![Total Downloads](https://camo.githubusercontent.com/0dda2795628c1662e793b727a22436168e9f5ebf80a2e8f956ade9720f893764/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616b61756e74696e672f6c61726176656c2d6d757461626c652d6f627365727665722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akaunting/laravel-mutable-observer)[![Tests](https://camo.githubusercontent.com/2aaf3f45ff2b28156f98185c6ef91a7797c383dc820478944a1a2c06e02ee7a4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f616b61756e74696e672f6c61726176656c2d6d757461626c652d6f627365727665722f74657374732e796d6c3f6272616e63683d6d6173746572266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/akaunting/laravel-mutable-observer/actions/workflows/tests.yml)[![Code Quality](https://camo.githubusercontent.com/70ba7c461b79fcfa219d58fbf3f9848a972172f0b361e58c45687495cf5ef2bd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f616b61756e74696e672f6c61726176656c2d6d757461626c652d6f627365727665722f74657374732e796d6c3f6272616e63683d6d6173746572266c6162656c3d636f64652532307175616c697479267374796c653d666c61742d737175617265)](https://github.com/akaunting/laravel-mutable-observer/actions/workflows/tests.yml)[![codecov](https://camo.githubusercontent.com/b84443fd691135d21a47fc90f237e213481bdd63bdc3bc0ed016ff7412950e29/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f616b61756e74696e672f6c61726176656c2d6d757461626c652d6f627365727665723f7374796c653d666c61742d737175617265)](https://codecov.io/gh/akaunting/laravel-mutable-observer)[![StyleCI](https://camo.githubusercontent.com/e50562b0cf69370fbef6e7ebd5f1ed8a835f2ba462037b5a9cd8674d552a4436/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3436323439323030312f736869656c643f7374796c653d666c61742d737175617265)](https://styleci.io/repos/462492001)[![PHPStan Level](https://camo.githubusercontent.com/cfad767368c5b88c30d3a7087a14099cb45895b5ded11e2ae54aa298b7ba5893/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c2532306d61782d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](phpstan.neon)[![Psalm Type Coverage](https://camo.githubusercontent.com/7b67ac09c8306474eeab47c8e19d92fc2fb240b2a2e1fecaca33d863d5fd6607/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5073616c6d2d6c6576656c253230312d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](psalm.xml)[![License](https://camo.githubusercontent.com/6e93e2de34b9090833b303a00e7a66ade1f2b952490a3c9972be366eff2261d4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f616b61756e74696e672f6c61726176656c2d6d757461626c652d6f627365727665723f7374796c653d666c61742d737175617265)](LICENSE.md)

This package allows you to `mute` and `unmute` specific observer events at will. It ships with a trait that adds mutable methods to your observer classes, making it perfect for testing scenarios and preventing unwanted side effects.

Features
--------

[](#features)

- ✅ **Mute specific events** - Target individual observer methods
- ✅ **Mute all events** - Silence entire observers with a single call
- ✅ **Framework integration** - Seamlessly works with Laravel's observer system
- ✅ **Laravel 9-12 support** - Compatible with all modern Laravel versions
- ✅ **PHP 8.0-8.4 support** - Uses modern PHP features like readonly properties
- ✅ **Type-safe** - Full type declarations for better IDE support
- ✅ **Zero dependencies** - Only requires Laravel framework
- ✅ **Well tested** - Comprehensive test coverage

Installation
------------

[](#installation)

Run the following command:

```
composer require akaunting/laravel-mutable-observer
```

Usage
-----

[](#usage)

### Basic Setup

[](#basic-setup)

Add the `Mutable` trait to your observer class:

```
namespace App\Observers;

use Akaunting\MutableObserver\Traits\Mutable;

class UserObserver
{
    use Mutable;

    public function creating($user)
    {
        // Send welcome email
        Mail::to($user->email)->send(new WelcomeEmail($user));
    }

    public function created($user)
    {
        // Log user creation
        Log::info("User created: {$user->email}");
    }

    public function updating($user)
    {
        // Validate changes
        // ...
    }
}
```

### Muting All Events

[](#muting-all-events)

Perfect for testing scenarios where you want to disable all observer actions:

```
UserObserver::mute();

// Create users without triggering any observer events
$user = User::create([
    'name' => 'John Doe',
    'email' => 'john@example.com',
]);
// No emails sent, no logs created

UserObserver::unmute();
```

### Muting Specific Events

[](#muting-specific-events)

Target individual observer methods while keeping others active:

```
// Mute only the creating event (no welcome emails)
UserObserver::mute('creating');

$user = User::create(['name' => 'Jane Doe']);
// Creating event is muted, but created event still fires
```

### Muting Multiple Events

[](#muting-multiple-events)

```
// Mute multiple specific events
UserObserver::mute(['creating', 'updating']);

$user = User::create(['name' => 'Test User']);
$user->update(['name' => 'Updated Name']);
// Both creating and updating events are muted

UserObserver::unmute();
```

### Real-World Examples

[](#real-world-examples)

#### Testing Scenario

[](#testing-scenario)

```
use Tests\TestCase;

class UserTest extends TestCase
{
    public function test_user_can_be_created_without_side_effects()
    {
        // Prevent emails and logs during testing
        UserObserver::mute();

        $user = User::factory()->create();

        $this->assertDatabaseHas('users', [
            'email' => $user->email,
        ]);

        UserObserver::unmute();
    }

    public function test_only_email_is_muted()
    {
        // Mute only email sending, keep logging
        UserObserver::mute('creating');

        Log::shouldReceive('info')->once();

        $user = User::factory()->create();
        // Email not sent, but log was created

        UserObserver::unmute();
    }
}
```

#### Bulk Operations

[](#bulk-operations)

```
// Disable observer for bulk operations
UserObserver::mute();

User::insert([
    ['name' => 'User 1', 'email' => 'user1@example.com'],
    ['name' => 'User 2', 'email' => 'user2@example.com'],
    ['name' => 'User 3', 'email' => 'user3@example.com'],
]);
// No observers triggered, much faster

UserObserver::unmute();
```

#### Conditional Muting

[](#conditional-muting)

```
use Illuminate\Support\Facades\App;

// Mute observers in specific environments
if (App::environment('testing')) {
    UserObserver::mute();
}

// Or use it for specific operations
$shouldNotify = false;

if (!$shouldNotify) {
    UserObserver::mute('creating');
}

$user = User::create($data);

if (!$shouldNotify) {
    UserObserver::unmute();
}
```

#### Using Constants

[](#using-constants)

```
use Akaunting\MutableObserver\Traits\Mutable;

// Use the built-in wildcard constant
UserObserver::mute(Mutable::WILDCARD_EVENT); // Same as mute()
```

API Reference
-------------

[](#api-reference)

### `Mutable::mute($events = null)`

[](#mutablemuteevents--null)

Mutes the specified observer events.

**Parameters:**

- `$events` (string|array|null) - The events to mute. Pass `null` or no arguments to mute all events.

**Returns:** void

**Examples:**

```
UserObserver::mute();                    // Mute all events
UserObserver::mute('created');           // Mute single event
UserObserver::mute(['created', 'updated']); // Mute multiple events
```

### `Mutable::unmute()`

[](#mutableunmute)

Unmutes all previously muted observer events.

**Returns:** void

**Example:**

```
UserObserver::unmute(); // Restore all observer functionality
```

### `Mutable::WILDCARD_EVENT`

[](#mutablewildcard_event)

A constant representing the wildcard event that mutes all observer methods.

**Value:** `'*'`

Requirements
------------

[](#requirements)

- PHP 8.0 or higher
- Laravel 9.0 or higher

Code Quality
------------

[](#code-quality)

This package maintains the highest code quality standards:

- ✅ **PHPStan Level Max** - Maximum static analysis level
- ✅ **Psalm Level 1** - Strictest type checking
- ✅ **PHP CS Fixer** - PSR-12 compliant code style
- ✅ **Infection** - Mutation testing with 90%+ MSI
- ✅ **100% Test Coverage** - Comprehensive test suite
- ✅ **Strict Types** - All files use `declare(strict_types=1)`

### Running Quality Checks

[](#running-quality-checks)

```
# Run all quality checks
composer quality

# Individual checks
composer test              # Run tests
composer test:coverage     # Run tests with coverage report
composer analyse           # Run PHPStan + Psalm
composer phpstan           # Run PHPStan only
composer psalm             # Run Psalm only
composer format            # Fix code style issues
composer format:check      # Check code style without fixing
composer infection         # Run mutation testing

# Using Makefile (Unix/Mac/WSL)
make quality              # Run all quality checks
make test                 # Run tests
make analyse              # Run static analysis
make format               # Fix code style
make help                 # Show all available commands
```

How It Works
------------

[](#how-it-works)

The package uses a proxy pattern to intercept calls to your observer methods. When you call `mute()`, it registers a proxy in Laravel's service container that swallows the specified events. When you call `unmute()`, it removes the proxy and restores normal observer functionality.

Best Practices
--------------

[](#best-practices)

1. **Always unmute after muting** - Especially in tests, use try-finally blocks:

    ```
    try {
        UserObserver::mute();
        // Your code here
    } finally {
        UserObserver::unmute();
    }
    ```
2. **Use setUp and tearDown in tests**:

    ```
    protected function setUp(): void
    {
        parent::setUp();
        UserObserver::mute();
    }

    protected function tearDown(): void
    {
        UserObserver::unmute();
        parent::tearDown();
    }
    ```
3. **Be specific when possible** - Mute only the events you need to disable:

    ```
    UserObserver::mute('creating'); // Better than mute()
    ```
4. **Document muted events** - Add comments explaining why observers are muted:

    ```
    // Mute email notifications during bulk import
    UserObserver::mute('created');
    ```

Troubleshooting
---------------

[](#troubleshooting)

**Q: Observer still firing after muting?**
A: Make sure the observer is registered through Laravel's observer system and the trait is properly imported.

**Q: Can I mute observers globally?**
A: Yes, mute them in a service provider's `boot()` method or middleware.

**Q: Does this work with model events?**
A: Yes, it works with any observer registered via `Model::observe()`.

Changelog
---------

[](#changelog)

Please see [Releases](../../releases) for more information what has changed recently.

Contributing
------------

[](#contributing)

Pull requests are more than welcome. You must follow the PSR coding standards.

Security
--------

[](#security)

Please review [our security policy](https://github.com/akaunting/laravel-sortable/security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Cüneyt Şentürk](https://github.com/cuneytsenturk)
- [Denis Duliçi](https://github.com/denisdulici)
- [Stephen Lewis](https://github.com/monooso)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [LICENSE](LICENSE.md) for more information.

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance80

Actively maintained with recent releases

Popularity42

Moderate usage in the ecosystem

Community16

Small or concentrated contributor base

Maturity72

Established project with proven stability

 Bus Factor1

Top contributor holds 50% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~464 days

Total

4

Last Release

201d ago

Major Versions

1.0.0 → 2.0.02023-03-07

2.0.1 → 3.0.02025-12-16

PHP version history (3 changes)1.0.0PHP &gt;=8.0

2.0.0PHP ^8.0

3.0.0PHP ^8.0|^8.1|^8.2|^8.3|^8.4

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5254835?v=4)[Denis Dulici](/maintainers/denisdulici)[@denisdulici](https://github.com/denisdulici)

![](https://avatars.githubusercontent.com/u/10936547?v=4)[Cüneyt Şentürk](/maintainers/cuneytsenturk)[@cuneytsenturk](https://github.com/cuneytsenturk)

---

Top Contributors

[![denisdulici](https://avatars.githubusercontent.com/u/5254835?v=4)](https://github.com/denisdulici "denisdulici (8 commits)")[![cuneytsenturk](https://avatars.githubusercontent.com/u/10936547?v=4)](https://github.com/cuneytsenturk "cuneytsenturk (5 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")

---

Tags

laravelmuteobserverphptraitlaravelobservermutablemuteunmute

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/akaunting-laravel-mutable-observer/health.svg)

```
[![Health](https://phpackages.com/badges/akaunting-laravel-mutable-observer/health.svg)](https://phpackages.com/packages/akaunting-laravel-mutable-observer)
```

###  Alternatives

[grumpydictator/firefly-iii

Firefly III: a personal finances manager.

23.9k69.5k](/packages/grumpydictator-firefly-iii)[firefly-iii/data-importer

Firefly III Data Import Tool.

8035.8k](/packages/firefly-iii-data-importer)[markwalet/nova-modal-response

A Laravel Nova asset for Modal responses on an action.

17878.9k](/packages/markwalet-nova-modal-response)[ronasit/laravel-helpers

Provided helpers function and some helper class.

2085.6k31](/packages/ronasit-laravel-helpers)[team-nifty-gmbh/tall-datatables

Server-side rendered datatables for Laravel and Livewire

1320.9k4](/packages/team-nifty-gmbh-tall-datatables)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.4k](/packages/tomshaw-electricgrid)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
