/**
  * @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();
 }
Beispiel #3
0
 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;
 }
Beispiel #4
0
 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;
 }
Beispiel #6
0
    /**
     * 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;
 }