Changeset 4066

Show
Ignore:
Timestamp:
03/21/08 04:41:59 (16 months ago)
Author:
jwage
Message:

fixes #900

Location:
branches/0.10
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • branches/0.10/lib/Doctrine/Template/Listener/Sluggable.php

    r3964 r4066  
    5353    } 
    5454 
     55    /** 
     56     * preInsert 
     57     * 
     58     * @param Doctrine_Event $event  
     59     * @return void 
     60     */ 
    5561    public function preInsert(Doctrine_Event $event) 
    5662    { 
     
    5965        $record = $event->getInvoker(); 
    6066 
    61         if ( ! $record->$name) { 
    62             $record->$name = $this->buildSlug($record); 
     67        $record->$name = $this->buildSlug($record); 
     68    } 
     69 
     70    /** 
     71     * preUpdate 
     72     * 
     73     * @param Doctrine_Event $event  
     74     * @return void 
     75     */ 
     76    public function preUpdate(Doctrine_Event $event) 
     77    { 
     78        if (false !== $this->_options['unique']) { 
     79            $name = $this->_options['name']; 
     80     
     81            $record = $event->getInvoker(); 
     82     
     83            $record->$name = $this->buildSlug($record);         
    6384        } 
    6485    } 
    6586 
     87    /** 
     88     * buildSlug 
     89     * 
     90     * Generate the slug for a given Doctrine_Record 
     91     * 
     92     * @param Doctrine_Record $record  
     93     * @return string $slug 
     94     */ 
    6695    protected function buildSlug($record) 
    6796    { 
    6897        if (empty($this->_options['fields'])) { 
    69             $value = (string) $record; 
     98            if (method_exists($record, 'getUniqueSlug')) { 
     99                $value = $record->getUniqueSlug($record); 
     100            } else { 
     101                $value = (string) $record; 
     102            } 
    70103        } else { 
    71             $value = ''; 
    72             foreach ($this->_options['fields'] as $field) { 
    73                 $value .= $record->$field . ' '; 
     104            if ($this->_options['unique'] === true) {    
     105                $value = $this->getUniqueSlug($record); 
     106            } else {   
     107                $value = ''; 
     108                foreach ($this->_options['fields'] as $field) { 
     109                    $value .= $record->$field . ' '; 
     110                }  
     111            } 
     112 
     113            $value =  Doctrine_Inflector::urlize($value); 
     114        } 
     115 
     116        return $value; 
     117    } 
     118 
     119    /** 
     120     * getUniqueSlug 
     121     * 
     122     * Creates a unique slug for a given Doctrine_Record. This function enforces the uniqueness by incrementing 
     123     * the values with a postfix if the slug is not unique 
     124     * 
     125     * @param Doctrine_Record $record  
     126     * @return string $slug 
     127     */ 
     128    public function getUniqueSlug($record) 
     129    { 
     130        $name = $this->_options['name']; 
     131        $slugFromFields = ''; 
     132        foreach ($this->_options['fields'] as $field) { 
     133            $slugFromFields .= $record->$field . ' '; 
     134        } 
     135 
     136        $proposal = $record->$name ? $record->$name : $slugFromFields; 
     137        $proposal =  Doctrine_Inflector::urlize($proposal); 
     138        $slug = $proposal; 
     139        $record_id = $record->id ? $record->id : 0; 
     140 
     141        $whereString = 'r.'.$name.' LIKE ? AND r.id <> ?'; 
     142        $whereParams = array($proposal.'%', $record_id); 
     143        foreach ($this->_options['uniqueBy'] as $uniqueBy) { 
     144            if (is_null($record->$uniqueBy)) { 
     145                $whereString .= ' AND r.'.$uniqueBy.' IS NULL'; 
     146            } else { 
     147                $whereString .= ' AND r.'.$uniqueBy.' = ?'; 
     148                $whereParams[] =  $record->$uniqueBy; 
    74149            } 
    75150        } 
    76151 
    77         return Doctrine_Inflector::urlize($value); 
     152        $similarSlugResult = Doctrine_Query::create() 
     153        ->select('r.'.$name) 
     154        ->from(get_class($record).' r') 
     155        ->where($whereString , $whereParams) 
     156        ->setHydrationMode(Doctrine::HYDRATE_ARRAY) 
     157        ->execute(); 
     158 
     159        $similarSlugs = array(); 
     160        foreach ($similarSlugResult as $key => $value) { 
     161            $similarSlugs[$key] = $value[$name]; 
     162        } 
     163 
     164        $i = 1; 
     165        while (in_array($slug, $similarSlugs)) { 
     166            $slug = $proposal.'-'.$i; 
     167            $i++; 
     168        } 
     169 
     170        return  $slug; 
    78171    } 
    79172} 
  • branches/0.10/lib/Doctrine/Template/Sluggable.php

    r3884 r4066  
    4040     * @var string 
    4141     */ 
    42     protected $_options = array('name'    =>  'slug', 
    43                                 'type'    =>  'clob', 
    44                                 'length'  =>  null, 
    45                                 'options' =>  array(), 
    46                                 'fields'  =>  array()); 
     42    protected $_options = array('name'       =>  'slug', 
     43                                'type'       =>  'clob', 
     44                                'length'     =>  null, 
     45                                'unique'     =>  true, 
     46                                'options'    =>  array(), 
     47                                'fields'     =>  array(), 
     48                                'uniqueBy'   =>  array(), 
     49                                'uniqueIndex'=>  true 
     50    ); 
    4751 
    4852    /** 
     
    6569    { 
    6670        $this->hasColumn($this->_options['name'], $this->_options['type'], $this->_options['length'], $this->_options['options']); 
     71         
     72        if ($this->_options['unique'] == true && $this->_options['uniqueIndex'] == true && !empty($this->_options['fields'])) { 
     73            $indexFields = array($this->_options['name']); 
     74            foreach ($this->_options['uniqueBy'] as $field) { 
     75                $indexFields[] = $field; 
     76            } 
     77            $this->index('sluggable', array('fields' => $indexFields, 
     78                                            'type' => 'unique'                 
     79            )); 
     80        } 
    6781 
    6882        $this->addListener(new Doctrine_Template_Listener_Sluggable($this->_options)); 
  • branches/0.10/tests/run.php

    r4065 r4066  
    179179$behaviors->addTestCase(new Doctrine_Hook_TestCase()); 
    180180$behaviors->addTestCase(new Doctrine_I18n_TestCase()); 
     181$behaviors->addTestCase(new Doctrine_Sluggable_TestCase()); 
    181182$test->addTestCase($behaviors); 
    182183