• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PHPCSStandards / PHP_CodeSniffer / 14471881504

15 Apr 2025 02:22PM UTC coverage: 77.605%. Remained the same
14471881504

Pull #999

github

web-flow
Merge 97fd6a533 into 142199d59
Pull Request #999: AbstractSniffTestCase: flag missing `.fixed` files

19354 of 24939 relevant lines covered (77.61%)

78.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Files/LocalFile.php
1
<?php
2
/**
3
 * A local file represents a chunk of text has a file system location.
4
 *
5
 * @author    Greg Sherwood <gsherwood@squiz.net>
6
 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
7
 * @license   https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8
 */
9

10
namespace PHP_CodeSniffer\Files;
11

12
use PHP_CodeSniffer\Config;
13
use PHP_CodeSniffer\Ruleset;
14
use PHP_CodeSniffer\Util\Cache;
15
use PHP_CodeSniffer\Util\Common;
16

17
class LocalFile extends File
18
{
19

20

21
    /**
22
     * Creates a LocalFile object and sets the content.
23
     *
24
     * @param string                   $path    The absolute path to the file.
25
     * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
26
     * @param \PHP_CodeSniffer\Config  $config  The config data for the run.
27
     *
28
     * @return void
29
     */
30
    public function __construct($path, Ruleset $ruleset, Config $config)
×
31
    {
32
        $this->path = trim($path);
×
33
        if (Common::isReadable($this->path) === false) {
×
34
            parent::__construct($this->path, $ruleset, $config);
×
35
            $error = 'Error opening file; file no longer exists or you do not have access to read the file';
×
36
            $this->addMessage(true, $error, 1, 1, 'Internal.LocalFile', [], 5, false);
×
37
            $this->ignored = true;
×
38
            return;
×
39
        }
40

41
        // Before we go and spend time tokenizing this file, just check
42
        // to see if there is a tag up top to indicate that the whole
43
        // file should be ignored. It must be on one of the first two lines.
44
        if ($config->annotations === true) {
×
45
            $handle = fopen($this->path, 'r');
×
46
            if ($handle !== false) {
×
47
                $firstContent  = fgets($handle);
×
48
                $firstContent .= fgets($handle);
×
49
                fclose($handle);
×
50

51
                if (stripos($firstContent, 'phpcs:ignorefile') !== false) {
×
52
                    // We are ignoring the whole file.
53
                    $this->ignored = true;
×
54
                    return;
×
55
                }
56
            }
57
        }
58

59
        $this->reloadContent();
×
60

61
        parent::__construct($this->path, $ruleset, $config);
×
62

63
    }//end __construct()
64

65

66
    /**
67
     * Loads the latest version of the file's content from the file system.
68
     *
69
     * @return void
70
     */
71
    public function reloadContent()
×
72
    {
73
        $this->setContent(file_get_contents($this->path));
×
74

75
    }//end reloadContent()
76

77

78
    /**
79
     * Processes the file.
80
     *
81
     * @return void
82
     */
83
    public function process()
×
84
    {
85
        if ($this->ignored === true) {
×
86
            return;
×
87
        }
88

89
        if ($this->configCache['cache'] === false) {
×
90
            parent::process();
×
91
            return;
×
92
        }
93

94
        $hash  = md5_file($this->path);
×
95
        $hash .= fileperms($this->path);
×
96
        $cache = Cache::get($this->path);
×
97
        if ($cache !== false && $cache['hash'] === $hash) {
×
98
            // We can't filter metrics, so just load all of them.
99
            $this->metrics = $cache['metrics'];
×
100

101
            if ($this->configCache['recordErrors'] === true) {
×
102
                // Replay the cached errors and warnings to filter out the ones
103
                // we don't need for this specific run.
104
                $this->configCache['cache'] = false;
×
105
                $this->replayErrors($cache['errors'], $cache['warnings']);
×
106
                $this->configCache['cache'] = true;
×
107
            } else {
108
                $this->errorCount   = $cache['errorCount'];
×
109
                $this->warningCount = $cache['warningCount'];
×
110
                $this->fixableCount = $cache['fixableCount'];
×
111
            }
112

113
            if (PHP_CODESNIFFER_VERBOSITY > 0
×
114
                || (PHP_CODESNIFFER_CBF === true && empty($this->config->files) === false)
×
115
            ) {
116
                echo "[loaded from cache]... ";
×
117
            }
118

119
            $this->numTokens = $cache['numTokens'];
×
120
            $this->fromCache = true;
×
121
            return;
×
122
        }//end if
123

124
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
×
125
            echo PHP_EOL;
×
126
        }
127

128
        parent::process();
×
129

130
        $cache = [
131
            'hash'         => $hash,
×
132
            'errors'       => $this->errors,
×
133
            'warnings'     => $this->warnings,
×
134
            'metrics'      => $this->metrics,
×
135
            'errorCount'   => $this->errorCount,
×
136
            'warningCount' => $this->warningCount,
×
137
            'fixableCount' => $this->fixableCount,
×
138
            'numTokens'    => $this->numTokens,
×
139
        ];
140

141
        Cache::set($this->path, $cache);
×
142

143
        // During caching, we don't filter out errors in any way, so
144
        // we need to do that manually now by replaying them.
145
        if ($this->configCache['recordErrors'] === true) {
×
146
            $this->configCache['cache'] = false;
×
147
            $this->replayErrors($this->errors, $this->warnings);
×
148
            $this->configCache['cache'] = true;
×
149
        }
150

151
    }//end process()
152

153

154
    /**
155
     * Clears and replays error and warnings for the file.
156
     *
157
     * Replaying errors and warnings allows for filtering rules to be changed
158
     * and then errors and warnings to be reapplied with the new rules. This is
159
     * particularly useful while caching.
160
     *
161
     * @param array $errors   The list of errors to replay.
162
     * @param array $warnings The list of warnings to replay.
163
     *
164
     * @return void
165
     */
166
    private function replayErrors($errors, $warnings)
×
167
    {
168
        $this->errors       = [];
×
169
        $this->warnings     = [];
×
170
        $this->errorCount   = 0;
×
171
        $this->warningCount = 0;
×
172
        $this->fixableCount = 0;
×
173

174
        $this->replayingErrors = true;
×
175

176
        foreach ($errors as $line => $lineErrors) {
×
177
            foreach ($lineErrors as $column => $colErrors) {
×
178
                foreach ($colErrors as $error) {
×
179
                    $this->activeListener = $error['listener'];
×
180
                    $this->addMessage(
×
181
                        true,
×
182
                        $error['message'],
×
183
                        $line,
×
184
                        $column,
×
185
                        $error['source'],
×
186
                        [],
×
187
                        $error['severity'],
×
188
                        $error['fixable']
×
189
                    );
190
                }
191
            }
192
        }
193

194
        foreach ($warnings as $line => $lineErrors) {
×
195
            foreach ($lineErrors as $column => $colErrors) {
×
196
                foreach ($colErrors as $error) {
×
197
                    $this->activeListener = $error['listener'];
×
198
                    $this->addMessage(
×
199
                        false,
×
200
                        $error['message'],
×
201
                        $line,
×
202
                        $column,
×
203
                        $error['source'],
×
204
                        [],
×
205
                        $error['severity'],
×
206
                        $error['fixable']
×
207
                    );
208
                }
209
            }
210
        }
211

212
        $this->replayingErrors = false;
×
213

214
    }//end replayErrors()
215

216

217
}//end class
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc