Skip to content

Instantly share code, notes, and snippets.

@jonom
Created January 30, 2020 19:23
Show Gist options
  • Save jonom/1d51c6f84700a9ca285178c5c4c6e47a to your computer and use it in GitHub Desktop.
Save jonom/1d51c6f84700a9ca285178c5c4c6e47a to your computer and use it in GitHub Desktop.
Unique URL Segment extension
<?php
class UniqueURLSegmentExtension extends DataExtension
{
private static $db = array(
'URLSegment' => 'Varchar(255)',
);
public function onBeforeWrite()
{
// If there is no URLSegment set, generate one from Title
if (!$this->owner->URLSegment) {
$this->owner->URLSegment = $this->generateURLSegment($this->owner->getTitle());
}
// validate segment or create default
if (!$this->owner->isInDB() || $this->owner->isChanged('URLSegment')) {
$this->owner->URLSegment = $this->generateURLSegment($this->owner->URLSegment);
$this->makeURLSegmentUnique();
}
}
/**
* Check if there is already a piece of content of this type with this URLSegment.
* Override this method for more nuanced logic.
*/
public function URLSegmentInUse($URLSegment)
{
$class = $this->ownerBaseClass;
$items = $class::get()->filter('URLSegment', $URLSegment);
// Exclude this item if already written
if ($this->owner->ID > 0) {
$items = $items->exclude('ID', $ID);
}
return $items->exists();
}
/**
* Generate a URL segment based on the title provided.
*
* @param string $title
*
* @return string Generated url segment
*/
public function generateURLSegment($title)
{
$filter = URLSegmentFilter::create();
$t = $filter->filter($title);
// Fallback to generic page name if path is empty (= no valid, convertable characters)
if (!$t || $t == '-' || $t == '-1') {
$class = strtolower($this->owner->ClassName);
$t = "$class-$this->owner->ID";
}
return $t;
}
public function makeURLSegmentUnique()
{
// Ensure that this object has a non-conflicting URLSegment value.
$count = 2;
$URLSegment = $this->owner->URLSegment;
while ($this->URLSegmentInUse($URLSegment)) {
$URLSegment = preg_replace('/-[0-9]+$/', null, $URLSegment).'-'.$count;
++$count;
}
$this->owner->URLSegment = $URLSegment;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment