<?php
App::import('Inflector');
class SluggableBehavior extends ModelBehavior {
var $__settings = array();
function setup(&$Model, $settings = array()) {
$default = array(
'fields' => array('title'),
'slugfield' => 'slug',
'separator' => '-',
'overwrite' => false,
'length' => 256,
'lower' => true
);
if(!isset($this->__settings[$Model->alias])) $this->__settings[$Model->alias] = $default;
$this->__settings[$Model->alias] = am($this->__settings[$Model->alias], ife(is_array($settings), $settings, array()));
}
function beforeSave(&$Model) {
$fields = $this->__settings[$Model->alias]['fields'];
$slugfield = $this->__settings[$Model->alias]['slugfield'];
if(!is_array($fields)) $fields = array($fields);
$hasFields = true;
foreach($fields as $field) {
if(!$Model->hasField($field)) $hasFields = false;
}
if($hasFields && $Model->hasField($slugfield) && ($this->__settings[$Model->alias]['overwrite'] || empty($Model->id))) {
$toslug = array();
foreach($fields as $field) $toslug[] = $Model->data[$Model->alias][$field];
$toslug = join(' ', $toslug);
$slug = Inflector::slug($toslug, $this->__settings[$Model->alias]['separator']);
if($this->__settings[$Model->alias]['lower']) $slug = strtolower($slug);
if(strlen($slug) > $this->__settings[$Model->alias]['length']) $slug = substr($slug, 0, $this->__settings[$Model->alias]['length']);
$conditions = array($Model->alias . '.' . $slugfield . ' LIKE' => $slug . '%');
if(!empty($Model->id)) $conditions[$Model->alias . '.' . $Model->primaryKey . ' !='] = $Model->id;
$sameUrls = $Model->find('all', array(
'recursive' => -1,
'conditions' => $conditions
));
$sameUrls = (!empty($sameUrls)) ?
Set::extract($sameUrls, '{n}.' . $Model->alias . '.' . $slugfield) :
null;
if($sameUrls) {
if(in_array($slug, $sameUrls)) {
$begginingSlug = $slug;
$index = 1;
while($index > 0) {
if(!in_array($begginingSlug . $this->__settings[$Model->alias]['separator'] . $index, $sameUrls)) {
$slug = $begginingSlug . $this->__settings[$Model->alias]['separator'] . $index;
$index = -1;
}
$index++;
}
}
}
if(!empty($Model->whitelist) && !in_array($slugfield, $Model->whitelist)) $Model->whitelist[] = $slugfield;
$Model->data[$Model->alias][$slugfield] = $slug;
}
return parent::beforeSave($Model);
}
}
?>