-
Notifications
You must be signed in to change notification settings - Fork 823
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
73990ac
commit 98ed9b4
Showing
6 changed files
with
186 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
namespace SilverStripe\UniqueKey; | ||
|
||
use SilverStripe\Core\Injector\Injectable; | ||
use SilverStripe\ORM\DataObject; | ||
|
||
class Service | ||
{ | ||
use Injectable; | ||
|
||
/** | ||
* Generate a unique key for data object | ||
* | ||
* recommended use: | ||
* - when you need unique key for caching purposes | ||
* - when you need unique id on the front end (for example JavaScript needs to target specific element) | ||
* | ||
* @param DataObject $object | ||
* @param array $extraKeys | ||
* @return string | ||
*/ | ||
public function generateKey(DataObject $object, array $extraKeys = []): string | ||
{ | ||
if (!$object->isInDB()) { | ||
return ''; | ||
} | ||
|
||
// extract class name (remove namespaces) | ||
$classSegments = explode('\\', $object->ClassName); | ||
|
||
if (count($classSegments) === 0) { | ||
return ''; | ||
} | ||
|
||
$class = array_pop($classSegments); | ||
$extraKeys = json_encode($extraKeys); | ||
|
||
$hash = md5(sprintf('%s-%s-%d', $extraKeys, $object->ClassName, $object->ID)); | ||
|
||
// note: class name and id are added just for readability as the hash already contains all parts | ||
// needed to create a unique key | ||
return sprintf('ss-%s-%d-%s', $class, $object->ID, $hash); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Tests\UniqueKey; | ||
|
||
use SilverStripe\Core\Extension; | ||
use SilverStripe\Dev\TestOnly; | ||
|
||
class ExtraKeysExtension extends Extension implements TestOnly | ||
{ | ||
public function cacheKeyComponent(): string | ||
{ | ||
return 'extra-key'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Tests\UniqueKey; | ||
|
||
use SilverStripe\Dev\TestOnly; | ||
use SilverStripe\ORM\DataObject; | ||
|
||
class Mountain extends DataObject implements TestOnly | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
private static $table_name = 'UniqueKeyTest_Mountain'; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private static $db = [ | ||
'Title' => 'Varchar', | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Tests\UniqueKey; | ||
|
||
use SilverStripe\Dev\TestOnly; | ||
use SilverStripe\ORM\DataObject; | ||
|
||
class River extends DataObject implements TestOnly | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
private static $table_name = 'UniqueKeyTest_River'; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private static $db = [ | ||
'Title' => 'Varchar', | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Tests\UniqueKey; | ||
|
||
use SilverStripe\Core\Injector\Injector; | ||
use SilverStripe\Dev\SapphireTest; | ||
use SilverStripe\ORM\DataObject; | ||
|
||
class ServiceTest extends SapphireTest | ||
{ | ||
/** | ||
* @var array | ||
*/ | ||
protected static $extra_dataobjects = [ | ||
River::class, | ||
Mountain::class, | ||
]; | ||
|
||
/** | ||
* @param int $id | ||
* @param string $class | ||
* @param bool $extraKeys | ||
* @param string $expected | ||
* @dataProvider uniqueKeysProvider | ||
*/ | ||
public function testUniqueKey(int $id, string $class, bool $extraKeys, string $expected): void | ||
{ | ||
if ($extraKeys) { | ||
$class::add_extension(ExtraKeysExtension::class); | ||
} | ||
|
||
/** @var DataObject $object */ | ||
$object = Injector::inst()->create($class); | ||
$object->ID = $id; | ||
|
||
$this->assertEquals($expected, $object->getUniqueKey()); | ||
|
||
if ($extraKeys) { | ||
$class::remove_extension(ExtraKeysExtension::class); | ||
} | ||
} | ||
|
||
public function uniqueKeysProvider(): array | ||
{ | ||
return [ | ||
[1, River::class, false, 'ss-River-1-7eab00006ab6d090635b03f9fa1187d7'], | ||
[1, River::class, true, 'ss-River-1-65474ab87fd42ca8cbfc32f87d5840e7'], | ||
[2, River::class, false, 'ss-River-2-9c63d549d3a7a2f9679f7ce0dbb6a177'], | ||
[2, River::class, true, 'ss-River-2-a028c9b5ecd2dd68edc6f20192e29c63'], | ||
[1, Mountain::class, false, 'ss-Mountain-1-013d8ba56604ceeb2bda4b09d04c7e29'], | ||
[1, Mountain::class, true, 'ss-Mountain-1-3dba35f13a9d3ad648be466946297444'], | ||
[2, Mountain::class, false, 'ss-Mountain-2-a628f2db748065729d6a832a094cea3f'], | ||
[2, Mountain::class, true, 'ss-Mountain-2-e6236799ab5a00d36ee704fa87d46021'], | ||
]; | ||
} | ||
} |