/**
  * @return Cli\Command[]
  */
 protected function getDomainCommands()
 {
     $cliCommands = [];
     $domainCommandClassNames = $this->reflectionService->getAllImplementationClassNamesForInterface(Domain\CommandInterface::class);
     foreach ($domainCommandClassNames as $domainCommandClassName) {
         if ($this->reflectionService->isClassAbstract($domainCommandClassName) === TRUE) {
             continue;
         }
         $cliCommands[] = $this->buildDomainCommand($domainCommandClassName);
     }
     return $cliCommands;
 }
 /**
  * Get all class names inside this namespace and return them as array.
  *
  * @param string $namespace
  * @return array Array of all class names inside a given namespace.
  */
 protected function getClassNamesInNamespace($namespace)
 {
     $affectedViewHelperClassNames = array();
     $allViewHelperClassNames = $this->reflectionService->getAllSubClassNamesForClass('TYPO3\\Fluid\\Core\\ViewHelper\\AbstractViewHelper');
     foreach ($allViewHelperClassNames as $viewHelperClassName) {
         if ($this->reflectionService->isClassAbstract($viewHelperClassName)) {
             continue;
         }
         if (strncmp($namespace, $viewHelperClassName, strlen($namespace)) === 0) {
             $affectedViewHelperClassNames[] = $viewHelperClassName;
         }
     }
     sort($affectedViewHelperClassNames);
     return $affectedViewHelperClassNames;
 }
 /**
  * Lists all public controller actions not covered by the active security policy
  *
  * @return void
  */
 public function showUnprotectedActionsCommand()
 {
     $controllerClassNames = $this->reflectionService->getAllSubClassNamesForClass('TYPO3\\Flow\\Mvc\\Controller\\AbstractController');
     $allActionsAreProtected = TRUE;
     foreach ($controllerClassNames as $controllerClassName) {
         if ($this->reflectionService->isClassAbstract($controllerClassName)) {
             continue;
         }
         $methodNames = get_class_methods($controllerClassName);
         $foundUnprotectedAction = FALSE;
         foreach ($methodNames as $methodName) {
             if (preg_match('/.*Action$/', $methodName) === 0 || $this->reflectionService->isMethodPublic($controllerClassName, $methodName) === FALSE) {
                 continue;
             }
             if ($this->policyService->hasPolicyEntryForMethod($controllerClassName, $methodName) === FALSE) {
                 if ($foundUnprotectedAction === FALSE) {
                     $this->outputLine(PHP_EOL . '<b>' . $controllerClassName . '</b>');
                     $foundUnprotectedAction = TRUE;
                     $allActionsAreProtected = FALSE;
                 }
                 $this->outputLine('  ' . $methodName);
             }
         }
     }
     if ($allActionsAreProtected === TRUE) {
         $this->outputLine('All public controller actions are covered by your security policy. Good job!');
     }
 }
 /**
  * Analyzes the Object Configuration provided by the compiler and builds the necessary PHP code for the proxy classes
  * to realize dependency injection.
  *
  * @return void
  */
 public function build()
 {
     $this->objectConfigurations = $this->objectManager->getObjectConfigurations();
     foreach ($this->objectConfigurations as $objectName => $objectConfiguration) {
         $className = $objectConfiguration->getClassName();
         if ($className === '' || $this->compiler->hasCacheEntryForClass($className) === true) {
             continue;
         }
         if ($objectName !== $className || $this->reflectionService->isClassAbstract($className)) {
             continue;
         }
         $proxyClass = $this->compiler->getProxyClass($className);
         if ($proxyClass === false) {
             continue;
         }
         $this->systemLogger->log('Building DI proxy for "' . $className . '".', LOG_DEBUG);
         $constructorPreCode = '';
         $constructorPostCode = '';
         $constructorPreCode .= $this->buildSetInstanceCode($objectConfiguration);
         $constructorPreCode .= $this->buildConstructorInjectionCode($objectConfiguration);
         $setRelatedEntitiesCode = '';
         if (!$this->reflectionService->hasMethod($className, '__sleep')) {
             $proxyClass->addTraits(['\\TYPO3\\Flow\\Object\\Proxy\\ObjectSerializationTrait']);
             $sleepMethod = $proxyClass->getMethod('__sleep');
             $sleepMethod->addPostParentCallCode($this->buildSerializeRelatedEntitiesCode($objectConfiguration));
             $setRelatedEntitiesCode = "\n        " . '$this->Flow_setRelatedEntities();' . "\n";
         }
         $wakeupMethod = $proxyClass->getMethod('__wakeup');
         $wakeupMethod->addPreParentCallCode($this->buildSetInstanceCode($objectConfiguration));
         $wakeupMethod->addPreParentCallCode($setRelatedEntitiesCode);
         $wakeupMethod->addPostParentCallCode($this->buildLifecycleInitializationCode($objectConfiguration, \TYPO3\Flow\Object\ObjectManagerInterface::INITIALIZATIONCAUSE_RECREATED));
         $wakeupMethod->addPostParentCallCode($this->buildLifecycleShutdownCode($objectConfiguration));
         $injectPropertiesCode = $this->buildPropertyInjectionCode($objectConfiguration);
         if ($injectPropertiesCode !== '') {
             $proxyClass->addTraits(['\\TYPO3\\Flow\\Object\\DependencyInjection\\PropertyInjectionTrait']);
             $proxyClass->getMethod('Flow_Proxy_injectProperties')->addPreParentCallCode($injectPropertiesCode);
             $proxyClass->getMethod('Flow_Proxy_injectProperties')->overrideMethodVisibility('private');
             $wakeupMethod->addPreParentCallCode("        \$this->Flow_Proxy_injectProperties();\n");
             $constructorPostCode .= '        if (\'' . $className . '\' === get_class($this)) {' . "\n";
             $constructorPostCode .= '            $this->Flow_Proxy_injectProperties();' . "\n";
             $constructorPostCode .= '        }' . "\n";
         }
         $constructorPostCode .= $this->buildLifecycleInitializationCode($objectConfiguration, \TYPO3\Flow\Object\ObjectManagerInterface::INITIALIZATIONCAUSE_CREATED);
         $constructorPostCode .= $this->buildLifecycleShutdownCode($objectConfiguration);
         $constructor = $proxyClass->getConstructor();
         $constructor->addPreParentCallCode($constructorPreCode);
         $constructor->addPostParentCallCode($constructorPostCode);
         if ($this->objectManager->getContext()->isProduction()) {
             $this->compileStaticMethods($className, $proxyClass);
         }
     }
 }
 /**
  * Analyzes the Object Configuration provided by the compiler and builds the necessary PHP code for the proxy classes
  * to realize dependency injection.
  *
  * @return void
  */
 public function build()
 {
     $this->objectConfigurations = $this->objectManager->getObjectConfigurations();
     foreach ($this->objectConfigurations as $objectName => $objectConfiguration) {
         $className = $objectConfiguration->getClassName();
         if ($className === '' || $this->compiler->hasCacheEntryForClass($className) === TRUE) {
             continue;
         }
         if ($objectName !== $className || $this->reflectionService->isClassAbstract($className) || $this->reflectionService->isClassFinal($className)) {
             continue;
         }
         $proxyClass = $this->compiler->getProxyClass($className);
         if ($proxyClass === FALSE) {
             continue;
         }
         $this->systemLogger->log('Building DI proxy for "' . $className . '".', LOG_DEBUG);
         $constructorPreCode = '';
         $constructorPostCode = '';
         $constructorPreCode .= $this->buildSetInstanceCode($objectConfiguration);
         $constructorPreCode .= $this->buildConstructorInjectionCode($objectConfiguration);
         $wakeupMethod = $proxyClass->getMethod('__wakeup');
         $wakeupMethod->addPreParentCallCode($this->buildSetInstanceCode($objectConfiguration));
         $wakeupMethod->addPreParentCallCode($this->buildSetRelatedEntitiesCode());
         $wakeupMethod->addPostParentCallCode($this->buildLifecycleInitializationCode($objectConfiguration, \TYPO3\Flow\Object\ObjectManagerInterface::INITIALIZATIONCAUSE_RECREATED));
         $wakeupMethod->addPostParentCallCode($this->buildLifecycleShutdownCode($objectConfiguration));
         $sleepMethod = $proxyClass->getMethod('__sleep');
         $sleepMethod->addPostParentCallCode($this->buildSerializeRelatedEntitiesCode($objectConfiguration));
         $searchForEntitiesAndStoreIdentifierArrayMethod = $proxyClass->getMethod('searchForEntitiesAndStoreIdentifierArray');
         $searchForEntitiesAndStoreIdentifierArrayMethod->setMethodParametersCode('$path, $propertyValue, $originalPropertyName');
         $searchForEntitiesAndStoreIdentifierArrayMethod->overrideMethodVisibility('private');
         $searchForEntitiesAndStoreIdentifierArrayMethod->addPreParentCallCode($this->buildSearchForEntitiesAndStoreIdentifierArrayCode());
         $injectPropertiesCode = $this->buildPropertyInjectionCode($objectConfiguration);
         if ($injectPropertiesCode !== '') {
             $proxyClass->getMethod('Flow_Proxy_injectProperties')->addPreParentCallCode($injectPropertiesCode);
             $proxyClass->getMethod('Flow_Proxy_injectProperties')->overrideMethodVisibility('private');
             $wakeupMethod->addPreParentCallCode("\t\t\$this->Flow_Proxy_injectProperties();\n");
             $constructorPostCode .= '		if (\'' . $className . '\' === get_class($this)) {' . "\n";
             $constructorPostCode .= '			$this->Flow_Proxy_injectProperties();' . "\n";
             $constructorPostCode .= '		}' . "\n";
         }
         $constructorPostCode .= $this->buildLifecycleInitializationCode($objectConfiguration, \TYPO3\Flow\Object\ObjectManagerInterface::INITIALIZATIONCAUSE_CREATED);
         $constructorPostCode .= $this->buildLifecycleShutdownCode($objectConfiguration);
         $constructor = $proxyClass->getConstructor();
         $constructor->addPreParentCallCode($constructorPreCode);
         $constructor->addPostParentCallCode($constructorPostCode);
         if ($this->objectManager->getContext()->isProduction()) {
             $this->compileStaticMethods($className, $proxyClass);
         }
     }
 }
 /**
  * Renders and returns the PHP code for this ProxyClass.
  *
  * @return string
  */
 public function render()
 {
     $namespace = $this->namespace;
     $proxyClassName = $this->originalClassName;
     $originalClassName = $this->originalClassName . \TYPO3\Flow\Object\Proxy\Compiler::ORIGINAL_CLASSNAME_SUFFIX;
     $abstractKeyword = $this->reflectionService->isClassAbstract($this->fullOriginalClassName) ? 'abstract ' : '';
     $constantsCode = $this->renderConstantsCode();
     $propertiesCode = $this->renderPropertiesCode();
     $methodsCode = isset($this->constructor) ? $this->constructor->render() : '';
     foreach ($this->methods as $proxyMethod) {
         $methodsCode .= $proxyMethod->render();
     }
     if ($methodsCode . $constantsCode === '') {
         return '';
     }
     $classCode = ($namespace !== '' ? "namespace {$namespace};\n\n" : '') . "use Doctrine\\ORM\\Mapping as ORM;\n" . "use TYPO3\\Flow\\Annotations as Flow;\n" . "\n" . $this->buildClassDocumentation() . $abstractKeyword . "class {$proxyClassName} extends {$originalClassName} implements " . implode(', ', array_unique($this->interfaces)) . " {\n\n" . $constantsCode . $propertiesCode . $methodsCode . "}";
     return $classCode;
 }
