While studying for my Zend Framework certification, I tried to build a small application to test my knowledge. One of the tasks in that project was to try and build a slug filter which converts a particular string to slug, for example, 'My Test String' to 'my-test-string'. It also checks for slug duplication if you are storing it into database table but for that you need to provide model object and field name to the filter.
Following is the code for slug filter, you can put the class file anywhere you want but I put it in application/models as SlugFilter.php because that directory was already added in include path.
-
/**
-
* Slug filter
-
*
-
* Filter used to generate slug
-
*
-
* @copyright 2010 SANIsoft Technologies Pvt. Ltd.
-
* @link http://www.sanisoft.com/
-
*/
-
-
/**
-
* Slug filter
-
*
-
* Filter used to generate slug
-
*
-
* @copyright 2010 SANIsoft Technologies Pvt. Ltd.
-
* @version Release: 1.0
-
* @link http://www.sanisoft.com/
-
*/
-
class SlugFilter implements Zend_Filter_Interface
-
{
-
var $field;
-
-
var $model;
-
-
/**
-
* Class constructor
-
*
-
* @param array $parameters Parameters used to define field name and model object
-
*/
-
{
-
// If field name and model object are provided then store them in class variables
-
$this->field = $parameters['field'];
-
$this->model = $parameters['model'];
-
}
-
}
-
-
/**
-
* Method used to generate slug
-
*
-
* @param string $value String to generate its slug
-
*
-
* @return string Generated slug
-
*/
-
public function filter($value, $conditions = null)
-
{
-
// Lowercase the string
-
-
// Generate slug by removing unwanted (other than alphanumeric and dash [-]) characters from the string
-
-
// If field name and model object are provided then check for slug duplication
-
if ($this->field && $this->model) {
-
// Initialize variable used to store matching slugs for currently generated slug
-
-
// Need to append ' AND ' to existing conditions
-
if ($conditions) {
-
$conditions .= ' AND ';
-
}
-
-
// Build conditions for slug duplication
-
$conditions .= $this->field . ' LIKE "' . $value . '%"';
-
-
// Get matching slugs for currently generated slug
-
$select = $this->model->select();
-
->where($conditions);
-
-
// Store matching slugs for currently generated slug
-
foreach ($this->model->fetchAll($select) as $record) {
-
$slugs[] = $record->{$this->field};
-
}
-
-
// If matching slugs for currently generated slug then try to append -1, -2, ... to currently generated slug to avoid duplication
-
// Lets start duplication checking with index as 1
-
$index = 1;
-
-
// Check for slug duplication
-
while (true) {
-
// If currently generated slug is not duplicate then use it
-
$value .= '-' . $index;
-
break;
-
}
-
-
// Increment counter by 1
-
$index++;
-
}
-
}
-
}
-
-
// Return generated slug
-
return $value;
-
}
-
}
Well, how to use this filter? Let me show you below. I used it for categories, so the category add code was something like
-
// Categories model's object
-
$categories = new Categories();
-
-
// Slug filter's object
-
-
// Create empty row object
-
$row = $categories->createRow();
-
-
// Set category's name
-
$row->name = $form->getValue('name');
-
-
// Generate slug for category using its name
-
$row->slug = $slug->filter($form->getValue('name'));
-
-
// Add category
-
$row->save();
assuming categories database table had 'name' and 'slug' fields.
Usually slug once generated does not change, especially if it's being used in URLs. But if you still want to re-generate it while editing category then following code should do that
-
// Categories model's object
-
$categories = new Categories();
-
-
// Slug filter's object
-
-
// Category's id
-
$id = (int)$form->getValue('id');
-
-
// Get existing row object
-
$row = $categories->fetchRow('id = ' . $id);
-
-
// Set category's name
-
$row->name = $form->getValue('name');
-
-
// Re-generate slug for category using its name
-
$row->slug = $slug->filter($form->getValue('name'), 'id != ' . $id);
-
-
// Edit category
-
$row->save();
The difference between add and edit code? we provided condition for re-generating slug to avoid slug duplication.
That's it for now!!!
As usual, your suggestions and comments are most welcome
No comments yet.