diff --git a/config/oauth2.doctrine-orm.global.php.dist b/config/oauth2.doctrine-orm.global.php.dist
index c59d734..2377bd1 100644
--- a/config/oauth2.doctrine-orm.global.php.dist
+++ b/config/oauth2.doctrine-orm.global.php.dist
@@ -64,6 +64,10 @@ return array(
),
),
),
+ 'scope_entity' => array(
+ 'entity' => 'ZF\OAuth2\Doctrine\Entity\Scope',
+ 'field' => 'scope',
+ ),
),
'mapping' => array(
'User' => array(
diff --git a/media/OAuth2-orm.module.xml b/media/OAuth2-orm.module.xml
index 101063b..58ce1ca 100755
--- a/media/OAuth2-orm.module.xml
+++ b/media/OAuth2-orm.module.xml
@@ -1,6 +1,6 @@
-
+
@@ -13,6 +13,8 @@
+
+
@@ -50,7 +52,6 @@
AccessTokenToScope_OAuth2
-
@@ -208,19 +209,28 @@
CASCADE
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
-
+
-
+
@@ -236,9 +246,10 @@
-
-
-
-
+
+
+
+
+
diff --git a/media/OAuth2-orm.skipper b/media/OAuth2-orm.skipper
index e7e294f..de5d5df 100755
--- a/media/OAuth2-orm.skipper
+++ b/media/OAuth2-orm.skipper
@@ -3,12 +3,12 @@
-
+
-
-
-
+
+
+
diff --git a/media/oauth2-doctrine-erd.png b/media/oauth2-doctrine-erd.png
index 45af7e1..86d4419 100644
Binary files a/media/oauth2-doctrine-erd.png and b/media/oauth2-doctrine-erd.png differ
diff --git a/src/EventListener/DynamicMappingSubscriber.php b/src/EventListener/DynamicMappingSubscriber.php
index 1beb18c..e9b9bb1 100644
--- a/src/EventListener/DynamicMappingSubscriber.php
+++ b/src/EventListener/DynamicMappingSubscriber.php
@@ -10,9 +10,15 @@
use Doctrine\ORM\Events;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Zend\Config\Config;
+use DoctrineModule\Persistence\ProvidesObjectManager;
+use DoctrineModule\Persistence\ObjectManagerAwareInterface;
-class DynamicMappingSubscriber implements EventSubscriber
+class DynamicMappingSubscriber implements
+ EventSubscriber,
+ ObjectManagerAwareInterface
{
+ use ProvidesObjectManager;
+
protected $config = array();
protected $mapping = array();
@@ -47,6 +53,8 @@ public function getSubscribedEvents()
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
+ $this->setObjectManager($eventArgs->getObjectManager());
+
// the $metadata is the whole mapping info for this class
$metadata = $eventArgs->getClassMetadata();
@@ -83,8 +91,10 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
$clientIdField = $this->getMapping()->Client->mapping->client_id->name;
$clientIdColumn = $metadata->columnNames[$clientIdField];
- $metadata->table['uniqueConstraints']['idx_' . $clientIdColumn . '_unique']['columns'][] =
- $clientIdColumn;
+ $indexName = $this->_generateIdentifierName(
+ array_merge(array($metadata->table['name']), ['clientId']), "uniq", $this->_getMaxIdentifierLength()
+ );
+ $metadata->table['uniqueConstraints'][$indexName]['columns'][] = $clientIdColumn;
$joinMap = array(
'targetEntity' => $this->getConfig()->user_entity->entity,
@@ -145,8 +155,39 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
$metadata->mapManyToOne($joinMap);
break;
+ case $this->getConfig()->scope_entity->entity:
+ // Add unique constriant for clientId based on column
+ // See https://github.com/TomHAnderson/zf-oauth2-doctrine/issues/24
+ $nameField = $this->getMapping()->Scope->mapping->scope->name;
+ $nameColumn = $metadata->columnNames[$nameField];
+ $indexName = $this->_generateIdentifierName(
+ array_merge(array($metadata->table['name']), ['scope']), "uniq", $this->_getMaxIdentifierLength()
+ );
+ $metadata->table['uniqueConstraints'][$indexName]['columns'][] = $nameColumn;
+ break;
+
default:
break;
}
}
+
+ // Copied from Doctrine DBAL\Schema\Table
+ protected function _generateIdentifierName($columnNames, $prefix='', $maxSize=30)
+ {
+ $hash = implode("", array_map(function ($column) {
+ return dechex(crc32($column));
+ }, $columnNames));
+
+ return substr(strtoupper($prefix . "_" . $hash), 0, $maxSize);
+ }
+
+ protected function _getMaxIdentifierLength()
+ {
+ return $this->getObjectManager()
+ ->getConnection()
+ ->getSchemaManager()
+ ->getDatabasePlatform()
+ ->getMaxIdentifierLength()
+ ;
+ }
}