Doctrine 1
  1. Doctrine 1
  2. DC-728

Updating slug in I18N behaviour yields non-unique slug

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.2.0, 1.2.1, 1.2.2
    • Fix Version/s: None
    • Component/s: I18n, Sluggable
    • Labels:
      None
    • Environment:
      Symfony 1.4.5
      Doctrine ORM

      Description

      There seems to be a bug in the way, doctrine tries to find a unique slug for a table that is I18N-enabled and has a slug in it.

      Following example:

      Problem:
        actAs:
          I18n:
            fields: [name]
            actAs:
              Sluggable: { fields: [name], uniqueBy: [lang, name], canUpdate: true }
        columns:
          name: { type: string(255), notnull: true }
      

      Now, if we insert a new entry, the slug get's created as expected. If we now insert another entry that would yield the same slug, the slug is made unique by adding the postfix as expected - all well so far.

      Now, if we try to update the entry with the slug with the postfix, what i think is an error happens (Excerpt from Sluggable.php, lib/Doctrine/Template/Listener/Sluggable.php):

       
      public function getUniqueSlug($record, $slugFromFields)
      ...
      if ($record->exists()) {
                  $identifier = $record->identifier();
                  $whereString .= ' AND r.' . implode(' != ? AND r.', $table->getIdentifierColumnNames()) . ' != ?';
                  $whereParams = array_merge($whereParams, array_values($identifier));
              }
      
              foreach ($this->_options['uniqueBy'] as $uniqueBy) {
                  if (is_null($record->$uniqueBy)) {
                      $whereString .= ' AND r.'.$uniqueBy.' IS NULL';
                  } else {
                      $whereString .= ' AND r.'.$uniqueBy.' = ?';
                      $value = $record->$uniqueBy;
                      if ($value instanceof Doctrine_Record) {
                          $value = current((array) $value->identifier());
                      }
                      $whereParams[] = $value;
                  }
              }
      ...
      

      So, the $record->exists() check evaluates to true and $table->getIdentifierColumnNames() yields the fields id and lang, so the whereString is something like

       
      AND r.id != ? AND r.lang != ?
      

      Now for the problematic part:
      uniqueBy is lang and name; so the code adds to the whereString:

       
      AND r.lang = ? AND r.name = ?
      

      So the resulting whereString has something like

       
      r.lang != ? AND r.lang = ?
      

      which will never yield a result in my eyes, thus, the postfix is never incremented and the slug defaults to the the slug of name without postfix.

        Activity

        Florian Aschenbrenner created issue -

          People

          • Assignee:
            Jonathan H. Wage
            Reporter:
            Florian Aschenbrenner
          • Votes:
            5 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated: