1<?php
2/*
3 * This file is part of the php-code-coverage 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
11namespace SebastianBergmann\CodeCoverage;
12
13/**
14 * Filter for whitelisting of code coverage information.
15 */
16class Filter
17{
18    /**
19     * Source files that are whitelisted.
20     *
21     * @var array
22     */
23    private $whitelistedFiles = [];
24
25    /**
26     * Adds a directory to the whitelist (recursively).
27     *
28     * @param string $directory
29     * @param string $suffix
30     * @param string $prefix
31     */
32    public function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '')
33    {
34        $facade = new \File_Iterator_Facade;
35        $files  = $facade->getFilesAsArray($directory, $suffix, $prefix);
36
37        foreach ($files as $file) {
38            $this->addFileToWhitelist($file);
39        }
40    }
41
42    /**
43     * Adds a file to the whitelist.
44     *
45     * @param string $filename
46     */
47    public function addFileToWhitelist($filename)
48    {
49        $this->whitelistedFiles[realpath($filename)] = true;
50    }
51
52    /**
53     * Adds files to the whitelist.
54     *
55     * @param array $files
56     */
57    public function addFilesToWhitelist(array $files)
58    {
59        foreach ($files as $file) {
60            $this->addFileToWhitelist($file);
61        }
62    }
63
64    /**
65     * Removes a directory from the whitelist (recursively).
66     *
67     * @param string $directory
68     * @param string $suffix
69     * @param string $prefix
70     */
71    public function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '')
72    {
73        $facade = new \File_Iterator_Facade;
74        $files  = $facade->getFilesAsArray($directory, $suffix, $prefix);
75
76        foreach ($files as $file) {
77            $this->removeFileFromWhitelist($file);
78        }
79    }
80
81    /**
82     * Removes a file from the whitelist.
83     *
84     * @param string $filename
85     */
86    public function removeFileFromWhitelist($filename)
87    {
88        $filename = realpath($filename);
89
90        unset($this->whitelistedFiles[$filename]);
91    }
92
93    /**
94     * Checks whether a filename is a real filename.
95     *
96     * @param string $filename
97     *
98     * @return bool
99     */
100    public function isFile($filename)
101    {
102        if ($filename == '-' ||
103            strpos($filename, 'vfs://') === 0 ||
104            strpos($filename, 'xdebug://debug-eval') !== false ||
105            strpos($filename, 'eval()\'d code') !== false ||
106            strpos($filename, 'runtime-created function') !== false ||
107            strpos($filename, 'runkit created function') !== false ||
108            strpos($filename, 'assert code') !== false ||
109            strpos($filename, 'regexp code') !== false) {
110            return false;
111        }
112
113        return file_exists($filename);
114    }
115
116    /**
117     * Checks whether or not a file is filtered.
118     *
119     * @param string $filename
120     *
121     * @return bool
122     */
123    public function isFiltered($filename)
124    {
125        if (!$this->isFile($filename)) {
126            return true;
127        }
128
129        $filename = realpath($filename);
130
131        return !isset($this->whitelistedFiles[$filename]);
132    }
133
134    /**
135     * Returns the list of whitelisted files.
136     *
137     * @return array
138     */
139    public function getWhitelist()
140    {
141        return array_keys($this->whitelistedFiles);
142    }
143
144    /**
145     * Returns whether this filter has a whitelist.
146     *
147     * @return bool
148     */
149    public function hasWhitelist()
150    {
151        return !empty($this->whitelistedFiles);
152    }
153
154    /**
155     * Returns the whitelisted files.
156     *
157     * @return array
158     */
159    public function getWhitelistedFiles()
160    {
161        return $this->whitelistedFiles;
162    }
163
164    /**
165     * Sets the whitelisted files.
166     *
167     * @param array $whitelistedFiles
168     */
169    public function setWhitelistedFiles($whitelistedFiles)
170    {
171        $this->whitelistedFiles = $whitelistedFiles;
172    }
173}
174