LogEntryRepository.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <?php
  2. namespace Gedmo\Loggable\Entity\Repository;
  3. use Doctrine\ORM\EntityRepository;
  4. use Gedmo\Loggable\AbstractLoggableListener as Loggable;
  5. /**
  6. * The LogEntryRepository has some useful functions
  7. * to interact with log entries.
  8. *
  9. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  10. * @package Gedmo\Loggable\Entity\Repository
  11. * @subpackage LogEntryRepository
  12. * @link http://www.gediminasm.org
  13. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  14. */
  15. class LogEntryRepository extends EntityRepository
  16. {
  17. /**
  18. * Loads all log entries for the
  19. * given $entity
  20. *
  21. * @param object $entity
  22. * @return array
  23. */
  24. public function getLogEntries($entity)
  25. {
  26. $q = $this->getLogEntriesQuery($entity);
  27. return $q->getResult();
  28. }
  29. /**
  30. * Get the query for loading of log entries
  31. *
  32. * @param object $entity
  33. * @return Query
  34. */
  35. public function getLogEntriesQuery($entity)
  36. {
  37. $objectClass = get_class($entity);
  38. $objectMeta = $this->_em->getClassMetadata($objectClass);
  39. $meta = $this->getClassMetadata();
  40. $dql = "SELECT log FROM {$meta->name} log";
  41. $dql .= " WHERE log.objectId = :objectId";
  42. $dql .= " AND log.objectClass = :objectClass";
  43. $dql .= " ORDER BY log.version DESC";
  44. $identifierField = $objectMeta->getSingleIdentifierFieldName();
  45. $objectId = $objectMeta->getReflectionProperty($identifierField)->getValue($entity);
  46. $q = $this->_em->createQuery($dql);
  47. $q->setParameters(compact('objectId', 'objectClass', 'order'));
  48. return $q;
  49. }
  50. /**
  51. * Reverts given $entity to $revision by
  52. * restoring all fields from that $revision.
  53. * After this operation you will need to
  54. * persist and flush the $entity.
  55. *
  56. * @param object $entity
  57. * @param integer $version
  58. * @throws \Gedmo\Exception\UnexpectedValueException
  59. * @return void
  60. */
  61. public function revert($entity, $version = 1)
  62. {
  63. $objectClass = get_class($entity);
  64. $objectMeta = $this->_em->getClassMetadata($objectClass);
  65. $meta = $this->getClassMetadata();
  66. $dql = "SELECT log FROM {$meta->name} log";
  67. $dql .= " WHERE log.objectId = :objectId";
  68. $dql .= " AND log.objectClass = :objectClass";
  69. $dql .= " AND log.version <= :version";
  70. $dql .= " ORDER BY log.version ASC";
  71. $identifierField = $objectMeta->getSingleIdentifierFieldName();
  72. $objectId = $objectMeta->getReflectionProperty($identifierField)->getValue($entity);
  73. $q = $this->_em->createQuery($dql);
  74. $q->setParameters(compact('objectId', 'objectClass', 'version'));
  75. $logs = $q->getResult();
  76. if ($logs) {
  77. $fields = $objectMeta->fieldNames;
  78. foreach ($objectMeta->associationMappings as $mapping) {
  79. if ($objectMeta->isSingleValuedAssociation($mapping['fieldName'])) {
  80. $fields[] = $mapping['fieldName'];
  81. }
  82. }
  83. unset($fields[$objectMeta->getSingleIdentifierFieldName()]);
  84. $filled = false;
  85. while (($log = array_pop($logs)) && !$filled) {
  86. if ($data = $log->getData()) {
  87. foreach ($data as $field => $value) {
  88. if (in_array($field, $fields)) {
  89. if ($objectMeta->isSingleValuedAssociation($field)) {
  90. $mapping = $objectMeta->getAssociationMapping($field);
  91. $value = $this->_em->getReference($mapping['targetEntity'], $value);
  92. }
  93. $objectMeta->getReflectionProperty($field)->setValue($entity, $value);
  94. unset($fields[array_search($field, $fields)]);
  95. }
  96. }
  97. }
  98. $filled = count($fields) === 0;
  99. }
  100. if (count($fields)) {
  101. throw new \Gedmo\Exception\UnexpectedValueException('Cound not fully revert the entity to version: '.$version);
  102. }
  103. } else {
  104. throw new \Gedmo\Exception\UnexpectedValueException('Count not find any log entries under version: '.$version);
  105. }
  106. }
  107. }