/** * @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); } }
/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Audit entry field not found for "Oro\Bundle\UserBundle\Entity\User" */ public function testAuditEntryFieldFailed() { $this->mapper->getAuditEntryFieldClass($this->getUser()); }