Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\VarDumper\Caster;
|
Chris@0
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * Represents a file or a URL.
|
Chris@0
|
16 *
|
Chris@0
|
17 * @author Nicolas Grekas <p@tchwork.com>
|
Chris@0
|
18 */
|
Chris@0
|
19 class LinkStub extends ConstStub
|
Chris@0
|
20 {
|
Chris@0
|
21 private static $vendorRoots;
|
Chris@0
|
22 private static $composerRoots;
|
Chris@0
|
23
|
Chris@0
|
24 public function __construct($label, $line = 0, $href = null)
|
Chris@0
|
25 {
|
Chris@0
|
26 $this->value = $label;
|
Chris@0
|
27
|
Chris@0
|
28 if (null === $href) {
|
Chris@0
|
29 $href = $label;
|
Chris@0
|
30 }
|
Chris@0
|
31 if (!is_string($href)) {
|
Chris@0
|
32 return;
|
Chris@0
|
33 }
|
Chris@0
|
34 if (0 === strpos($href, 'file://')) {
|
Chris@0
|
35 if ($href === $label) {
|
Chris@0
|
36 $label = substr($label, 7);
|
Chris@0
|
37 }
|
Chris@0
|
38 $href = substr($href, 7);
|
Chris@0
|
39 } elseif (false !== strpos($href, '://')) {
|
Chris@0
|
40 $this->attr['href'] = $href;
|
Chris@0
|
41
|
Chris@0
|
42 return;
|
Chris@0
|
43 }
|
Chris@0
|
44 if (!file_exists($href)) {
|
Chris@0
|
45 return;
|
Chris@0
|
46 }
|
Chris@0
|
47 if ($line) {
|
Chris@0
|
48 $this->attr['line'] = $line;
|
Chris@0
|
49 }
|
Chris@0
|
50 if ($label !== $this->attr['file'] = realpath($href) ?: $href) {
|
Chris@0
|
51 return;
|
Chris@0
|
52 }
|
Chris@0
|
53 if ($composerRoot = $this->getComposerRoot($href, $inVendor)) {
|
Chris@0
|
54 $this->attr['ellipsis'] = strlen($href) - strlen($composerRoot) + 1;
|
Chris@0
|
55 $this->attr['ellipsis-type'] = 'path';
|
Chris@0
|
56 $this->attr['ellipsis-tail'] = 1 + ($inVendor ? 2 + strlen(implode(array_slice(explode(DIRECTORY_SEPARATOR, substr($href, 1 - $this->attr['ellipsis'])), 0, 2))) : 0);
|
Chris@0
|
57 } elseif (3 < count($ellipsis = explode(DIRECTORY_SEPARATOR, $href))) {
|
Chris@0
|
58 $this->attr['ellipsis'] = 2 + strlen(implode(array_slice($ellipsis, -2)));
|
Chris@0
|
59 $this->attr['ellipsis-type'] = 'path';
|
Chris@0
|
60 $this->attr['ellipsis-tail'] = 1;
|
Chris@0
|
61 }
|
Chris@0
|
62 }
|
Chris@0
|
63
|
Chris@0
|
64 private function getComposerRoot($file, &$inVendor)
|
Chris@0
|
65 {
|
Chris@0
|
66 if (null === self::$vendorRoots) {
|
Chris@0
|
67 self::$vendorRoots = array();
|
Chris@0
|
68
|
Chris@0
|
69 foreach (get_declared_classes() as $class) {
|
Chris@0
|
70 if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
|
Chris@0
|
71 $r = new \ReflectionClass($class);
|
Chris@0
|
72 $v = dirname(dirname($r->getFileName()));
|
Chris@0
|
73 if (file_exists($v.'/composer/installed.json')) {
|
Chris@0
|
74 self::$vendorRoots[] = $v.DIRECTORY_SEPARATOR;
|
Chris@0
|
75 }
|
Chris@0
|
76 }
|
Chris@0
|
77 }
|
Chris@0
|
78 }
|
Chris@0
|
79 $inVendor = false;
|
Chris@0
|
80
|
Chris@0
|
81 if (isset(self::$composerRoots[$dir = dirname($file)])) {
|
Chris@0
|
82 return self::$composerRoots[$dir];
|
Chris@0
|
83 }
|
Chris@0
|
84
|
Chris@0
|
85 foreach (self::$vendorRoots as $root) {
|
Chris@0
|
86 if ($inVendor = 0 === strpos($file, $root)) {
|
Chris@0
|
87 return $root;
|
Chris@0
|
88 }
|
Chris@0
|
89 }
|
Chris@0
|
90
|
Chris@0
|
91 $parent = $dir;
|
Chris@0
|
92 while (!@file_exists($parent.'/composer.json')) {
|
Chris@0
|
93 if (!@file_exists($parent)) {
|
Chris@0
|
94 // open_basedir restriction in effect
|
Chris@0
|
95 break;
|
Chris@0
|
96 }
|
Chris@0
|
97 if ($parent === dirname($parent)) {
|
Chris@0
|
98 return self::$composerRoots[$dir] = false;
|
Chris@0
|
99 }
|
Chris@0
|
100
|
Chris@0
|
101 $parent = dirname($parent);
|
Chris@0
|
102 }
|
Chris@0
|
103
|
Chris@0
|
104 return self::$composerRoots[$dir] = $parent.DIRECTORY_SEPARATOR;
|
Chris@0
|
105 }
|
Chris@0
|
106 }
|