public function tearDown()
 {
     // Replace entity manager
     $moduleOptions = \SoliantEntityAudit\Module::getModuleOptions();
     $moduleOptions->setEntityManager($this->_oldEntityManager);
     \SoliantEntityAudit\Module::getModuleOptions()->setAuditedClassNames($this->_oldAuditedClassNames);
 }
 public function testDoesNotReturnRevisionEntity()
 {
     $sm = Bootstrap::getApplication()->getServiceManager();
     $em = \SoliantEntityAudit\Module::getModuleOptions()->getEntityManager();
     $helper = $sm->get('viewhelpermanager')->get('auditCurrentRevisionEntity');
     $entity = new Album();
     $revisionEntity = $helper($entity);
     $this->assertEquals(null, $revisionEntity);
 }
 public function testGettersAndSetters()
 {
     $entity = new Revision();
     $this->assertLessThanOrEqual(new \DateTime(), $entity->getTimestamp());
     $userClass = \SoliantEntityAudit\Module::getModuleOptions()->getUserEntityClassName();
     $user = new $userClass();
     $this->assertEquals($entity, $entity->setUser($user));
     $this->assertEquals($user, $entity->getUser());
     $entity->setComment('Test revision entity setter and getter');
     $this->assertEquals('Test revision entity setter and getter', $entity->getComment());
 }
 public function testGetRevisionEntitiesByEntityClass()
 {
     // Inserting data insures we will have a result > 0
     $em = \SoliantEntityAudit\Module::getModuleOptions()->getEntityManager();
     $service = \SoliantEntityAudit\Module::getModuleOptions()->getAuditService();
     $service->setComment('test 2');
     $entity = new Album();
     $entity->setTitle('Test 1');
     $em->persist($entity);
     $em->flush();
     $entity->setTitle('Test 2');
     $em->flush();
     $serviceEntities = $service->getRevisionEntities($entity);
     $this->assertGreaterThan(1, sizeof($service->getRevisionEntities(get_class($entity))));
 }
 public function testSetUser()
 {
     $serviceManager = Bootstrap::getApplication()->getServiceManager();
     $em = Bootstrap::getApplication()->getServiceManager()->get("doctrine.entitymanager.orm_default");
     $moduleOptions = clone $serviceManager->get('auditModuleOptions');
     $moduleOptions->setDefaults(array());
     $userClass = \SoliantEntityAudit\Module::getModuleOptions()->getUserEntityClassName();
     $user = new $userClass();
     $user->setEmail('test');
     $user->setPassword('test');
     $em->persist($user);
     $em->flush();
     $moduleOptions->setUser($user);
     $this->assertEquals($user, $moduleOptions->getUser());
 }
 public function testPaginatorCanAcceptAuditedClassName()
 {
     $sm = Bootstrap::getApplication()->getServiceManager();
     $em = \SoliantEntityAudit\Module::getModuleOptions()->getEntityManager();
     $helper = $sm->get('viewhelpermanager')->get('auditRevisionEntityPaginator');
     $revisionEntities = $em->getRepository('SoliantEntityAudit\\Entity\\RevisionEntity')->findAll();
     $count = sizeof($revisionEntities);
     $paginator = $helper($page = 0, get_class(array_shift($revisionEntities)->getTargetEntity()));
     $paginatedcount = 0;
     foreach ($paginator as $row) {
         $paginatedcount++;
     }
     $this->assertGreaterThan(0, $count);
     $this->assertEquals($count, $paginatedcount);
 }
 public function getTargetEntity()
 {
     $entityManager = \SoliantEntityAudit\Module::getModuleOptions()->getEntityManager();
     return $entityManager->getRepository($entityManager->getRepository($this->getAuditEntityClass())->findOneBy($this->getEntityKeys())->getAuditedEntityClass())->findOneBy($this->getEntityKeys());
 }
 /**
  * Gets the names of all mapped classes known to this driver.
  *
  * @return array The names of all mapped classes known to this driver.
  */
 function getAllClassNames()
 {
     $moduleOptions = \SoliantEntityAudit\Module::getModuleOptions();
     $entityManager = $moduleOptions->getEntityManager();
     $metadataFactory = $entityManager->getMetadataFactory();
     $auditEntities = array();
     foreach ($moduleOptions->getAuditedClassNames() as $name => $targetClassOptions) {
         $auditClassName = "SoliantEntityAudit\\Entity\\" . str_replace('\\', '_', $name);
         $auditEntities[] = $auditClassName;
         $auditedClassMetadata = $metadataFactory->getMetadataFor($name);
         // FIXME:  done in autoloader
         foreach ($auditedClassMetadata->getAssociationMappings() as $mapping) {
             if (isset($mapping['joinTable']['name'])) {
                 $auditJoinTableClassName = "SoliantEntityAudit\\Entity\\" . str_replace('\\', '_', $mapping['joinTable']['name']);
                 $auditEntities[] = $auditJoinTableClassName;
                 $moduleOptions->addJoinClass($auditJoinTableClassName, $mapping);
             }
         }
     }
     // Add revision (manage here rather than separate namespace)
     $auditEntities[] = 'SoliantEntityAudit\\Entity\\Revision';
     $auditEntities[] = 'SoliantEntityAudit\\Entity\\RevisionEntity';
     return $auditEntities;
 }
 /**
  * Dynamically scope an audit class
  *
  * @param  string $className
  * @return false|string
  */
 public function loadClass($className, $type)
 {
     $moduleOptions = \SoliantEntityAudit\Module::getModuleOptions();
     if (!$moduleOptions) {
         return;
     }
     $entityManager = $moduleOptions->getEntityManager();
     $auditClass = new ClassGenerator();
     //  Build a discovered many to many join class
     $joinClasses = $moduleOptions->getJoinClasses();
     if (in_array($className, array_keys($joinClasses))) {
         $auditClass->setNamespaceName("SoliantEntityAudit\\Entity");
         $auditClass->setName($className);
         $auditClass->setExtendedClass('AbstractAudit');
         $auditClass->addProperty('id', null, PropertyGenerator::FLAG_PROTECTED);
         $auditClass->addProperty('targetRevisionEntity', null, PropertyGenerator::FLAG_PROTECTED);
         $auditClass->addProperty('sourceRevisionEntity', null, PropertyGenerator::FLAG_PROTECTED);
         $auditClass->addMethod('getTargetRevisionEntity', array(), MethodGenerator::FLAG_PUBLIC, 'return $this->targetRevisionEntity;');
         $auditClass->addMethod('getSourceRevisionEntity', array(), MethodGenerator::FLAG_PUBLIC, 'return $this->sourceRevisionEntity;');
         $auditClass->addMethod('getId', array(), MethodGenerator::FLAG_PUBLIC, 'return $this->id;');
         $auditClass->addMethod('setTargetRevisionEntity', array(ParameterGenerator::fromArray(array('name' => 'value', 'type' => '\\SoliantEntityAudit\\Entity\\RevisionEntity'))), MethodGenerator::FLAG_PUBLIC, '$this->targetRevisionEntity = $value;' . "\n" . 'return $this;');
         $auditClass->addMethod('setSourceRevisionEntity', array(ParameterGenerator::fromArray(array('name' => 'value', 'type' => '\\SoliantEntityAudit\\Entity\\RevisionEntity'))), MethodGenerator::FLAG_PUBLIC, '$this->sourceRevisionEntity = $value;' . "\n" . 'return $this;');
         #            print_r($auditClass->generate());
         #            die();
         eval($auditClass->generate());
         return;
     }
     // Add revision reference getter and setter
     $auditClass->addProperty($moduleOptions->getRevisionEntityFieldName(), null, PropertyGenerator::FLAG_PROTECTED);
     $auditClass->addMethod('get' . $moduleOptions->getRevisionEntityFieldName(), array(), MethodGenerator::FLAG_PUBLIC, " return \$this->" . $moduleOptions->getRevisionEntityFieldName() . ";");
     $auditClass->addMethod('set' . $moduleOptions->getRevisionEntityFieldName(), array('value'), MethodGenerator::FLAG_PUBLIC, " \$this->" . $moduleOptions->getRevisionEntityFieldName() . " = \$value;\nreturn \$this;\r\n            ");
     // Verify this autoloader is used for target class
     #FIXME:  why is this sent work outside the set namespace?
     foreach ($moduleOptions->getAuditedClassNames() as $targetClass => $targetClassOptions) {
         $auditClassName = 'SoliantEntityAudit\\Entity\\' . str_replace('\\', '_', $targetClass);
         if ($auditClassName == $className) {
             $currentClass = $targetClass;
         }
         $autoloadClasses[] = $auditClassName;
     }
     if (!in_array($className, $autoloadClasses)) {
         return;
     }
     // Get fields from target entity
     $metadataFactory = $entityManager->getMetadataFactory();
     $auditedClassMetadata = $metadataFactory->getMetadataFor($currentClass);
     $fields = $auditedClassMetadata->getFieldNames();
     $identifiers = $auditedClassMetadata->getFieldNames();
     $service = \SoliantEntityAudit\Module::getModuleOptions()->getAuditService();
     // Generate audit entity
     foreach ($fields as $field) {
         $auditClass->addProperty($field, null, PropertyGenerator::FLAG_PROTECTED);
     }
     foreach ($auditedClassMetadata->getAssociationNames() as $associationName) {
         $auditClass->addProperty($associationName, null, PropertyGenerator::FLAG_PROTECTED);
         $fields[] = $associationName;
     }
     $auditClass->addMethod('getAssociationMappings', array(), MethodGenerator::FLAG_PUBLIC, "return unserialize('" . serialize($auditedClassMetadata->getAssociationMappings()) . "');");
     // Add exchange array method
     $setters = array();
     foreach ($fields as $fieldName) {
         $setters[] = '$this->' . $fieldName . ' = (isset($data["' . $fieldName . '"])) ? $data["' . $fieldName . '"]: null;';
         $arrayCopy[] = "    \"{$fieldName}\"" . ' => $this->' . $fieldName;
     }
     $auditClass->addMethod('getArrayCopy', array(), MethodGenerator::FLAG_PUBLIC, "return array(\n" . implode(",\n", $arrayCopy) . "\n);");
     $auditClass->addMethod('exchangeArray', array('data'), MethodGenerator::FLAG_PUBLIC, implode("\n", $setters));
     // Add function to return the entity class this entity audits
     $auditClass->addMethod('getAuditedEntityClass', array(), MethodGenerator::FLAG_PUBLIC, " return '" . addslashes($currentClass) . "';");
     $auditClass->setNamespaceName("SoliantEntityAudit\\Entity");
     $auditClass->setName(str_replace('\\', '_', $currentClass));
     // $auditedClassMetadata = $metadataFactory->getMetadataFor($currentClass);
     if ($auditedClassMetadata->parentClasses) {
         $auditClass->setExtendedClass(str_replace('\\', '_', array_pop($auditedClassMetadata->parentClasses)));
     } else {
         $auditClass->setExtendedClass('AbstractAudit');
     }
     foreach ($auditedClassMetadata->getAssociationMappings() as $mapping) {
         if (isset($mapping['joinTable']['name'])) {
             $auditJoinTableClassName = "SoliantEntityAudit\\Entity\\" . str_replace('\\', '_', $mapping['joinTable']['name']);
             $auditEntities[] = $auditJoinTableClassName;
             $moduleOptions->addJoinClass($auditJoinTableClassName, $mapping);
         }
     }
     #        if ($auditClass->getName() == 'AppleConnect_Entity_UserAuthenticationLog') {
     #            echo '<pre>';
     #            echo($auditClass->generate());
     #            die();
     #        }
     eval($auditClass->generate());
     #            die();
     return true;
 }
 public function associationTargetAction()
 {
     // When an association is requested all audit metadata must
     // be loaded in order to create the necessary join table
     // information
     $moduleOptions = $this->getServiceLocator()->get('auditModuleOptions');
     $this->mapAllAuditedClasses();
     foreach ($moduleOptions->getAuditedClassNames() as $className => $route) {
         $auditClassName = 'SoliantEntityAudit\\Entity\\' . str_replace('\\', '_', $className);
         $x = new $auditClassName();
     }
     $joinClasses = $moduleOptions->getJoinClasses();
     $page = (int) $this->getEvent()->getRouteMatch()->getParam('page');
     $joinTable = $this->getEvent()->getRouteMatch()->getParam('joinTable');
     $revisionEntityId = $this->getEvent()->getRouteMatch()->getParam('revisionEntityId');
     $auditService = $this->getServiceLocator()->get('auditService');
     $revisionEntity = \SoliantEntityAudit\Module::getModuleOptions()->getEntityManager()->getRepository('SoliantEntityAudit\\Entity\\RevisionEntity')->find($revisionEntityId);
     if (!$revisionEntity) {
         return $this->plugin('redirect')->toRoute('audit');
     }
     return array('revisionEntity' => $revisionEntity, 'page' => $page, 'joinTable' => $joinTable);
 }
 public function postFlush(PostFlushEventArgs $args)
 {
     if ($this->getEntities() and !$this->getInAuditTransaction()) {
         $this->setInAuditTransaction(true);
         $moduleOptions = Module::getModuleOptions();
         $entityManager = $moduleOptions->getEntityManager();
         $entityManager->beginTransaction();
         // Insert entites will trigger key generation and must be
         // re-exchanged (delete entites go out of scope)
         foreach ($this->getReexchangeEntities() as $entityMap) {
             $entityMap['auditEntity']->exchangeArray($this->getClassProperties($entityMap['entity']));
             $entityMap['revisionEntity']->setAuditEntity($entityMap['auditEntity']);
         }
         // Flush revision and revisionEntities
         $entityManager->persist($this->getRevision());
         foreach ($this->getRevisionEntities() as $entity) {
             $entityManager->persist($entity);
         }
         $entityManager->flush();
         foreach ($this->getEntities() as $entity) {
             $entityManager->persist($entity);
         }
         // Persist many to many collections
         foreach ($this->getCollections() as $value) {
             $mapping = $value->getMapping();
             if (!$mapping['isOwningSide']) {
                 continue;
             }
             $joinClassName = "SoliantEntityAudit\\Entity\\" . str_replace('\\', '_', $mapping['joinTable']['name']);
             $moduleOptions->addJoinClass($joinClassName, $mapping);
             $revisionEntity = null;
             foreach ($this->many2many as $map) {
                 if ($map['collection'] == $value) {
                     $revisionEntity = $map['revisionEntity'];
                     break;
                 }
             }
             if (!$revisionEntity) {
                 continue;
             }
             foreach ($value->getSnapshot() as $element) {
                 $audit = new $joinClassName();
                 // Get current inverse revision entity
                 $revisionEntities = $entityManager->getRepository('SoliantEntityAudit\\Entity\\RevisionEntity')->findBy(array('targetEntityClass' => $this->getEntityClass($element), 'entityKeys' => serialize(array('id' => $element->getId()))), array('id' => 'DESC'), 1);
                 $inverseRevisionEntity = reset($revisionEntities);
                 if (!$inverseRevisionEntity) {
                     // No inverse revision entity found
                     continue;
                 }
                 $audit->setTargetRevisionEntity($revisionEntity);
                 $audit->setSourceRevisionEntity($inverseRevisionEntity);
                 $entityManager->persist($audit);
             }
         }
         $entityManager->flush();
         $entityManager->commit();
         $this->resetEntities();
         $this->resetReexchangeEntities();
         $this->resetRevision();
         $this->resetRevisionEntities();
         $this->setInAuditTransaction(false);
     }
 }
 /**
  * Pass an audited entity or the audit entity
  * and return a collection of RevisionEntity s
  * for that record
  */
 public function getRevisionEntities($entity)
 {
     $entityManager = \SoliantEntityAudit\Module::getModuleOptions()->getEntityManager();
     if (gettype($entity) != 'string' and in_array(get_class($entity), array_keys(\SoliantEntityAudit\Module::getModuleOptions()->getAuditedClassNames()))) {
         $auditEntityClass = 'SoliantEntityAudit\\Entity\\' . str_replace('\\', '_', get_class($entity));
         $identifiers = $this->getEntityIdentifierValues($entity);
     } elseif ($entity instanceof AbstractAudit) {
         $auditEntityClass = get_class($entity);
         $identifiers = $this->getEntityIdentifierValues($entity, true);
     } else {
         $auditEntityClass = 'SoliantEntityAudit\\Entity\\' . str_replace('\\', '_', $entity);
     }
     $search = array('auditEntityClass' => $auditEntityClass);
     if (isset($identifiers)) {
         $search['entityKeys'] = serialize($identifiers);
     }
     return $entityManager->getRepository('SoliantEntityAudit\\Entity\\RevisionEntity')->findBy($search, array('id' => 'DESC'));
 }