Skip to content

Commit ef20773

Browse files
committed
Work in progress
Better Composer support Better namespace support
1 parent 352bd2b commit ef20773

File tree

3 files changed

+130
-57
lines changed

3 files changed

+130
-57
lines changed

src/PHPFUI/InstaDoc/Controller.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function display() : string
7777
{
7878
$fullClassName = $this->requestedNamespace . '\\' . $this->requestedClass;
7979
$tree = NamespaceTree::getNamespaceTree($fullClassName);
80-
$fullClassPath = $tree->getPathForClass($this->requestedClass);
80+
$fullClassPath = $tree->getPathForClass($fullClassName);
8181
$section = new Section($this);
8282
$mainColumn->add($section->getBreadCrumbs($fullClassName));
8383
$mainColumn->add($section->getMenu($fullClassName));
@@ -209,13 +209,13 @@ public function getMenu() : \PHPFUI\AccordionMenu
209209
return $this->accordionMenu;
210210
}
211211

212-
foreach ($this->fileManager->getAllNamespaces() as $namespace)
213-
{
214-
foreach ($this->fileManager->getClassesInNamespace($namespace) as $file => $class)
215-
{
216-
NamespaceTree::getNamespaceTree($namespace . '\\' . $class, $file);
217-
}
218-
}
212+
// foreach ($this->fileManager->getAllNamespaces() as $namespace)
213+
// {
214+
// foreach ($this->fileManager->getClassesInNamespace($namespace) as $file => $class)
215+
// {
216+
// NamespaceTree::getNamespaceTree($namespace . '\\' . $class, $file);
217+
// }
218+
// }
219219

220220
NamespaceTree::setActiveClass($this->requestedClass);
221221
NamespaceTree::setActiveNamespace($this->requestedNamespace);

