Пример #1
0
 /**
  * @param string $action
  * @param object $entity
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  *
  * @throws \ReflectionException
  */
 protected function createLogEntity($action, $entity)
 {
     $entityClassName = $this->getEntityClassName($entity);
     if (!$this->checkAuditable($entityClassName)) {
         return;
     }
     $user = $this->getLoadedUser();
     $organization = $this->getOrganization();
     if (!$organization) {
         return;
     }
     $uow = $this->em->getUnitOfWork();
     $meta = $this->getConfig($entityClassName);
     $entityMeta = $this->em->getClassMetadata($entityClassName);
     $logEntryMeta = $this->em->getClassMetadata($this->getLogEntityClass());
     /** @var AbstractAudit $logEntry */
     $logEntry = $logEntryMeta->newInstance();
     $logEntry->setAction($action);
     $logEntry->setObjectClass($meta->name);
     $logEntry->setLoggedAt();
     $logEntry->setUser($user);
     $logEntry->setOrganization($organization);
     $logEntry->setObjectName(method_exists($entity, '__toString') ? (string) $entity : $meta->name);
     $entityId = $this->getIdentifier($entity);
     if (!$entityId && $action === self::ACTION_CREATE) {
         $this->pendingLogEntityInserts[spl_object_hash($entity)] = $logEntry;
     }
     $logEntry->setObjectId($entityId);
     $newValues = [];
     if ($action !== self::ACTION_REMOVE && count($meta->propertyMetadata)) {
         foreach ($uow->getEntityChangeSet($entity) as $field => $changes) {
             if (!isset($meta->propertyMetadata[$field])) {
                 continue;
             }
             $old = $changes[0];
             $new = $changes[1];
             if ($old == $new) {
                 continue;
             }
             $fieldMapping = null;
             if ($entityMeta->hasField($field)) {
                 $fieldMapping = $entityMeta->getFieldMapping($field);
                 if ($fieldMapping['type'] === 'date') {
                     // leave only date
                     $utc = new \DateTimeZone('UTC');
                     if ($old && $old instanceof \DateTime) {
                         $old->setTimezone($utc);
                         $old = new \DateTime($old->format('Y-m-d'), $utc);
                     }
                     if ($new && $new instanceof \DateTime) {
                         $new->setTimezone($utc);
                         $new = new \DateTime($new->format('Y-m-d'), $utc);
                     }
                 }
             }
             if ($old instanceof \DateTime && $new instanceof \DateTime && $old->getTimestamp() == $new->getTimestamp()) {
                 continue;
             }
             if ($entityMeta->isSingleValuedAssociation($field) && $new) {
                 $oid = spl_object_hash($new);
                 $value = $this->getIdentifier($new);
                 if (!is_array($value) && !$value) {
                     $this->pendingRelatedEntities[$oid][] = ['log' => $logEntry, 'field' => $field];
                 }
                 $method = $meta->propertyMetadata[$field]->method;
                 if ($old !== null) {
                     // check if an object has the required method to avoid a fatal error
                     if (!method_exists($old, $method)) {
                         throw new \ReflectionException(sprintf('Try to call to undefined method %s::%s', get_class($old), $method));
                     }
                     $old = $old->{$method}();
                 }
                 if ($new !== null) {
                     // check if an object has the required method to avoid a fatal error
                     if (!method_exists($new, $method)) {
                         throw new \ReflectionException(sprintf('Try to call to undefined method %s::%s', get_class($new), $method));
                     }
                     $new = $new->{$method}();
                 }
             }
             $newValues[$field] = ['old' => $old, 'new' => $new, 'type' => $this->getFieldType($entityMeta, $field)];
         }
         $entityIdentifier = $this->getEntityIdentifierString($entity);
         if (!empty($this->collectionLogData[$entityClassName][$entityIdentifier])) {
             $collectionData = $this->collectionLogData[$entityClassName][$entityIdentifier];
             foreach ($collectionData as $field => $changes) {
                 if (!isset($meta->propertyMetadata[$field])) {
                     continue;
                 }
                 if ($changes['old'] != $changes['new']) {
                     $newValues[$field] = $changes;
                     $newValues[$field]['type'] = $this->getFieldType($entityMeta, $field);
                 }
             }
             unset($this->collectionLogData[$entityClassName][$entityIdentifier]);
             if (!$this->collectionLogData[$entityClassName]) {
                 unset($this->collectionLogData[$entityClassName]);
             }
         }
         foreach ($newValues as $field => $newValue) {
             $logEntry->createField($field, $newValue['type'], $newValue['new'], $newValue['old']);
         }
     }
     if ($action === self::ACTION_UPDATE && 0 === count($newValues)) {
         return;
     }
     $version = 1;
     if ($action !== self::ACTION_CREATE) {
         $version = $this->getNewVersion($logEntryMeta, $entity);
         if (empty($version)) {
             // was versioned later
             $version = 1;
         }
     }
     $logEntry->setVersion($version);
     $this->em->persist($logEntry);
     $uow->computeChangeSet($logEntryMeta, $logEntry);
     $logEntryFieldMeta = $this->em->getClassMetadata($this->auditEntityMapper->getAuditEntryFieldClass($this->getLoadedUser()));
     foreach ($logEntry->getFields() as $field) {
         $this->em->persist($field);
         $uow->computeChangeSet($logEntryFieldMeta, $field);
     }
 }
Пример #2
0
 /**
  * @expectedException \InvalidArgumentException
  * @expectedExceptionMessage Audit entry field not found for "Oro\Bundle\UserBundle\Entity\User"
  */
 public function testAuditEntryFieldFailed()
 {
     $this->mapper->getAuditEntryFieldClass($this->getUser());
 }