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

Generate slug from the same field if explicitly modified #610

Open
artrz opened this issue Apr 12, 2024 · 2 comments
Open

Generate slug from the same field if explicitly modified #610

artrz opened this issue Apr 12, 2024 · 2 comments

Comments

@artrz
Copy link
Contributor

artrz commented Apr 12, 2024

In some cases it is useful to be able to generate the slug from the same field. Let's say I have a form where I set a title and optionally the slug. If the slug is sent it's still important to process it to make sure there are no funky chars, it is unique, etc.

This could be implemented it by adding a new config setting like honorSelf (false as default) and update SlugService::buildSlug() to generate the slug from the $attribute. Something along the next lines:

    public function buildSlug(string $attribute, array $config, bool $force = null): ?string
    {
        $slug = $this->model->getAttribute($attribute);

        if ($config['honorSelf'] && $slug && $this->model->isDirty($attribute)) {
            return $this->obtainSlug($slug, $config, $attribute);
        }

        if ($force || $this->needsSlugging($attribute, $config)) {
            $source = $this->getSlugSource($config['source']);

            if ($source || is_numeric($source)) {
                $slug = $this->obtainSlug($source, $config, $attribute);
            }
        }

        return $slug;
    }

    // ...

    protected function obtainSlug(string $source, array $config, string $attribute): string
    {
        $slug = $this->generateSlug($source, $config, $attribute);
        $slug = $this->validateSlug($slug, $config, $attribute);
        $slug = $this->makeSlugUnique($slug, $config, $attribute);

        return $slug;
    }

I'm not sure about collateral effects. If there's interest into this, I could dig deeper.

@cviebrock
Copy link
Owner

I'm not sure I fully understand the use-case here.

If you have a form where you can optionally provide a slug, then you can handle funky characters, uniqueness, etc. with form validation, I would think.

@artrz
Copy link
Contributor Author

artrz commented Apr 17, 2024

Yes, front side validation is always desirable even when it can be bypassed. Still, slugs should always be generated as near as possible to the persisting action for the best match at least in my case. E.g. user A fills the slug field with 'x' on his form, user B fills the slug field with 'x' and sends the form, user A sends his form. Maybe user A sends his form first but has higher network latency. Maybe an API endpoint is being used where it's not possible to rely on the 3rd party validation implementation.

Not a deal breaker, a couple of years ago I solved this by extending the trait iirc, and in my latest implementation I ended up skipping the observer reactivity by returning an empty sluggableEvent (would be cool to have a SluggableObserver::NONE) and manually calling SlugService::createSlug(). For another project I might extend SlugService and bind my custom class with the code in OP to see how it goes. Btw, in SlugService::createSlug() seems that the is_array() check is not really neaded as the agument is typehinted. Also, I'm not sure that requiring a config for the attribute should be obligatory when using this method as the source is explicitly sent.

Feel free to close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants