ExtensionMetadataFactory.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. namespace Gedmo\Mapping;
  3. use Doctrine\Common\Persistence\ObjectManager,
  4. Doctrine\Common\ClassLoader,
  5. Doctrine\Common\Persistence\Mapping\ClassMetadata;
  6. /**
  7. * The extension metadata factory is responsible for extension driver
  8. * initialization and fully reading the extension metadata
  9. *
  10. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  11. * @package Gedmo.Mapping
  12. * @subpackage ExtensionMetadataFactory
  13. * @link http://www.gediminasm.org
  14. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  15. */
  16. class ExtensionMetadataFactory
  17. {
  18. /**
  19. * Extension driver
  20. * @var Gedmo\Mapping\Driver
  21. */
  22. protected $driver;
  23. /**
  24. * Object manager, entity or document
  25. * @var object
  26. */
  27. private $objectManager;
  28. /**
  29. * Extension namespace
  30. *
  31. * @var string
  32. */
  33. private $extensionNamespace;
  34. /**
  35. * Initializes extension driver
  36. *
  37. * @param ObjectManager $objectManager
  38. * @param string $extensionNamespace
  39. */
  40. public function __construct(ObjectManager $objectManager, $extensionNamespace)
  41. {
  42. $this->objectManager = $objectManager;
  43. $this->extensionNamespace = $extensionNamespace;
  44. $omDriver = $objectManager->getConfiguration()->getMetadataDriverImpl();
  45. $this->driver = $this->getDriver($omDriver);
  46. }
  47. /**
  48. * Reads extension metadata
  49. *
  50. * @param ClassMetadata $meta
  51. * @return array - the metatada configuration
  52. */
  53. public function getExtensionMetadata(ClassMetadata $meta)
  54. {
  55. if ($meta->isMappedSuperclass) {
  56. return; // ignore mappedSuperclasses for now
  57. }
  58. $config = array();
  59. // collect metadata from inherited classes
  60. foreach (array_reverse(class_parents($meta->name)) as $parentClass) {
  61. // read only inherited mapped classes
  62. if ($this->objectManager->getMetadataFactory()->hasMetadataFor($parentClass)) {
  63. $this->driver->readExtendedMetadata($this->objectManager->getClassMetadata($parentClass), $config);
  64. }
  65. }
  66. $this->driver->readExtendedMetadata($meta, $config);
  67. if ($config) {
  68. $this->driver->validateFullMetadata($meta, $config);
  69. // cache the metadata
  70. $cacheId = self::getCacheId($meta->name, $this->extensionNamespace);
  71. if ($cacheDriver = $this->objectManager->getMetadataFactory()->getCacheDriver()) {
  72. $cacheDriver->save($cacheId, $config, null);
  73. }
  74. }
  75. return $config;
  76. }
  77. /**
  78. * Get the cache id
  79. *
  80. * @param string $className
  81. * @param string $extensionNamespace
  82. * @return string
  83. */
  84. public static function getCacheId($className, $extensionNamespace)
  85. {
  86. return $className . '\\$' . strtoupper(str_replace('\\', '_', $extensionNamespace)) . '_CLASSMETADATA';
  87. }
  88. /**
  89. * Get the extended driver instance which will
  90. * read the metadata required by extension
  91. *
  92. * @param object $omDriver
  93. * @throws DriverException if driver was not found in extension
  94. * @return Gedmo\Mapping\Driver
  95. */
  96. private function getDriver($omDriver)
  97. {
  98. $driver = null;
  99. $className = get_class($omDriver);
  100. $driverName = substr($className, strrpos($className, '\\') + 1);
  101. if ($driverName == 'DriverChain') {
  102. $driver = new Driver\Chain();
  103. foreach ($omDriver->getDrivers() as $namespace => $nestedOmDriver) {
  104. $driver->addDriver($this->getDriver($nestedOmDriver), $namespace);
  105. }
  106. } else {
  107. $driverName = substr($driverName, 0, strpos($driverName, 'Driver'));
  108. // create driver instance
  109. $driverClassName = $this->extensionNamespace . '\Mapping\Driver\\' . $driverName;
  110. if (!class_exists($driverClassName)) {
  111. // @TODO: implement XML driver also
  112. $driverClassName = $this->extensionNamespace . '\Mapping\Driver\Annotation';
  113. if (!class_exists($driverClassName)) {
  114. throw new \Gedmo\Exception\RuntimeException("Failed to fallback to annotation driver: ({$driverClassName}), extension driver was not found.");
  115. }
  116. }
  117. $driver = new $driverClassName();
  118. if ($driver instanceof \Gedmo\Mapping\Driver\File) {
  119. $driver->setPaths($omDriver->getPaths());
  120. }
  121. }
  122. return $driver;
  123. }
  124. }