zachflower/ignorable-observers
composer require zachflower/ignorable-observers
IgnorableObservers in your Eloquent model:
use IgnorableObservers\IgnorableObservers;
class User extends Model {
use IgnorableObservers;
}
User::ignoreObservableEvents(); // Disables all observers
User::createMany($users); // No observers triggered
User::resumeObservableEvents(); // Re-enables observers
ignoreObservableEvents(), resumeObservableEvents(), and ignoreObservableEventsFor() (for selective disabling).ignoreObservableEventsForThread() for async/queue operations.isIgnoringObservableEvents() to verify state in tests.Bulk Operations:
User::ignoreObservableEvents();
try {
User::insert($batchData);
// No emails, notifications, or queued jobs triggered
} finally {
User::resumeObservableEvents();
}
Selective Observer Disabling:
User::ignoreObservableEventsFor([UserObserver::class]);
// Only UserObserver is ignored; other observers run normally
Thread-Specific Ignoring (for queues/jobs):
User::ignoreObservableEventsForThread();
// Observers ignored only in this thread
Conditional Disabling (e.g., in API routes):
if ($request->hasHeader('X-Ignore-Observers')) {
User::ignoreObservableEvents();
}
resumeObservableEvents() is always called.isIgnoringObservableEvents() in tests to assert observer behavior:
$this->assertTrue(User::isIgnoringObservableEvents());
Forgetting to Resume:
resumeObservableEvents() is omitted. Use try-finally blocks or service wrappers.function withIgnoredObservers(callable $callback) {
User::ignoreObservableEvents();
try {
$callback();
} finally {
User::resumeObservableEvents();
}
}
Thread Leaks:
ignoreObservableEventsForThread() only affects the current thread. Queued jobs may not inherit the state.ignoreObservableEventsForThread() in job constructors if needed.Observer Registration Timing:
ignoreObservableEvents() is called, or they won’t be ignored.boot() method.Static Method Limitation:
\Log::debug('Observers ignored?', [User::isIgnoringObservableEvents()]);
public function creating(Model $model) {
\Log::debug('Creating observer triggered?', [$model->exists]);
}
Custom Ignore Logic:
Override the trait’s ignoreObservableEvents() to add conditions:
public static function ignoreObservableEvents() {
if (!app()->environment('production')) {
return; // Skip in non-prod
}
parent::ignoreObservableEvents();
}
Global Toggle: Create a singleton service to manage global observer states across models:
class ObserverManager {
protected static $globalIgnore = false;
public static function ignoreGlobally() {
self::$globalIgnore = true;
}
}
Then modify the trait to respect this flag.
Observer Whitelisting: Extend the trait to allow whitelisting observers instead of blacklisting:
public static function ignoreAllBut(array $observers) {
// Implementation...
}
How can I help you explore Laravel packages today?