/**
  * Create edges between versions graph
  *
  * @param Graph  $graph
  * @param string $className
  */
 private function createEdges(Graph $graph, $className)
 {
     $migrationsAnnotations = $this->reader->getClassMigrationMethodInfo($className);
     $parentVertex = $graph->hasVertex($className) ? $graph->getVertex($className) : $graph->createVertex($className);
     foreach ($migrationsAnnotations as $migrationsAnnotation) {
         if ($migrationsAnnotation->annotation->from) {
             $fromClass = $migrationsAnnotation->annotation->from;
             $fromVertex = $graph->hasVertex($fromClass) ? $graph->getVertex($fromClass) : $graph->createVertex($fromClass);
             if (!$parentVertex->hasEdgeTo($fromVertex)) {
                 $edge = $fromVertex->createEdgeTo($parentVertex);
                 $this->annotations[$this->getEdgeId($edge)] = $migrationsAnnotation;
                 $this->createEdges($graph, $fromClass);
             }
         }
         if ($migrationsAnnotation->annotation->to) {
             $toClass = $migrationsAnnotation->annotation->to;
             $fromVertex = $graph->hasVertex($toClass) ? $graph->getVertex($toClass) : $graph->createVertex($toClass);
             if (!$parentVertex->hasEdgeTo($fromVertex)) {
                 $edge = $parentVertex->createEdgeTo($fromVertex);
                 $this->annotations[$this->getEdgeId($edge)] = $migrationsAnnotation;
                 $this->createEdges($graph, $toClass);
             }
         }
     }
 }
 /**
  * Walks through all migrateFrom functions
  * With empty object
  *
  * @param $fromClassName
  * @param $path
  * @param $visited
  */
 private function migrateFrom($fromClassName, $path = array(), &$visited = array())
 {
     $migrations = $this->versionReader->getClassMigrationMethodInfo($fromClassName);
     // farther version found
     $found = true;
     /** @var MethodInfo $methodInfo */
     foreach ($migrations as $methodInfo) {
         if ($methodInfo->annotation->from) {
             $migration = array('from' => $methodInfo->annotation->from, 'to' => $fromClassName);
             $migrationId = $this->getMigrationId($migration);
             if (false === in_array($migrationId, $visited)) {
                 // mark as visited
                 array_push($visited, $migrationId);
                 // add to log for testing
                 array_push($this->testedMigrations['from'], $migration);
                 $migrationsPath = $path;
                 $migrationsPath[] = $methodInfo;
                 $this->migrateFrom($methodInfo->annotation->from, $migrationsPath, $visited);
                 $found = false;
             }
         }
     }
     if (true === $found) {
         $this->migrateFromPath($fromClassName, $path);
     }
 }
 /**
  * Migrate object to specified version.
  *
  * @param mixed  $object       Object instance.
  * @param string $otherVersion Version name.
  *
  * @throws \LogicException
  * @throws Exception\VersionPathNotFoundException
  *
  * @return mixed Migrated object.
  */
 public function migrateToVersion($object, $otherVersion)
 {
     $className = get_class($object);
     if ($className !== $this->className) {
         throw new \LogicException('Converter for class "' . $className . '" can not migrate "' . $className . '" objects.');
     }
     $otherVersionClassName = $this->reader->getClassNameByVersion($className, $otherVersion);
     if ($otherVersionClassName) {
         $object = $this->migrateToClass($object, $otherVersionClassName);
     }
     return $object;
 }
 public function testGetClassNameByVersion()
 {
     $versionReader = new VersionReader(new AnnotationReader());
     $this->assertEquals('Evispa\\ObjectMigration\\Tests\\Mock\\MockCodeV4', $versionReader->getClassNameByVersion('Evispa\\ObjectMigration\\Tests\\Mock\\MockCodeV1', 'vnd.evispa.simple-code.v4'));
 }