/** * @param ChangeSet $changeset * @return bool|object */ public function applyChangeSet(ChangeSet $changeset) { $now = new \DateTime(); if ($changeset->getChangeAt() == null || $changeset->getChangeAt()->diff($now)->invert) { return false; } if ($changeset->getAction() == LoggableListener::ACTION_CREATE && $changeset->getObjectId() != null) { throw new \Exception("changeSet invalid {$changeset->getId()} create with object id"); } if ($changeset->getAction() != LoggableListener::ACTION_CREATE && $changeset->getObjectId() == null) { throw new \Exception("changeSet invalid {$changeset->getId()} no objectId found but no create Action"); } $data = $changeset->getData(); if ($changeset->getObjectId() == null) { //create a new one $r = new \ReflectionClass($changeset->getObjectClass()); $entity = $r->newInstanceWithoutConstructor(); } else { //edit $entity = $this->_em->find($changeset->getObjectClass(), $changeset->getObjectId()); } if ($changeset->getAction() == LoggableListener::ACTION_REMOVE) { //very rudimental remove... dont care about sitdeffects $this->_em->remove($entity); $this->_em->remove($changeset); $this->_em->flush(); return true; } $wrapped = new EntityWrapper($entity, $this->_em); $objectMeta = $wrapped->getMetadata(); foreach ($data as $field => $value) { if ($objectMeta->isSingleValuedAssociation($field)) { $mapping = $objectMeta->getAssociationMapping($field); $value = $value ? $this->_em->getReference($mapping['targetEntity'], $value) : null; } if (property_exists($changeset->getObjectClass(), $field)) { $wrapped->setPropertyValue($field, $value); } } if ($changeset->getObjectId() == null) { //MANY_TO_ONE create new one foreach ($objectMeta->getAssociationMappings() as $associationMapping) { if ($associationMapping['type'] != \Doctrine\ORM\Mapping\ClassMetadata::MANY_TO_ONE) { continue; } $one = $objectMeta->getReflectionProperty($associationMapping['fieldName'])->getValue($entity); if (array_key_exists('inversedBy', $associationMapping)) { $field = $associationMapping['inversedBy']; $associationMeta = $this->_em->getClassMetadata($associationMapping['targetEntity']); $associationMeta->getReflectionProperty($field)->getValue($one)->add($entity); } } } $object = $wrapped->getObject(); $object->removeScheduledChangeDate(); $this->_em->persist($object); $this->_em->remove($changeset); $this->_em->flush(); return $object; }
/** * Get log entries * * @access public * @param array $entities ,default is empty array * @param array $objectIds ,default is empty array * @param string $objectClass ,default is null * @param int $status ,default is null * @return array log entries array */ public function getLogEntries($entities = array(), $objectIds = array(), $objectClass = null, $status = null) { $parameters = array(); $queryBuilder = $this->createQueryBuilder("log"); $queryBuilder->select("log")->addOrderBy('log.version', Criteria::DESC)->addOrderBy('log.id', Criteria::DESC); if (count($entities) > 0) { // assuming array of entities belong to them class $entity = reset($entities); $objectIds = array(); $wrapped = new EntityWrapper($entity, $this->getEntityManager()); $objectClass = $wrapped->getMetadata()->name; // collect entitites ids array_shift($entities); $objectIds[] = $wrapped->getIdentifier(); foreach ($entities as $entity) { $wrapped = new EntityWrapper($entity, $this->getEntityManager()); $objectIds[] = $wrapped->getIdentifier(); } } if (!is_null($status)) { $parameters["objectStatus"] = $status; $queryBuilder->andWhere($queryBuilder->expr()->eq('log.objectStatus', ":objectStatus")); } if (!is_null($objectClass)) { $parameters["objectClass"] = $objectClass; $queryBuilder->andWhere($queryBuilder->expr()->eq('log.objectClass', ":objectClass")); } if (count($objectIds) > 0) { $parameters["objectIds"] = $objectIds; $queryBuilder->andWhere($queryBuilder->expr()->in('log.objectId', ":objectIds")); } $queryBuilder->setParameters($parameters); return $queryBuilder->getQuery()->getResult(); }
public function getLogEntriesQueryBuilder($entity) { $wrapped = new EntityWrapper($entity, $this->_em); $objectClass = $wrapped->getMetadata()->name; $objectId = $wrapped->getIdentifier(); $qb = $this->createQueryBuilder('a')->where('a.objectId = :objectId AND a.objectClass = :objectClass')->orderBy('a.loggedAt', 'DESC')->setParameters(compact('objectId', 'objectClass')); return $qb; }
public function nullifyLogEntry($entity, $rootVersion) { $wrapped = new EntityWrapper($entity, $this->_em); $objectClass = $wrapped->getMetadata()->name; $objectId = $wrapped->getIdentifier(); $logEntry = $this->findOneBy(compact('objectId', 'objectClass', 'rootVersion')); if ($logEntry) { $logEntry->setData(null); $this->getEntityManager()->flush($logEntry); } }
/** * Get the query for loading of log entries * * @param object $entity * @param integer $rootVersion * * @return Query */ public function getLogEntriesQueryRoot($entity, $rootVersion = null) { $wrapped = new EntityWrapper($entity, $this->_em); $objectClass = $wrapped->getMetadata()->name; $meta = $this->getClassMetadata(); $dql = "SELECT log FROM {$meta->name} log"; $dql .= " WHERE log.objectId = :objectId"; $dql .= " AND log.objectClass = :objectClass"; $dql .= " AND log.rootVersion <= :rootVersion"; $dql .= " ORDER BY log.version DESC"; $objectId = $wrapped->getIdentifier(); $q = $this->_em->createQuery($dql); $q->setParameters(compact('objectId', 'objectClass', 'rootVersion')); return $q; }
/** * Reverts given $entity to $revision by * restoring all fields from that $revision. * After this operation you will need to * persist and flush the $entity. * * @param object $entity * @param integer $version * @throws \Gedmo\Exception\UnexpectedValueException * @return void */ public function revert($entity, $version = 1) { $wrapped = new EntityWrapper($entity, $this->_em); $objectMeta = $wrapped->getMetadata(); $objectClass = $objectMeta->name; //$objectMeta = $this->_em->getClassMetadata($objectClass); $meta = $this->getClassMetadata(); $dql = "SELECT log FROM {$meta->name} log"; $dql .= " WHERE log.objectId = :objectId"; $dql .= " AND log.objectClass = :objectClass"; $dql .= " AND log.version <= :version"; $dql .= " ORDER BY log.version ASC"; $objectId = $wrapped->getIdentifier(); $q = $this->_em->createQuery($dql); $q->setParameters(compact('objectId', 'objectClass', 'version')); $logs = $q->getResult(); if ($logs) { $config = $this->getLoggableListener()->getConfiguration($this->_em, $objectMeta->name); $fields = $config['versioned']; $filled = false; while (($log = array_pop($logs)) && !$filled) { if ($data = $log->getData()) { foreach ($data as $field => $value) { if (in_array($field, $fields)) { if ($objectMeta->isSingleValuedAssociation($field)) { $mapping = $objectMeta->getAssociationMapping($field); $value = $value ? $this->_em->getReference($mapping['targetEntity'], $value) : null; } $wrapped->setPropertyValue($field, $value); unset($fields[array_search($field, $fields)]); } } } $filled = count($fields) === 0; } if (count($fields)) { throw new \Gedmo\Exception\UnexpectedValueException('Cound not fully revert the entity to version: '.$version); } } else { throw new \Gedmo\Exception\UnexpectedValueException('Count not find any log entries under version: '.$version); } }
/** * Loads all translations with all translatable * fields from the given entity * * @param object $entity Must implement Translatable * @return array list of translations in locale groups */ public function findTranslations($entity) { $result = array(); $wrapped = new EntityWrapper($entity, $this->_em); if ($wrapped->hasValidIdentifier()) { $entityId = $wrapped->getIdentifier(); $entityClass = $wrapped->getMetadata()->name; $translationMeta = $this->getClassMetadata(); // table inheritance support $qb = $this->_em->createQueryBuilder(); $qb->select('trans.content, trans.field, trans.locale')->from($translationMeta->rootEntityName, 'trans')->where('trans.foreignKey = :entityId', 'trans.objectClass = :entityClass')->orderBy('trans.locale'); $q = $qb->getQuery(); $data = $q->execute(compact('entityId', 'entityClass'), Query::HYDRATE_ARRAY); if ($data && is_array($data) && count($data)) { foreach ($data as $row) { $result[$row['locale']][$row['field']] = $row['content']; } } } return $result; }
protected function revertObjectBySingleLog(Log $log, EntityWrapper $wrapped) { if (!$log->getOlddata()) { return false; } $objectMeta = $wrapped->getMetadata(); foreach ($log->getOlddata() as $field => $value) { if ($objectMeta->isSingleValuedAssociation($field)) { $mapping = $objectMeta->getAssociationMapping($field); $value = $value ? $this->_em->getReference($mapping['targetEntity'], $value) : null; } if (is_array($value) && count($value) == 3 && array_key_exists('date', $value) && array_key_exists('timezone', $value)) { //check if look likes a DateTime $value = new \DateTime($value['date'], new \DateTimeZone($value['timezone'])); } $wrapped->setPropertyValue($field, $value); } return true; }