db backup prior to drupal security update
[yaffs-website] / vendor / phpunit / php-code-coverage / src / CodeCoverage / Report / Factory.php
1 <?php
2 /*
3  * This file is part of the PHP_CodeCoverage package.
4  *
5  * (c) Sebastian Bergmann <sebastian@phpunit.de>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * Factory for PHP_CodeCoverage_Report_Node_* object graphs.
13  *
14  * @since Class available since Release 1.1.0
15  */
16 class PHP_CodeCoverage_Report_Factory
17 {
18     /**
19      * @param  PHP_CodeCoverage                       $coverage
20      * @return PHP_CodeCoverage_Report_Node_Directory
21      */
22     public function create(PHP_CodeCoverage $coverage)
23     {
24         $files      = $coverage->getData();
25         $commonPath = $this->reducePaths($files);
26         $root       = new PHP_CodeCoverage_Report_Node_Directory(
27             $commonPath,
28             null
29         );
30
31         $this->addItems(
32             $root,
33             $this->buildDirectoryStructure($files),
34             $coverage->getTests(),
35             $coverage->getCacheTokens()
36         );
37
38         return $root;
39     }
40
41     /**
42      * @param PHP_CodeCoverage_Report_Node_Directory $root
43      * @param array                                  $items
44      * @param array                                  $tests
45      * @param bool                                   $cacheTokens
46      */
47     private function addItems(PHP_CodeCoverage_Report_Node_Directory $root, array $items, array $tests, $cacheTokens)
48     {
49         foreach ($items as $key => $value) {
50             if (substr($key, -2) == '/f') {
51                 $key = substr($key, 0, -2);
52
53                 if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
54                     $root->addFile($key, $value, $tests, $cacheTokens);
55                 }
56             } else {
57                 $child = $root->addDirectory($key);
58                 $this->addItems($child, $value, $tests, $cacheTokens);
59             }
60         }
61     }
62
63     /**
64      * Builds an array representation of the directory structure.
65      *
66      * For instance,
67      *
68      * <code>
69      * Array
70      * (
71      *     [Money.php] => Array
72      *         (
73      *             ...
74      *         )
75      *
76      *     [MoneyBag.php] => Array
77      *         (
78      *             ...
79      *         )
80      * )
81      * </code>
82      *
83      * is transformed into
84      *
85      * <code>
86      * Array
87      * (
88      *     [.] => Array
89      *         (
90      *             [Money.php] => Array
91      *                 (
92      *                     ...
93      *                 )
94      *
95      *             [MoneyBag.php] => Array
96      *                 (
97      *                     ...
98      *                 )
99      *         )
100      * )
101      * </code>
102      *
103      * @param  array $files
104      * @return array
105      */
106     private function buildDirectoryStructure($files)
107     {
108         $result = array();
109
110         foreach ($files as $path => $file) {
111             $path    = explode('/', $path);
112             $pointer = &$result;
113             $max     = count($path);
114
115             for ($i = 0; $i < $max; $i++) {
116                 if ($i == ($max - 1)) {
117                     $type = '/f';
118                 } else {
119                     $type = '';
120                 }
121
122                 $pointer = &$pointer[$path[$i] . $type];
123             }
124
125             $pointer = $file;
126         }
127
128         return $result;
129     }
130
131     /**
132      * Reduces the paths by cutting the longest common start path.
133      *
134      * For instance,
135      *
136      * <code>
137      * Array
138      * (
139      *     [/home/sb/Money/Money.php] => Array
140      *         (
141      *             ...
142      *         )
143      *
144      *     [/home/sb/Money/MoneyBag.php] => Array
145      *         (
146      *             ...
147      *         )
148      * )
149      * </code>
150      *
151      * is reduced to
152      *
153      * <code>
154      * Array
155      * (
156      *     [Money.php] => Array
157      *         (
158      *             ...
159      *         )
160      *
161      *     [MoneyBag.php] => Array
162      *         (
163      *             ...
164      *         )
165      * )
166      * </code>
167      *
168      * @param  array  $files
169      * @return string
170      */
171     private function reducePaths(&$files)
172     {
173         if (empty($files)) {
174             return '.';
175         }
176
177         $commonPath = '';
178         $paths      = array_keys($files);
179
180         if (count($files) == 1) {
181             $commonPath                 = dirname($paths[0]) . '/';
182             $files[basename($paths[0])] = $files[$paths[0]];
183
184             unset($files[$paths[0]]);
185
186             return $commonPath;
187         }
188
189         $max = count($paths);
190
191         for ($i = 0; $i < $max; $i++) {
192             // strip phar:// prefixes
193             if (strpos($paths[$i], 'phar://') === 0) {
194                 $paths[$i] = substr($paths[$i], 7);
195                 $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
196             }
197             $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
198
199             if (empty($paths[$i][0])) {
200                 $paths[$i][0] = DIRECTORY_SEPARATOR;
201             }
202         }
203
204         $done = false;
205         $max  = count($paths);
206
207         while (!$done) {
208             for ($i = 0; $i < $max - 1; $i++) {
209                 if (!isset($paths[$i][0]) ||
210                     !isset($paths[$i+1][0]) ||
211                     $paths[$i][0] != $paths[$i+1][0]) {
212                     $done = true;
213                     break;
214                 }
215             }
216
217             if (!$done) {
218                 $commonPath .= $paths[0][0];
219
220                 if ($paths[0][0] != DIRECTORY_SEPARATOR) {
221                     $commonPath .= DIRECTORY_SEPARATOR;
222                 }
223
224                 for ($i = 0; $i < $max; $i++) {
225                     array_shift($paths[$i]);
226                 }
227             }
228         }
229
230         $original = array_keys($files);
231         $max      = count($original);
232
233         for ($i = 0; $i < $max; $i++) {
234             $files[implode('/', $paths[$i])] = $files[$original[$i]];
235             unset($files[$original[$i]]);
236         }
237
238         ksort($files);
239
240         return substr($commonPath, 0, -1);
241     }
242 }