LogEntryRepository.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace Gedmo\Loggable\Entity\Repository;
  3. use Gedmo\Tool\Wrapper\EntityWrapper;
  4. use Doctrine\ORM\EntityRepository;
  5. use Gedmo\Loggable\LoggableListener;
  6. /**
  7. * The LogEntryRepository has some useful functions
  8. * to interact with log entries.
  9. *
  10. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  11. * @package Gedmo\Loggable\Entity\Repository
  12. * @subpackage LogEntryRepository
  13. * @link http://www.gediminasm.org
  14. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  15. */
  16. class LogEntryRepository extends EntityRepository
  17. {
  18. /**
  19. * Currently used loggable listener
  20. *
  21. * @var LoggableListener
  22. */
  23. private $listener;
  24. /**
  25. * Loads all log entries for the
  26. * given $entity
  27. *
  28. * @param object $entity
  29. * @return array
  30. */
  31. public function getLogEntries($entity)
  32. {
  33. $q = $this->getLogEntriesQuery($entity);
  34. return $q->getResult();
  35. }
  36. /**
  37. * Get the query for loading of log entries
  38. *
  39. * @param object $entity
  40. * @return Query
  41. */
  42. public function getLogEntriesQuery($entity)
  43. {
  44. $wrapped = new EntityWrapper($entity, $this->_em);
  45. $objectClass = $wrapped->getMetadata()->name;
  46. $meta = $this->getClassMetadata();
  47. $dql = "SELECT log FROM {$meta->name} log";
  48. $dql .= " WHERE log.objectId = :objectId";
  49. $dql .= " AND log.objectClass = :objectClass";
  50. $dql .= " ORDER BY log.version DESC";
  51. $objectId = $wrapped->getIdentifier();
  52. $q = $this->_em->createQuery($dql);
  53. $q->setParameters(compact('objectId', 'objectClass', 'order'));
  54. return $q;
  55. }
  56. /**
  57. * Reverts given $entity to $revision by
  58. * restoring all fields from that $revision.
  59. * After this operation you will need to
  60. * persist and flush the $entity.
  61. *
  62. * @param object $entity
  63. * @param integer $version
  64. * @throws \Gedmo\Exception\UnexpectedValueException
  65. * @return void
  66. */
  67. public function revert($entity, $version = 1)
  68. {
  69. $wrapped = new EntityWrapper($entity, $this->_em);
  70. $objectMeta = $wrapped->getMetadata();
  71. $objectClass = $objectMeta->name;
  72. //$objectMeta = $this->_em->getClassMetadata($objectClass);
  73. $meta = $this->getClassMetadata();
  74. $dql = "SELECT log FROM {$meta->name} log";
  75. $dql .= " WHERE log.objectId = :objectId";
  76. $dql .= " AND log.objectClass = :objectClass";
  77. $dql .= " AND log.version <= :version";
  78. $dql .= " ORDER BY log.version ASC";
  79. $objectId = $wrapped->getIdentifier();
  80. $q = $this->_em->createQuery($dql);
  81. $q->setParameters(compact('objectId', 'objectClass', 'version'));
  82. $logs = $q->getResult();
  83. if ($logs) {
  84. $config = $this->getLoggableListener()->getConfiguration($this->_em, $objectMeta->name);
  85. $fields = $config['versioned'];
  86. $filled = false;
  87. while (($log = array_pop($logs)) && !$filled) {
  88. if ($data = $log->getData()) {
  89. foreach ($data as $field => $value) {
  90. if (in_array($field, $fields)) {
  91. if ($objectMeta->isSingleValuedAssociation($field)) {
  92. $mapping = $objectMeta->getAssociationMapping($field);
  93. $value = $value ? $this->_em->getReference($mapping['targetEntity'], $value) : null;
  94. }
  95. $wrapped->setPropertyValue($field, $value);
  96. unset($fields[array_search($field, $fields)]);
  97. }
  98. }
  99. }
  100. $filled = count($fields) === 0;
  101. }
  102. /*if (count($fields)) {
  103. throw new \Gedmo\Exception\UnexpectedValueException('Could not fully revert the entity to version: '.$version);
  104. }*/
  105. } else {
  106. throw new \Gedmo\Exception\UnexpectedValueException('Could not find any log entries under version: '.$version);
  107. }
  108. }
  109. /**
  110. * Get the currently used LoggableListener
  111. *
  112. * @throws \Gedmo\Exception\RuntimeException - if listener is not found
  113. * @return LoggableListener
  114. */
  115. private function getLoggableListener()
  116. {
  117. if (is_null($this->listener)) {
  118. foreach ($this->_em->getEventManager()->getListeners() as $event => $listeners) {
  119. foreach ($listeners as $hash => $listener) {
  120. if ($listener instanceof LoggableListener) {
  121. $this->listener = $listener;
  122. break;
  123. }
  124. }
  125. if ($this->listener) {
  126. break;
  127. }
  128. }
  129. if (is_null($this->listener)) {
  130. throw new \Gedmo\Exception\RuntimeException('The loggable listener could not be found');
  131. }
  132. }
  133. return $this->listener;
  134. }
  135. }