src/Slug.php
public function onBeforeWrite()
    {
        $owner = $this->getOwner();
        $slugHasChanged = $owner->isChanged('URLSlug');
        $fieldToSlugHasChanged = $owner->isChanged($this->fieldToSlug);
        $updateSlug = (
            empty($owner->URLSlug)
            || ($this->enforceParity && $fieldToSlugHasChanged)
            || (!$this->enforceParity && $slugHasChanged)
        );

        if ($updateSlug) {
            $owner->URLSlug = $this->getSlug($this->enforceParity);

            $collisionList = DataObject::get(get_class($owner))->exclude('ID', $owner->ID);
            $filter = ['URLSlug' => $owner->URLSlug];
            if ($this->relationName) {
                $parentIDField = $this->relationName . 'ID';
                $filter[$parentIDField] = $owner->$parentIDField;
                // Also handle polymorphic relationships
                $parentClassName = DataObject::getSchema()->hasOneComponent(get_class($owner), $this->relationName);
                if ($parentClassName === DataObject::class) {
                    $parentClassField = $this->relationName . 'Class';
                    $filter[$parentClassField] = $owner->$parentClassField;
                }
            }

            $count = 1;
            while ($collisionList->filter($filter)->exists()) {
                $owner->URLSlug = $owner->URLSlug . $count++;
                $filter['URLSlug'] = $owner->URLSlug;
            }
        } elseif ($slugHasChanged) {
            // enforceParity is set, and the slug has changed... but the
            // field to slug has not. We need to reset to keep parity.
            // Ideally we could do this via the $original property through
            // {@see DataObject::getChangedFields}, however the returned
            // 'before' value for a changed field is unreliable :(
            // https://github.com/silverstripe/silverstripe-framework/issues/8443
            throw new UnexpectedValueException(
                'URLSlug has been updated independently of the tracked field, ' .
                'but this has been disabled via Slug::enforceParity'
            );
        }
    }
public function onBeforeWrite()
    {
        $owner = $this->getOwner();
        $slugHasChanged = $owner->isChanged('URLSlug');
        $fieldToSlugHasChanged = $owner->isChanged($this->fieldToSlug);
        $updateSlug = (
            empty($owner->URLSlug)
            || ($this->enforceParity && $fieldToSlugHasChanged)
            || (!$this->enforceParity && $slugHasChanged)
        );

        if ($updateSlug) {
            $owner->URLSlug = $this->getSlug($this->enforceParity);

            $collisionList = DataObject::get(get_class($owner))->exclude('ID', $owner->ID);
            $filter = ['URLSlug' => $owner->URLSlug];
            if ($this->relationName) {
                $parentIDField = $this->relationName . 'ID';
                $filter[$parentIDField] = $owner->$parentIDField;
                // Also handle polymorphic relationships
                $parentClassName = DataObject::getSchema()->hasOneComponent(get_class($owner), $this->relationName);
                if ($parentClassName === DataObject::class) {
                    $parentClassField = $this->relationName . 'Class';
                    $filter[$parentClassField] = $owner->$parentClassField;
                }
            }

            $count = 1;
            while ($collisionList->filter($filter)->exists()) {
                $owner->URLSlug = $owner->URLSlug . $count++;
                $filter['URLSlug'] = $owner->URLSlug;
            }
        } elseif ($slugHasChanged) {
            // enforceParity is set, and the slug has changed... but the
            // field to slug has not. We need to reset to keep parity.
            // Ideally we could do this via the $original property through
            // {@see DataObject::getChangedFields}, however the returned
            // 'before' value for a changed field is unreliable :(
            // https://github.com/silverstripe/silverstripe-framework/issues/8443
            throw new UnexpectedValueException(
                'URLSlug has been updated independently of the tracked field, ' .
                'but this has been disabled via Slug::enforceParity'
            );
        }
    }
Check for collisions, iff we need to update the slug and
upate the model with the confirmedsafe value before writing