Skip to content

Commit 599862a

Browse files
committed
Added simple file to class
1 parent 00c7cd8 commit 599862a

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace Phpactor\ClassFileConverter\Adapter\Simple;
4+
5+
use Phpactor\ClassFileConverter\Domain\FileToClass;
6+
use Phpactor\ClassFileConverter\Domain\ClassNameCandidates;
7+
use Phpactor\ClassFileConverter\Domain\FilePath;
8+
use Phpactor\ClassFileConverter\Domain\ClassName;
9+
10+
class SimpleFileToClass implements FileToClass
11+
{
12+
public function fileToClassCandidates(FilePath $filePath): ClassNameCandidates
13+
{
14+
$classNames = [];
15+
16+
$className = $this->getClassNameFromFile($filePath->__toString());
17+
18+
if ($className) {
19+
$classNames[] = ClassName::fromString($className);
20+
}
21+
22+
return ClassNameCandidates::fromClassNames($classNames);
23+
}
24+
25+
/**
26+
* Return the class name from a file.
27+
*
28+
* Taken from http://stackoverflow.com/questions/7153000/get-class-name-from-file
29+
*
30+
* @param string $file
31+
*
32+
* @return string
33+
*/
34+
private function getClassNameFromFile($file)
35+
{
36+
$fp = fopen($file, 'r');
37+
38+
$class = $namespace = $buffer = '';
39+
$i = 0;
40+
41+
while (!$class) {
42+
if (feof($fp)) {
43+
break;
44+
}
45+
46+
// Read entire lines to prevent keyword truncation
47+
for ($line = 0; $line <= 20; $line++) {
48+
$buffer .= fgets($fp);
49+
}
50+
$tokens = @token_get_all($buffer);
51+
52+
if (strpos($buffer, '{') === false) {
53+
continue;
54+
}
55+
56+
for (; $i < count($tokens); $i++) {
57+
if ($tokens[$i][0] === T_NAMESPACE) {
58+
for ($j = $i + 1; $j < count($tokens); $j++) {
59+
if ($tokens[$j][0] === T_STRING) {
60+
$namespace .= '\\' . $tokens[$j][1];
61+
} elseif ($tokens[$j] === '{' || $tokens[$j] === ';') {
62+
break;
63+
}
64+
}
65+
}
66+
67+
if ($tokens[$i][0] === T_CLASS) {
68+
for ($j = $i + 1; $j < count($tokens); $j++) {
69+
if ($tokens[$j][0] === T_STRING) {
70+
$class = $tokens[$i + 2][1];
71+
break 2;
72+
}
73+
}
74+
}
75+
}
76+
}
77+
78+
if (!trim($class)) {
79+
return;
80+
}
81+
82+
fclose($fp);
83+
84+
return ltrim($namespace . '\\' . $class, '\\');
85+
}
86+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Phpactor\ClassFileConverter\Tests\Integration\Simple;
4+
5+
use Phpactor\ClassFileConverter\Tests\Integration\IntegrationTestCase;
6+
use Symfony\Component\Filesystem\Filesystem;
7+
use Phpactor\ClassFileConverter\Adapter\Simple\SimpleFileToClass;
8+
use Phpactor\ClassFileConverter\Domain\FilePath;
9+
use Phpactor\ClassFileConverter\Domain\ClassNameCandidates;
10+
use Phpactor\ClassFileConverter\Domain\ClassName;
11+
12+
class SimpleFileToClassTest extends IntegrationTestCase
13+
{
14+
/**
15+
* @var SimpleFileToClass
16+
*/
17+
private $fileToClass;
18+
19+
public function setUp()
20+
{
21+
$this->initWorkspace();
22+
$projectPath = __DIR__.'/project';
23+
$filesystem = new Filesystem();
24+
$filesystem->mirror($projectPath, $this->workspacePath());
25+
$this->fileToClass = new SimpleFileToClass();
26+
}
27+
28+
public function testFileToClass()
29+
{
30+
$candidates = $this->fileToClass->fileToClassCandidates(FilePath::fromString(__DIR__ . '/project/lib/Foobar.php'));
31+
32+
$this->assertEquals(ClassNameCandidates::fromClassNames([
33+
ClassName::fromString('Acme\\Foobar')
34+
]), $candidates);
35+
}
36+
37+
public function testFileToNoCandidates()
38+
{
39+
$candidates = $this->fileToClass->fileToClassCandidates(FilePath::fromString(__DIR__ . '/project/lib/NoClasses.php'));
40+
41+
$this->assertEquals(ClassNameCandidates::fromClassNames([]), $candidates);
42+
}
43+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Acme;
4+
5+
class Foobar
6+
{
7+
}

tests/Integration/Simple/project/lib/NoClasses.php

Whitespace-only changes.

0 commit comments

Comments
 (0)