From 5a86fac95a044a1a0e2c61c80811e1aca97ff025 Mon Sep 17 00:00:00 2001
From: Luca Longo <l.longo@ambita.it>
Date: Mon, 28 Mar 2022 12:32:57 +0200
Subject: [PATCH 1/2] Skips the slug generation by a true callable

---
 src/HasSlug.php       |  8 ++++++++
 src/SlugOptions.php   |  9 +++++++++
 tests/HasSlugTest.php | 28 ++++++++++++++++++++++++++--
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/src/HasSlug.php b/src/HasSlug.php
index 5586c7a..6368f5b 100644
--- a/src/HasSlug.php
+++ b/src/HasSlug.php
@@ -27,6 +27,10 @@ protected function generateSlugOnCreate(): void
     {
         $this->slugOptions = $this->getSlugOptions();
 
+        if ($this->slugOptions->skipGenerate) {
+            return;
+        }
+
         if (! $this->slugOptions->generateSlugsOnCreate) {
             return;
         }
@@ -44,6 +48,10 @@ protected function generateSlugOnUpdate(): void
     {
         $this->slugOptions = $this->getSlugOptions();
 
+        if ($this->slugOptions->skipGenerate) {
+            return;
+        }
+
         if (! $this->slugOptions->generateSlugsOnUpdate) {
             return;
         }
diff --git a/src/SlugOptions.php b/src/SlugOptions.php
index a14d09c..a0b136d 100644
--- a/src/SlugOptions.php
+++ b/src/SlugOptions.php
@@ -16,6 +16,8 @@ class SlugOptions
 
     public int $maximumLength = 250;
 
+    public bool $skipGenerate = false;
+
     public bool $generateSlugsOnCreate = true;
 
     public bool $generateSlugsOnUpdate = true;
@@ -74,6 +76,13 @@ public function slugsShouldBeNoLongerThan(int $maximumLength): self
         return $this;
     }
 
+    public function skipGenerateWhen(callable $callable): self
+    {
+        $this->skipGenerate = $callable() === true;
+
+        return $this;
+    }
+
     public function doNotGenerateSlugsOnCreate(): self
     {
         $this->generateSlugsOnCreate = false;
diff --git a/tests/HasSlugTest.php b/tests/HasSlugTest.php
index 1244c34..250e2b0 100644
--- a/tests/HasSlugTest.php
+++ b/tests/HasSlugTest.php
@@ -156,8 +156,32 @@ public function getSlugOptions(): SlugOptions
     expect($model->url)->toEqual('this-is-an-other-1');
 });
 
+it('has a method that prevents a slug being generated on condition', function () {
+    $model = new class () extends TestModel {
+        public function getSlugOptions(): SlugOptions
+        {
+            return parent::getSlugOptions()
+                ->skipGenerateWhen(fn () => $this->name === 'Skip me');
+        }
+    };
+
+    $model->name = 'Skip me';
+    $model->save();
+
+    expect($model->url)->toBeNull();
+
+    $model->other_field = 'Spatie';
+    $model->save();
+
+    expect($model->url)->toBeNull();
+
+    $model->name = 'this is a test';
+    $model->save();
+
+    expect($model->url)->toEqual('this-is-a-test');
+});
 
-it('has an method that prevents a slug being generated on creation', function () {
+it('has a method that prevents a slug being generated on creation', function () {
     $model = new class () extends TestModel {
         public function getSlugOptions(): SlugOptions
         {
@@ -171,7 +195,7 @@ public function getSlugOptions(): SlugOptions
     expect($model->url)->toBeNull();
 });
 
-it('has an method that prevents a slug being generated on update', function () {
+it('has a method that prevents a slug being generated on update', function () {
     $model = new class () extends TestModel {
         public function getSlugOptions(): SlugOptions
         {

From 2cdb39f46a3a068d85ea93bd80573fbd8fca43b7 Mon Sep 17 00:00:00 2001
From: Luca Longo <l.longo@ambita.it>
Date: Mon, 28 Mar 2022 12:36:52 +0200
Subject: [PATCH 2/2] Update doc

---
 README.md             | 14 ++++++++++++++
 tests/HasSlugTest.php |  8 ++++----
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 4739c5f..d3148b0 100644
--- a/README.md
+++ b/README.md
@@ -212,6 +212,20 @@ $model->slug = 'my-custom-url';
 $model->save(); //slug is now "my-custom-url";
 ```
 
+## Prevents slugs from being generated on some conditions
+
+If you don't want to create the slug when the model has a state, you can use the `skipGenerateWhen` function.
+
+```php
+public function getSlugOptions() : SlugOptions
+{
+    return SlugOptions::create()
+        ->generateSlugsFrom('name')
+        ->saveSlugsTo('slug')
+        ->skipGenerateWhen(fn () => $this->state === 'draft');
+}
+```
+
 ### Prevent slugs from being generated on creation
 
 If you don't want to create the slug when the model is initially created you can set use the `doNotGenerateSlugsOnCreate()` function.
diff --git a/tests/HasSlugTest.php b/tests/HasSlugTest.php
index 250e2b0..d9b2377 100644
--- a/tests/HasSlugTest.php
+++ b/tests/HasSlugTest.php
@@ -161,11 +161,11 @@ public function getSlugOptions(): SlugOptions
         public function getSlugOptions(): SlugOptions
         {
             return parent::getSlugOptions()
-                ->skipGenerateWhen(fn () => $this->name === 'Skip me');
+                ->skipGenerateWhen(fn () => $this->name === 'draft');
         }
     };
 
-    $model->name = 'Skip me';
+    $model->name = 'draft';
     $model->save();
 
     expect($model->url)->toBeNull();
@@ -175,10 +175,10 @@ public function getSlugOptions(): SlugOptions
 
     expect($model->url)->toBeNull();
 
-    $model->name = 'this is a test';
+    $model->name = 'this is not a draft';
     $model->save();
 
-    expect($model->url)->toEqual('this-is-a-test');
+    expect($model->url)->toEqual('this-is-not-a-draft');
 });
 
 it('has a method that prevents a slug being generated on creation', function () {