src/PHPFUI/InstaDoc/FileManager.php

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class FileManager
66
{
77
private const CLASSES = '.Classes';
88
private const GIT = '.Git';
9+
private const SOURCE = '.Source';
910
private const NAMESPACE = '.Namespace';
1011

1112
private const REPO_ROOT = '.Root';
@@ -44,10 +45,7 @@ public function getComposerPath() : string
4445
*/
4546
public function addNamespace(string $namespace, string $directory, bool $localGit = false) : FileManager
4647
{
47-
$this->includedNamespaces[$namespace][FileManager::REPO_ROOT] = $directory;
48-
$this->includedNamespaces[$namespace][] = $directory;
49-
$this->includedNamespaces[$namespace][FileManager::GIT] = $localGit;
50-
$this->includedNamespaces[$namespace][FileManager::CLASSES] = [];
48+
NamespaceTree::addNameSpace($namespace, $directory, $localGit);
5149

5250
return $this;
5351
}
@@ -91,7 +89,7 @@ public function getAllNamespaceDirectories(bool $rescan = true) : array
9189

9290
if ($this->composerJsonPath)
9391
{
94-
$directories = $this->getAllVendorDirectories($this->composerJsonPath);
92+
$directories = $this->getAllVendorDirectories();
9593
}
9694
$directories = array_merge($directories, $this->includedNamespaces);
9795

@@ -117,27 +115,21 @@ public function getAllNamespaces() : array
117115
* Read the composer files to get all namespaces for include
118116
* libraries.
119117
*/
120-
public function getAllVendorDirectories() : array
118+
private function getAllVendorDirectories() : array
121119
{
122-
$composerJsonPath = $this->composerJsonPath;
123-
124-
if (is_dir($composerJsonPath))
125-
{
126-
$composerJsonPath .= '/composer.lock';
127-
}
120+
$composerJsonPath = $this->composerJsonPath . 'composer.lock';
128121
$composerJsonPath = str_replace('//', '/', $composerJsonPath);
129122
$json = json_decode(@file_get_contents($composerJsonPath), true);
130123

131124
if (! $json)
132125
{
133126
throw new \Exception("{$composerJsonPath} does not appear to be a valid composer.lock file");
134127
}
135-
$dir = str_replace('composer.lock', '', $composerJsonPath);
136128
$directories = [];
137129

138130
foreach ($json['packages'] as $package)
139131
{
140-
$packagePath = $dir . 'vendor/' . $package['name'];
132+
$packagePath = $this->composerJsonPath . 'vendor/' . $package['name'];
141133
$autoload = $package['autoload'] ?? [];
142134
$namespace = $sourceDir = '';
143135
$autoLoadTypes = ['psr-4', 'psr-0', 'classmap'];
@@ -166,7 +158,11 @@ public function getAllVendorDirectories() : array
166158
$path = str_replace('//', '/', $path);
167159
$directories[$namespace][FileManager::GIT] = false;
168160
$directories[$namespace][FileManager::REPO_ROOT] = $path;
169-
$directories[$namespace][] = $path . $sourceDir;
161+
if (is_array($sourceDir))
162+
{
163+
$sourceDir = reset($sourceDir);
164+
}
165+
$directories[$namespace][FileManager::SOURCE][$path . $sourceDir] = true;
170166
$directories[$namespace][FileManager::CLASSES] = [];
171167
}
172168
}
@@ -191,16 +187,29 @@ public function getClassesInNamespace(string $namespace) : array
191187
$files = $this->getFilesInNamespace($namespace, $extension);
192188
$namespaceInfo = $this->namespaces[$namespace];
193189

190+
// echo '<pre>';
194191
foreach ($files as $file)
195192
{
196-
$class = substr($file, strlen($namespaceInfo[0]));
197-
$class = str_replace('/', '\\', $class);
198-
if (0 === strpos($class, $namespace))
193+
$file = str_replace('\\', '/', $file);
194+
foreach ($namespaceInfo[FileManager::SOURCE] as $directory => $value)
199195
{
200-
$class = substr($class, strlen($namespace));
196+
$directory = str_replace('\\', '/', $directory);
197+
$start = strpos($file, $directory);
198+
if ($start !== false)
199+
{
200+
$class = substr($file, $start + strlen($directory));
201+
$class = str_replace(['/', '.php'], ['\\', ''], $class);
202+
if (strpos($class, $namespace) !== 0)
203+
{
204+
$class = str_replace('\\\\', '\\', $namespace . '\\' . $class);
205+
}
206+
$class = substr($class, strlen($namespace) + 1);
207+
// echo "add class {$namespace} => {$class}\n";
208+
$classes[$file] = $class;
209+
}
201210
}
202-
$classes[$file] = substr($class, 0, strlen($class) - strlen($extension));
203211
}
212+
// echo '<pre>';
204213

205214
return $this->namespaces[$namespace][FileManager::CLASSES] = $classes;
206215
}
@@ -219,32 +228,18 @@ public function getFilesInNamespace(string $namespace, string $extension = '') :
219228
throw new \Exception('In ' . __METHOD__ . " -> {$namespace} was not found.");
220229
}
221230