예제 #7
0
 /**
  * @param array $classesSelector
  * @return array
  */
 protected function getAffectedClassNames(array $classesSelector)
 {
     if (isset($classesSelector['parentClassName'])) {
         $affectedClassNames = $this->reflectionService->getAllSubClassNamesForClass($classesSelector['parentClassName']);
     } elseif (isset($classesSelector['interface'])) {
         $affectedClassNames = $this->reflectionService->getAllImplementationClassNamesForInterface($classesSelector['interface']);
     } elseif (isset($classesSelector['classesContainingMethodsAnnotatedWith'])) {
         $affectedClassNames = $this->reflectionService->getClassesContainingMethodsAnnotatedWith($classesSelector['classesContainingMethodsAnnotatedWith']);
     } else {
         $affectedClassNames = $this->reflectionService->getAllClassNames();
     }
     foreach ($affectedClassNames as $index => $className) {
         if ($this->reflectionService->isClassAbstract($className) && (!isset($classesSelector['includeAbstractClasses']) || $classesSelector['includeAbstractClasses'] === FALSE)) {
             unset($affectedClassNames[$index]);
         } elseif (isset($classesSelector['classNamePattern']) && preg_match($classesSelector['classNamePattern'], $className) === 0) {
             unset($affectedClassNames[$index]);
         }
     }
     return $affectedClassNames;
 }
 /**
  * Renders and returns the PHP code for this ProxyClass.
  *
  * @return string
  */
 public function render()
 {
     $namespace = $this->namespace;
     $proxyClassName = $this->originalClassName;
     $originalClassName = $this->originalClassName . \TYPO3\Flow\Object\Proxy\Compiler::ORIGINAL_CLASSNAME_SUFFIX;
     $classModifier = '';
     if ($this->reflectionService->isClassAbstract($this->fullOriginalClassName)) {
         $classModifier = 'abstract ';
     } elseif ($this->reflectionService->isClassFinal($this->fullOriginalClassName)) {
         $classModifier = 'final ';
     }
     $constantsCode = $this->renderConstantsCode();
     $propertiesCode = $this->renderPropertiesCode();
     $traitsCode = $this->renderTraitsCode();
     $methodsCode = isset($this->constructor) ? $this->constructor->render() : '';
     foreach ($this->methods as $proxyMethod) {
         $methodsCode .= $proxyMethod->render();
     }
     if ($methodsCode . $constantsCode === '') {
         return '';
     }
     $classCode = ($namespace !== '' ? 'namespace ' . $namespace . ";\n\n" : '') . "use Doctrine\\ORM\\Mapping as ORM;\n" . "use TYPO3\\Flow\\Annotations as Flow;\n" . "\n" . $this->buildClassDocumentation() . $classModifier . 'class ' . $proxyClassName . ' extends ' . $originalClassName . ' implements ' . implode(', ', array_unique($this->interfaces)) . " {\n\n" . $traitsCode . $constantsCode . $propertiesCode . $methodsCode . '}';
     return $classCode;
 }
 /**
  * Lists all public controller actions not covered by the active security policy
  *
  * @return void
  */
 public function showUnprotectedActionsCommand()
 {
     $methodPrivileges = array();
     foreach ($this->policyService->getRoles(true) as $role) {
         $methodPrivileges = array_merge($methodPrivileges, $role->getPrivilegesByType(\TYPO3\Flow\Security\Authorization\Privilege\Method\MethodPrivilegeInterface::class));
     }
     $controllerClassNames = $this->reflectionService->getAllSubClassNamesForClass(\TYPO3\Flow\Mvc\Controller\AbstractController::class);
     $allActionsAreProtected = true;
     foreach ($controllerClassNames as $controllerClassName) {
         if ($this->reflectionService->isClassAbstract($controllerClassName)) {
             continue;
         }
         $methodNames = get_class_methods($controllerClassName);
         $foundUnprotectedAction = false;
         foreach ($methodNames as $methodName) {
             if (preg_match('/.*Action$/', $methodName) === 0 || $this->reflectionService->isMethodPublic($controllerClassName, $methodName) === false) {
                 continue;
             }
             /** @var MethodPrivilegeInterface $methodPrivilege */
             foreach ($methodPrivileges as $methodPrivilege) {
                 if ($methodPrivilege->matchesMethod($controllerClassName, $methodName)) {
                     continue 2;
                 }
             }
             if ($foundUnprotectedAction === false) {
                 $this->outputLine(PHP_EOL . '<b>' . $controllerClassName . '</b>');
                 $foundUnprotectedAction = true;
                 $allActionsAreProtected = false;
             }
             $this->outputLine('  ' . $methodName);
         }
     }
     if ($allActionsAreProtected === true) {
         $this->outputLine('All public controller actions are covered by your security policy. Good job!');
     }
 }
 /**
  * Loads the metadata for the specified class into the provided container.
  *
  * @param string $className
  * @param ClassMetadata $metadata
  * @return void
  * @throws MappingException
  * @throws \UnexpectedValueException
  * @todo adjust when Doctrine 2.5 is used, see http://www.doctrine-project.org/jira/browse/DDC-93
  */
 public function loadMetadataForClass($className, ClassMetadata $metadata)
 {
     /**
      * This is the actual type we have at this point, but we cannot change the
      * signature due to inheritance.
      *
      * @var OrmClassMetadata $metadata
      */
     $class = $metadata->getReflectionClass();
     $classSchema = $this->getClassSchema($class->getName());
     $classAnnotations = $this->reader->getClassAnnotations($class);
     // Evaluate Entity annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\MappedSuperclass'])) {
         $mappedSuperclassAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\MappedSuperclass'];
         if ($mappedSuperclassAnnotation->repositoryClass !== null) {
             $metadata->setCustomRepositoryClass($mappedSuperclassAnnotation->repositoryClass);
         }
         $metadata->isMappedSuperclass = true;
     } elseif (isset($classAnnotations[\TYPO3\Flow\Annotations\Entity::class]) || isset($classAnnotations['Doctrine\\ORM\\Mapping\\Entity'])) {
         $entityAnnotation = isset($classAnnotations[\TYPO3\Flow\Annotations\Entity::class]) ? $classAnnotations[\TYPO3\Flow\Annotations\Entity::class] : $classAnnotations['Doctrine\\ORM\\Mapping\\Entity'];
         if ($entityAnnotation->repositoryClass !== null) {
             $metadata->setCustomRepositoryClass($entityAnnotation->repositoryClass);
         } elseif ($classSchema->getRepositoryClassName() !== null) {
             if ($this->reflectionService->isClassImplementationOf($classSchema->getRepositoryClassName(), 'Doctrine\\ORM\\EntityRepository')) {
                 $metadata->setCustomRepositoryClass($classSchema->getRepositoryClassName());
             }
         }
         if ($entityAnnotation->readOnly) {
             $metadata->markReadOnly();
         }
     } elseif ($classSchema->getModelType() === ClassSchema::MODELTYPE_VALUEOBJECT) {
         // also ok... but we make it read-only
         $metadata->markReadOnly();
     } else {
         throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
     }
     // Evaluate Table annotation
     $primaryTable = array();
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\Table'])) {
         $tableAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\Table'];
         $primaryTable = array('name' => $tableAnnotation->name, 'schema' => $tableAnnotation->schema);
         if ($tableAnnotation->indexes !== null) {
             foreach ($tableAnnotation->indexes as $indexAnnotation) {
                 $index = array('columns' => $indexAnnotation->columns);
                 if (!empty($indexAnnotation->name)) {
                     $primaryTable['indexes'][$indexAnnotation->name] = $index;
                 } else {
                     $primaryTable['indexes'][] = $index;
                 }
             }
         }
         if ($tableAnnotation->uniqueConstraints !== null) {
             foreach ($tableAnnotation->uniqueConstraints as $uniqueConstraint) {
                 $uniqueConstraint = array('columns' => $uniqueConstraint->columns);
                 if (!empty($uniqueConstraint->name)) {
                     $primaryTable['uniqueConstraints'][$uniqueConstraint->name] = $uniqueConstraint;
                 } else {
                     $primaryTable['uniqueConstraints'][] = $uniqueConstraint;
                 }
             }
         }
         if ($tableAnnotation->options !== null) {
             $primaryTable['options'] = $tableAnnotation->options;
         }
     }
     if (!isset($primaryTable['name'])) {
         $className = $classSchema->getClassName();
         $primaryTable['name'] = $this->inferTableNameFromClassName($className);
     }
     // Evaluate NamedNativeQueries annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\NamedNativeQueries'])) {
         $namedNativeQueriesAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\NamedNativeQueries'];
         foreach ($namedNativeQueriesAnnotation->value as $namedNativeQuery) {
             $metadata->addNamedNativeQuery(array('name' => $namedNativeQuery->name, 'query' => $namedNativeQuery->query, 'resultClass' => $namedNativeQuery->resultClass, 'resultSetMapping' => $namedNativeQuery->resultSetMapping));
         }
     }
     // Evaluate SqlResultSetMappings annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\SqlResultSetMappings'])) {
         $sqlResultSetMappingsAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\SqlResultSetMappings'];
         foreach ($sqlResultSetMappingsAnnotation->value as $resultSetMapping) {
             $entities = array();
             $columns = array();
             foreach ($resultSetMapping->entities as $entityResultAnnotation) {
                 $entityResult = array('fields' => array(), 'entityClass' => $entityResultAnnotation->entityClass, 'discriminatorColumn' => $entityResultAnnotation->discriminatorColumn);
                 foreach ($entityResultAnnotation->fields as $fieldResultAnnotation) {
                     $entityResult['fields'][] = array('name' => $fieldResultAnnotation->name, 'column' => $fieldResultAnnotation->column);
                 }
                 $entities[] = $entityResult;
             }
             foreach ($resultSetMapping->columns as $columnResultAnnotation) {
                 $columns[] = array('name' => $columnResultAnnotation->name);
             }
             $metadata->addSqlResultSetMapping(array('name' => $resultSetMapping->name, 'entities' => $entities, 'columns' => $columns));
         }
     }
     // Evaluate NamedQueries annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\NamedQueries'])) {
         $namedQueriesAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\NamedQueries'];
         if (!is_array($namedQueriesAnnotation->value)) {
             throw new \UnexpectedValueException('@NamedQueries should contain an array of @NamedQuery annotations.');
         }
         foreach ($namedQueriesAnnotation->value as $namedQuery) {
             if (!$namedQuery instanceof NamedQuery) {
                 throw new \UnexpectedValueException('@NamedQueries should contain an array of @NamedQuery annotations.');
             }
             $metadata->addNamedQuery(array('name' => $namedQuery->name, 'query' => $namedQuery->query));
         }
     }
     // Evaluate InheritanceType annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\InheritanceType'])) {
         $inheritanceTypeAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\InheritanceType'];
         $inheritanceType = constant('Doctrine\\ORM\\Mapping\\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($inheritanceTypeAnnotation->value));
         if ($inheritanceType !== OrmClassMetadata::INHERITANCE_TYPE_NONE) {
             // Evaluate DiscriminatorColumn annotation
             if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorColumn'])) {
                 $discriminatorColumnAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorColumn'];
                 $discriminatorColumn = array('name' => $discriminatorColumnAnnotation->name, 'type' => $discriminatorColumnAnnotation->type, 'length' => $discriminatorColumnAnnotation->length, 'columnDefinition' => $discriminatorColumnAnnotation->columnDefinition);
             } else {
                 $discriminatorColumn = array('name' => 'dtype', 'type' => 'string', 'length' => 255);
             }
             // Evaluate DiscriminatorMap annotation
             if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorMap'])) {
                 $discriminatorMapAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\DiscriminatorMap'];
                 $discriminatorMap = $discriminatorMapAnnotation->value;
             } else {
                 $discriminatorMap = array();
                 $subclassNames = $this->reflectionService->getAllSubClassNamesForClass($className);
                 if (!$this->reflectionService->isClassAbstract($className)) {
                     $mappedClassName = strtolower(str_replace('Domain_Model_', '', str_replace('\\', '_', $className)));
                     $discriminatorMap[$mappedClassName] = $className;
                 }
                 foreach ($subclassNames as $subclassName) {
                     $mappedSubclassName = strtolower(str_replace('Domain_Model_', '', str_replace('\\', '_', $subclassName)));
                     $discriminatorMap[$mappedSubclassName] = $subclassName;
                 }
             }
             if ($discriminatorMap !== array()) {
                 $metadata->setDiscriminatorColumn($discriminatorColumn);
                 $metadata->setDiscriminatorMap($discriminatorMap);
             } else {
                 $inheritanceType = OrmClassMetadata::INHERITANCE_TYPE_NONE;
             }
         }
         $metadata->setInheritanceType($inheritanceType);
     }
     // Evaluate DoctrineChangeTrackingPolicy annotation
     if (isset($classAnnotations['Doctrine\\ORM\\Mapping\\ChangeTrackingPolicy'])) {
         $changeTrackingAnnotation = $classAnnotations['Doctrine\\ORM\\Mapping\\ChangeTrackingPolicy'];
         $metadata->setChangeTrackingPolicy(constant('Doctrine\\ORM\\Mapping\\ClassMetadata::CHANGETRACKING_' . strtoupper($changeTrackingAnnotation->value)));
     } else {
         $metadata->setChangeTrackingPolicy(OrmClassMetadata::CHANGETRACKING_DEFERRED_EXPLICIT);
     }
     // Evaluate annotations on properties/fields
     try {
         $this->evaluatePropertyAnnotations($metadata);
     } catch (MappingException $exception) {
         throw new MappingException(sprintf('Failure while evaluating property annotations for class "%s": %s', $metadata->getName(), $exception->getMessage()), 1382003497, $exception);
     }
     // build unique index for table
     if (!isset($primaryTable['uniqueConstraints'])) {
         $idProperties = array_keys($classSchema->getIdentityProperties());
         if (array_diff($idProperties, $metadata->getIdentifierFieldNames()) !== array()) {
             $uniqueIndexName = $this->truncateIdentifier('flow_identity_' . $primaryTable['name']);
             foreach ($idProperties as $idProperty) {
                 $primaryTable['uniqueConstraints'][$uniqueIndexName]['columns'][] = isset($metadata->columnNames[$idProperty]) ? $metadata->columnNames[$idProperty] : strtolower($idProperty);
             }
         }
     }
     $metadata->setPrimaryTable($primaryTable);
     // Evaluate AssociationOverrides annotation
     $this->evaluateOverridesAnnotations($classAnnotations, $metadata);
     // Evaluate EntityListeners annotation
     $this->evaluateEntityListenersAnnotation($class, $metadata, $classAnnotations);
     // Evaluate @HasLifecycleCallbacks annotation
     $this->evaluateLifeCycleAnnotations($class, $metadata);
 }