gdfgdfg
gdfgdfg

Reputation: 3566

Generate unique slug Codeigniter 3 && MySQL

I need to generate unique slug based on user input with this code:

public function create_slug($id, $name){

    $count = null;
    $name = url_title($name);
    while(true) {
        $this->db->select('id');
        $this->db->where('id !=', $id);
        $this->db->where('slug', $name);
        $query = $this->db->get('users');
        if ($query->num_rows() == 0) {
            break;
        } else {
            $name .= '-' . (++$count);
        }
    }
    return $name;
}

It select everything that mach the slug ($name), except its own slug. The result for first user input - 123 is slug - 123. For second same input the slug is 123-1, but third input with same text is with result 123-1-2, which is not what I want.

I tried another way :

public function create_slug($id, $name){
    $count = null;
    $name = url_title($name);
    $this->db->select('id');
    $this->db->where('id !=', $id);
    $this->db->where('slug', $name);

    $query = $this->db->get('users');

    if($query->num_rows()){
        $count = '-' . ($query->num_rows() + 1);
    }
    return $name . $count;
}

Here, is same query, but count rows + 1. For first 123 the slug is 123; Second 123, slug 123-2; Third 123, slug again 123-2, which is not unique.

How can I create slug that is based on some user input and is unique and, if there is slug with value name, next will be name-1, if again, next will be name-2 and etc. ?

Upvotes: 2

Views: 2851

Answers (1)

PaulD
PaulD

Reputation: 1171

You need to create a temp slug_name based on the original name, and test the slug_name. On fail, recreate new slug_name based on original name. On success (breaking out of the loop) return the amended slug_name.

public function create_slug($id, $name)
{
    $count = 0;
    $name = url_title($name);
    $slug_name = $name;             // Create temp name
    while(true) 
    {
        $this->db->select('id');
        $this->db->where('id !=', $id);
        $this->db->where('slug', $slug_name);   // Test temp name
        $query = $this->db->get('users');
        if ($query->num_rows() == 0) break;
        $slug_name = $name . '-' . (++$count);  // Recreate new temp name
    }
    return $slug_name;      // Return temp name
}

Or like this using count_all_results. Removed your id check as well as I presume the slug needs to be unique for the entire table.

public function create_slug($id, $name)
{
    $count = 0;
    $slug_name = $name = url_title($name);
    while(true) 
    {
        $this->db->from('users')->where('slug', $slug_name);
        if ($this->db->count_all_results() > 0) break;
        $slug_name = $name . '-' . (++$count);
    }
    return $slug_name;
}

Upvotes: 2

Related Questions