222-
foreach ($this->namespaces[$namespace] as $key => $directory)
231+
$directory = $this->namespaces[$namespace][FileManager::REPO_ROOT];
232+
if (is_dir($directory))
223233
{
224-
if ('integer' != gettype($key))
225-
{
226-
continue;
227-
}
234+
$directory = str_replace('\\', '/', $directory);
235+
$rdi = new \RecursiveDirectoryIterator($directory);
236+
$iterator = new \RecursiveIteratorIterator($rdi, \RecursiveIteratorIterator::CHILD_FIRST);
228237

229-
if (is_file($directory))
230-
{
231-
if ($this->hasExtension($filename, $extension))
232-
{
233-
$files[] = $directory;
234-
}
235-
}
236-
else
238+
foreach ($iterator as $filename => $fileInfo)
237239
{
238-
$directory = str_replace('\\', '/', $directory);
239-
$rdi = new \RecursiveDirectoryIterator($directory);
240-
$iterator = new \RecursiveIteratorIterator($rdi, \RecursiveIteratorIterator::CHILD_FIRST);
241-
242-
foreach ($iterator as $filename => $fileInfo)
240+
if (! $fileInfo->isDir() && $this->hasExtension($filename, $extension))
243241
{
244-
if (! $fileInfo->isDir() && $this->hasExtension($filename, $extension))
245-
{
246-
$files[] = $filename;
247-
}
242+
$files[] = $filename;
248243
}
249244
}
250245
}
@@ -299,6 +294,8 @@ public function load(string $file = '') : FileManager
299294
{
300295
$file = $this->getSerializedName($file);
301296

297+
@unlink($file);
298+
302299
if (! file_exists($file))
303300
{
304301
$this->rescan();
@@ -333,7 +330,7 @@ public function rescan() : FileManager
333330
*/
334331
public function save(string $file = '') : FileManager
335332
{
336-
file_put_contents($this->getSerializedName($file), json_encode($this->namespaces));
333+
file_put_contents($this->getSerializedName($file), json_encode($this->namespaces, JSON_PRETTY_PRINT));
337334

338335
return $this;
339336
}

src/PHPFUI/InstaDoc/NamespaceTree.php

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,97 @@ class NamespaceTree
99
private static $controller;
1010
private static $root = null;
1111

12+
/**
13+
* @var array indexed by namespace part containing a NamespaceTree
14+
*/
1215
private $children = [];
16+
17+
/**
18+
* @var array indexed by fully qualified class name containing the file name
19+
*/
1320
private $classes = [];
21+
22+
/**
23+
* @var string of the namespace part
24+
*/
1425
private $namespace = '';
26+
27+
/**
28+
* @var NamespaceTree our parent
29+
*/
1530
private $parent = null;
1631

1732
// only we can make us to ensure the tree is good
1833
private function __construct()
1934
{
2035
}
2136

37+
public static function addNamespace(string $namespace, string $directory, bool $localGit) : void
38+
{
39+
/*
40+
$parts = explode('\\', str_replace('\\\\', '\\', $fullClassName));
41+
$rootNamespace = array_shift($parts);
42+
$className = array_pop($parts);
43+
44+
if (! isset(self::getRoot()->children[$rootNamespace]))
45+
{
46+
$root = new NamespaceTree();
47+
$root->namespace = $rootNamespace;
48+
self::$root->children[$rootNamespace] = $root;
49+
}
50+
$parent = self::$root->children[$rootNamespace];
51+
52+
foreach ($parts as $partialNamespace)
53+
{
54+
if (! isset($parent->children[$partialNamespace]))
55+
{
56+
$child = new NamespaceTree();
57+
$child->namespace = $partialNamespace;
58+
$child->parent = $parent;
59+
$parent->children[$partialNamespace] = $child;
60+
$parent = $child;
61+
}
62+
else
63+
{
64+
$parent = $parent->children[$partialNamespace];
65+
}
66+
}
67+
*/
68+
$node = self::findNamespace($namespace);
69+
70+
$iterator = new \DirectoryIterator($directory);
71+
foreach ($iterator as $fileinfo)
72+
{
73+
$filename = $fileinfo->getFilename();
74+
if ($fileinfo->isDir() && strpos($filename, '.') === false)
75+
{
76+
self::addNamespace($namespace.'/'.$filename, $directory.'/'.$filename, $localGit);
77+
}
78+
elseif (strpos($filename, '.php') == strlen($filename) - 4)
79+
{
80+
$class = substr($filename, 0, strlen($filename) - 4);
81+
$class = $namespace . '\\' . $class;
82+
$file = $directory . '/' . $filename;
83+
$node->addClass($class, $file);
84+
}
85+
}
86+
}
87+
88+
public static function findNamespace(string $namespace) : NamespaceTree
89+
{
90+
$parts = explode('\\', $namespace);
91+
92+
93+
94+
}
95+
96+
private function addClass(string $class, string $file) : NamespaceTree
97+
{
98+
$this->classes[$class] = $file;
99+
100+
return $this;
101+
}
102+
22103
/**
23104
* Returns array of all classes
24105
*/
@@ -88,7 +169,7 @@ public function getNamespace() : string
88169
* Returns the NamespaceTree node that contains the class. If
89170
* you pass in a path, it sets the class's path.
90171
*/
91-
public static function getNamespaceTree(string $fullClassName, string $path = '') : NamespaceTree
172+
public static function getNamespaceTree(string $fullClassName) : NamespaceTree
92173
{
93174
$parts = explode('\\', str_replace('\\\\', '\\', $fullClassName));
94175
$rootNamespace = array_shift($parts);
@@ -117,11 +198,6 @@ public static function getNamespaceTree(string $fullClassName, string $path = ''
117198
$parent = $parent->children[$partialNamespace];
118199
}
119200
}
120-
// if we have a path, then we should add the class, otherwise we are just doing a lookup
121-
if ($path)
122-
{
123-
$parent->classes[$className] = $path;
124-
}
125201

126202
return $parent;
127203
}

0 commit comments

Comments
 (0)