Skip to content

Commit

Permalink
Merge pull request #2 from larapack/develop
Browse files Browse the repository at this point in the history
Merge from develop
  • Loading branch information
marktopper committed Nov 30, 2015
2 parents a388ef2 + 997cbf3 commit 6ad2be6
Showing 1 changed file with 54 additions and 43 deletions.
97 changes: 54 additions & 43 deletions src/Larapack/AttributeSlugging/Sluggable.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace Larapack\AttributeSlugging;

use Illuminate\Support\Str;
use Exception;
use Illuminate\Support\Str;

trait Sluggable
{
Expand All @@ -12,40 +12,43 @@ trait Sluggable
*
* protected $slugs = [];
*/

/**
* Boot the sluggable trait for a model.
*
* @return void
*/
public static function bootSluggable()
{
/*
* Set slugged attributes on new records
*/
static::creating(function($model) {
static::creating(function ($model) {
$model->slugAttributes();
});
static::updating(function($model) {

static::updating(function ($model) {
$model->slugAttributes();
});
}

/**
* Returns the slug collection.
*
* @return void
*/
public function getSlugAttribute()
{
if (property_exists(get_called_class(), 'slug')) {
return $this->slug;
}
return [];
if (property_exists(get_called_class(), 'slug')) {
return $this->slug;
}

return [];
}

/**
* Adds slug attributes to the dataset, used before saving.
*
* @return void
*/
public function slugAttributes()
Expand All @@ -54,13 +57,15 @@ public function slugAttributes()
$this->setSluggedValue($slugAttribute, $sourceAttributes);
}
}

/**
* Sets a single slug attribute value.
* @param string $slugAttribute Attribute to populate with the slug.
* @param mixed $sourceAttributes Attribute(s) to generate the slug from.
* Supports dotted notation for relations.
* @param int $maxLength Maximum length for the slug not including the counter.
*
* @param string $slugAttribute Attribute to populate with the slug.
* @param mixed $sourceAttributes Attribute(s) to generate the slug from.
* Supports dotted notation for relations.
* @param int $maxLength Maximum length for the slug not including the counter.
*
* @return string The generated value.
*/
public function setSluggedValue($slugAttribute, $sourceAttributes, $maxLength = 240)
Expand All @@ -69,31 +74,32 @@ public function setSluggedValue($slugAttribute, $sourceAttributes, $maxLength =
if (!is_array($sourceAttributes)) {
$sourceAttributes = [$sourceAttributes];
}

$slugArr = [];
foreach ($sourceAttributes as $attribute) {
$slugArr[] = $this->getSluggableSourceAttributeValue($attribute);
}

$slug = implode(' ', $slugArr);
$slug = substr($slug, 0, $maxLength);
$slug = Str::slug($slug, $this->getSluggableSeparator());
}
else {
} else {
$slug = $this->{$slugAttribute};
}

if (empty($slug)) {
throw new Exception('Slug attribute [$slugAttribute] can not be empty.');
throw new Exception('Slug attribute [$slugAttribute] can not be empty.');
}

return $this->{$slugAttribute} = $this->getSluggableUniqueAttributeValue($slugAttribute, $slug);
}

/**
* Ensures a unique attribute value, if the value is already used a counter suffix is added.
* @param string $name The database column name.
* @param value $value The desired column value.
*
* @param string $name The database column name.
* @param value $value The desired column value.
*
* @return string A safe value that is unique.
*/
protected function getSluggableUniqueAttributeValue($name, $value)
Expand All @@ -109,46 +115,51 @@ protected function getSluggableUniqueAttributeValue($name, $value)
// If this model already have a slug that matches the requirements, then return that slug
$current = $this->newQuery()->whereRaw("{$name} RLIKE '{$_value}(-[0-9]*)?$'")->where($keyName, $keyValue)->first();
if ($current) {
return $current->{$name};
}
return $current->{$name};
}

// Get the latest slug matching the requirements to ensure that it is unique
$latestSlug = $this->newQuery()->whereRaw("{$name} RLIKE '{$_value}(-[0-9]*)?$'")->latest($name)->pluck($name);
if ($latestSlug) {
if ($latestSlug == $_value) {
return $_value . $separator . 1;
}

$pieces = explode('-', $latestSlug);
$number = intval(end($pieces));
return $_value . $separator . ($number + 1);
if ($latestSlug == $_value) {
return $_value.$separator. 1;
}

$pieces = explode('-', $latestSlug);
$number = intval(end($pieces));

return $_value.$separator.($number + 1);
}

return $_value;
}

/**
* Get an attribute relation value using dotted notation.
* Eg: author.name
* Eg: author.name.
*
* @return mixed
*/
protected function getSluggableSourceAttributeValue($key)
{
if (strpos($key, '.') === false)
if (strpos($key, '.') === false) {
return $this->getAttribute($key);
}
$keyParts = explode('.', $key);
$value = $this;
foreach ($keyParts as $part) {
if (!isset($value[$part])) {
return null;
return;
}
$value = $value[$part];
}

return $value;
}

/**
* Override the default slug separator.
*
* @return string
*/
public function getSluggableSeparator()
Expand Down

0 comments on commit 6ad2be6

Please sign in to comment.