Skip to content

Commit

Permalink
PR fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mfendeksilverstripe committed Apr 9, 2020
1 parent 5fec5f1 commit e6614e3
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 17 deletions.
2 changes: 1 addition & 1 deletion docs/en/02_Developer_Guides/01_Templates/10_Unique_Keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The unique key generation can be altered in two ways:

### Extension point

`cacheKeyComponent` extension point is located in `DataObject::getCacheKeyComponent`.
`cacheKeyComponent` extension point is located in `DataObject::getUniqueKeyComponents`.
Use standard extension flow to define the `cacheKeyComponent` method on your extension which is expected to return a `string`.
This value will be used when unique key is generated. Common cases are:

Expand Down
13 changes: 7 additions & 6 deletions src/ORM/DataObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -3237,7 +3237,7 @@ public static function get_one($callerClass, $filter = "", $cache = true, $order
/** @var DataObject $singleton */
$singleton = singleton($callerClass);

$cacheComponents = [$filter, $orderby, $singleton->getCacheKeyComponent()];
$cacheComponents = [$filter, $orderby, $singleton->getUniqueKeyComponents()];
$cacheKey = md5(serialize($cacheComponents));

$item = null;
Expand Down Expand Up @@ -4189,7 +4189,7 @@ public function mergeRelatedObjects($list, $items)

/**
* Generate a unique key for data object
* the unique key uses the @see DataObject::getCacheKeyComponent() extension point so unique key modifiers
* the unique key uses the @see DataObject::getUniqueKeyComponents() extension point so unique key modifiers
* such as versioned or fluent are covered
* i.e. same data object in different stages or different locales will produce different unique key
*
Expand All @@ -4198,18 +4198,19 @@ public function mergeRelatedObjects($list, $items)
* - when you need unique id on the front end (for example JavaScript needs to target specific element)
*
* @return string
* @throws Exception
*/
public function getUniqueKey(): string
{
/** @var UniqueKeyInterface $service */
$service = UniqueKeyService::singleton();
if (!$service instanceof UniqueKeyInterface) {
return '';
return bin2hex(random_bytes(16));
}

$cacheKeys = $this->getCacheKeyComponent();
$keyComponents = $this->getUniqueKeyComponents();

return $service->generateKey($this, $cacheKeys);
return $service->generateKey($this, $keyComponents);
}

/**
Expand Down Expand Up @@ -4238,7 +4239,7 @@ protected function mergeRelatedObject($list, $added, $item)
}
}

private function getCacheKeyComponent(): array
private function getUniqueKeyComponents(): array
{
return $this->extend('cacheKeyComponent');
}
Expand Down
4 changes: 2 additions & 2 deletions src/ORM/UniqueKey/UniqueKeyInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ interface UniqueKeyInterface
* Generate a unique key for data object
*
* @param DataObject $object
* @param array $extraKeys
* @param array $keyComponents
* @return string
*/
public function generateKey(DataObject $object, array $extraKeys = []): string;
public function generateKey(DataObject $object, array $keyComponents = []): string;
}
20 changes: 12 additions & 8 deletions src/ORM/UniqueKey/UniqueKeyService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace SilverStripe\ORM\UniqueKey;

use Exception;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\ORM\DataObject;
Expand All @@ -21,19 +22,22 @@ class UniqueKeyService implements UniqueKeyInterface
{
use Injectable;

public function generateKey(DataObject $object, array $extraKeys = []): string
/**
* @param DataObject $object
* @param array $keyComponents
* @return string
* @throws Exception
*/
public function generateKey(DataObject $object, array $keyComponents = []): string
{
if (!$object->isInDB()) {
return '';
}

$id = $object->isInDB() ? (string) $object->ID : bin2hex(random_bytes(16));
$class = ClassInfo::shortName($object);
$extraKeys = json_encode($extraKeys);
$keyComponents = json_encode($keyComponents);

$hash = md5(sprintf('%s-%s-%d', $extraKeys, $object->ClassName, $object->ID));
$hash = md5(sprintf('%s-%s-%s', $keyComponents, $object->ClassName, $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);
return sprintf('ss-%s-%s-%s', $class, $id, $hash);
}
}

0 comments on commit e6614e3

Please sign in to comment.