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

PHPCSStandards / PHP_CodeSniffer / 14732455750

29 Apr 2025 01:27PM UTC coverage: 78.302% (+0.007%) from 78.295%
14732455750

Pull #1054

github

web-flow
Merge 4b912a7d0 into d12e243d8
Pull Request #1054: Standards: introduce `prepareInstalledStandardsForDisplay()` method

0 of 11 new or added lines in 3 files covered. (0.0%)

1 existing line in 1 file now uncovered.

19548 of 24965 relevant lines covered (78.3%)

86.08 hits per line

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

0.0
/src/Util/Standards.php
1
<?php
2
/**
3
 * Functions for helping process standards.
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\Util;
11

12
use DirectoryIterator;
13
use PHP_CodeSniffer\Config;
14

15
class Standards
16
{
17

18

19
    /**
20
     * Get a list of paths where standards are installed.
21
     *
22
     * Unresolvable relative paths will be excluded from the results.
23
     *
24
     * @return array
25
     */
26
    public static function getInstalledStandardPaths()
×
27
    {
28
        $ds = DIRECTORY_SEPARATOR;
×
29

30
        $installedPaths = [dirname(__DIR__, 2).$ds.'src'.$ds.'Standards'];
×
31
        $configPaths    = Config::getConfigData('installed_paths');
×
32
        if ($configPaths !== null) {
×
33
            $installedPaths = array_merge($installedPaths, explode(',', $configPaths));
×
34
        }
35

36
        $resolvedInstalledPaths = [];
×
37
        foreach ($installedPaths as $installedPath) {
×
38
            if (substr($installedPath, 0, 1) === '.') {
×
39
                $installedPath = Common::realpath(__DIR__.$ds.'..'.$ds.'..'.$ds.$installedPath);
×
40
                if ($installedPath === false) {
×
41
                    continue;
×
42
                }
43
            }
44

45
            $resolvedInstalledPaths[] = $installedPath;
×
46
        }
47

48
        return $resolvedInstalledPaths;
×
49

50
    }//end getInstalledStandardPaths()
51

52

53
    /**
54
     * Get the details of all coding standards installed.
55
     *
56
     * Coding standards are directories located in the
57
     * CodeSniffer/Standards directory. Valid coding standards
58
     * include a Sniffs subdirectory.
59
     *
60
     * The details returned for each standard are:
61
     * - path:      the path to the coding standard's main directory
62
     * - name:      the name of the coding standard, as sourced from the ruleset.xml file
63
     * - namespace: the namespace used by the coding standard, as sourced from the ruleset.xml file
64
     *
65
     * If you only need the paths to the installed standards,
66
     * use getInstalledStandardPaths() instead as it performs less work to
67
     * retrieve coding standard names.
68
     *
69
     * @param boolean $includeGeneric If true, the special "Generic"
70
     *                                coding standard will be included
71
     *                                if installed.
72
     * @param string  $standardsDir   A specific directory to look for standards
73
     *                                in. If not specified, PHP_CodeSniffer will
74
     *                                look in its default locations.
75
     *
76
     * @return array
77
     * @see    getInstalledStandardPaths()
78
     */
79
    public static function getInstalledStandardDetails(
×
80
        $includeGeneric=false,
81
        $standardsDir=''
82
    ) {
83
        $rulesets = [];
×
84

85
        if ($standardsDir === '') {
×
86
            $installedPaths = self::getInstalledStandardPaths();
×
87
        } else {
88
            $installedPaths = [$standardsDir];
×
89
        }
90

91
        foreach ($installedPaths as $standardsDir) {
×
92
            // Check if the installed dir is actually a standard itself.
93
            $csFile = $standardsDir.'/ruleset.xml';
×
94
            if (is_file($csFile) === true) {
×
95
                $rulesets[] = $csFile;
×
96
                continue;
×
97
            }
98

99
            if (is_dir($standardsDir) === false) {
×
100
                continue;
×
101
            }
102

103
            $di = new DirectoryIterator($standardsDir);
×
104
            foreach ($di as $file) {
×
105
                if ($file->isDir() === true && $file->isDot() === false) {
×
106
                    $filename = $file->getFilename();
×
107

108
                    // Ignore the special "Generic" standard.
109
                    if ($includeGeneric === false && $filename === 'Generic') {
×
110
                        continue;
×
111
                    }
112

113
                    // Valid coding standard dirs include a ruleset.
114
                    $csFile = $file->getPathname().'/ruleset.xml';
×
115
                    if (is_file($csFile) === true) {
×
116
                        $rulesets[] = $csFile;
×
117
                    }
118
                }
119
            }
120
        }//end foreach
121

122
        $installedStandards = [];
×
123

124
        foreach ($rulesets as $rulesetPath) {
×
125
            $ruleset = @simplexml_load_string(file_get_contents($rulesetPath));
×
126
            if ($ruleset === false) {
×
127
                continue;
×
128
            }
129

130
            $standardName = (string) $ruleset['name'];
×
131
            $dirname      = basename(dirname($rulesetPath));
×
132

133
            if (isset($ruleset['namespace']) === true) {
×
134
                $namespace = (string) $ruleset['namespace'];
×
135
            } else {
136
                $namespace = $dirname;
×
137
            }
138

139
            $installedStandards[$dirname] = [
×
140
                'path'      => dirname($rulesetPath),
×
141
                'name'      => $standardName,
×
142
                'namespace' => $namespace,
×
143
            ];
144
        }//end foreach
145

146
        return $installedStandards;
×
147

148
    }//end getInstalledStandardDetails()
149

150

151
    /**
152
     * Get a list of all coding standards installed.
153
     *
154
     * Coding standards are directories located in the
155
     * CodeSniffer/Standards directory. Valid coding standards
156
     * include a Sniffs subdirectory.
157
     *
158
     * @param boolean $includeGeneric If true, the special "Generic"
159
     *                                coding standard will be included
160
     *                                if installed.
161
     * @param string  $standardsDir   A specific directory to look for standards
162
     *                                in. If not specified, PHP_CodeSniffer will
163
     *                                look in its default locations.
164
     *
165
     * @return array
166
     * @see    isInstalledStandard()
167
     */
168
    public static function getInstalledStandards(
×
169
        $includeGeneric=false,
170
        $standardsDir=''
171
    ) {
172
        $installedStandards = [];
×
173

174
        if ($standardsDir === '') {
×
175
            $installedPaths = self::getInstalledStandardPaths();
×
176
        } else {
177
            $installedPaths = [$standardsDir];
×
178
        }
179

180
        foreach ($installedPaths as $standardsDir) {
×
181
            // Check if the installed dir is actually a standard itself.
182
            $csFile = $standardsDir.'/ruleset.xml';
×
183
            if (is_file($csFile) === true) {
×
184
                $basename = basename($standardsDir);
×
185
                $installedStandards[$basename] = $basename;
×
186
                continue;
×
187
            }
188

189
            if (is_dir($standardsDir) === false) {
×
190
                // Doesn't exist.
191
                continue;
×
192
            }
193

194
            $di = new DirectoryIterator($standardsDir);
×
195
            $standardsInDir = [];
×
196
            foreach ($di as $file) {
×
197
                if ($file->isDir() === true && $file->isDot() === false) {
×
198
                    $filename = $file->getFilename();
×
199

200
                    // Ignore the special "Generic" standard.
201
                    if ($includeGeneric === false && $filename === 'Generic') {
×
202
                        continue;
×
203
                    }
204

205
                    // Valid coding standard dirs include a ruleset.
206
                    $csFile = $file->getPathname().'/ruleset.xml';
×
207
                    if (is_file($csFile) === true) {
×
208
                        $standardsInDir[$filename] = $filename;
×
209
                    }
210
                }
211
            }
212

213
            natsort($standardsInDir);
×
214
            $installedStandards += $standardsInDir;
×
215
        }//end foreach
216

217
        return $installedStandards;
×
218

219
    }//end getInstalledStandards()
220

221

222
    /**
223
     * Determine if a standard is installed.
224
     *
225
     * Coding standards are directories located in the
226
     * CodeSniffer/Standards directory. Valid coding standards
227
     * include a ruleset.xml file.
228
     *
229
     * @param string $standard The name of the coding standard.
230
     *
231
     * @return boolean
232
     * @see    getInstalledStandards()
233
     */
234
    public static function isInstalledStandard($standard)
×
235
    {
236
        $path = self::getInstalledStandardPath($standard);
×
237
        if ($path !== null && strpos($path, 'ruleset.xml') !== false) {
×
238
            return true;
×
239
        } else {
240
            // This could be a custom standard, installed outside our
241
            // standards directory.
242
            $standard = Common::realpath($standard);
×
243
            if ($standard === false) {
×
244
                return false;
×
245
            }
246

247
            // Might be an actual ruleset file itUtil.
248
            // If it has an XML extension, let's at least try it.
249
            if (is_file($standard) === true
×
250
                && (substr(strtolower($standard), -4) === '.xml'
×
251
                || substr(strtolower($standard), -9) === '.xml.dist')
×
252
            ) {
253
                return true;
×
254
            }
255

256
            // If it is a directory with a ruleset.xml file in it,
257
            // it is a standard.
258
            $ruleset = rtrim($standard, ' /\\').DIRECTORY_SEPARATOR.'ruleset.xml';
×
259
            if (is_file($ruleset) === true) {
×
260
                return true;
×
261
            }
262
        }//end if
263

264
        return false;
×
265

266
    }//end isInstalledStandard()
267

268

269
    /**
270
     * Return the path of an installed coding standard.
271
     *
272
     * Coding standards are directories located in the
273
     * CodeSniffer/Standards directory. Valid coding standards
274
     * include a ruleset.xml file.
275
     *
276
     * @param string $standard The name of the coding standard.
277
     *
278
     * @return string|null
279
     */
280
    public static function getInstalledStandardPath($standard)
×
281
    {
282
        if (strpos($standard, '.') !== false) {
×
283
            return null;
×
284
        }
285

286
        $installedPaths = self::getInstalledStandardPaths();
×
287
        foreach ($installedPaths as $installedPath) {
×
288
            $standardPath = $installedPath.DIRECTORY_SEPARATOR.$standard;
×
289
            if (file_exists($standardPath) === false) {
×
290
                if (basename($installedPath) !== $standard) {
×
291
                    continue;
×
292
                }
293

294
                $standardPath = $installedPath;
×
295
            }
296

297
            $path = Common::realpath($standardPath.DIRECTORY_SEPARATOR.'ruleset.xml');
×
298

299
            if ($path !== false && is_file($path) === true) {
×
300
                return $path;
×
301
            } else if (Common::isPharFile($standardPath) === true) {
×
302
                $path = Common::realpath($standardPath);
×
303
                if ($path !== false) {
×
304
                    return $path;
×
305
                }
306
            }
307
        }//end foreach
308

309
        return null;
×
310

311
    }//end getInstalledStandardPath()
312

313

314
    /**
315
     * Prepares a list of installed coding standards for display.
316
     *
317
     * @return string
318
     */
NEW
319
    public static function prepareInstalledStandardsForDisplay()
×
320
    {
321
        $installedStandards = self::getInstalledStandards();
×
322
        $numStandards       = count($installedStandards);
×
323

NEW
324
        $output = '';
×
325
        if ($numStandards === 0) {
×
NEW
326
            $output .= 'No coding standards are installed.';
×
327
        } else {
328
            $lastStandard = array_pop($installedStandards);
×
329
            if ($numStandards === 1) {
×
NEW
330
                $output .= "The only coding standard installed is $lastStandard";
×
331
            } else {
332
                $standardList  = implode(', ', $installedStandards);
×
333
                $standardList .= ' and '.$lastStandard;
×
NEW
334
                $output       .= 'The installed coding standards are '.$standardList;
×
335
            }
336
        }
337

NEW
338
        return $output;
×
339

340
    }//end prepareInstalledStandardsForDisplay()
341

342

343
    /**
344
     * Prints out a list of installed coding standards.
345
     *
346
     * @deprecated 4.0.0 Use `echo Standards::prepareInstalledStandardsForDisplay()` instead.
347
     *
348
     * @return void
349
     */
NEW
350
    public static function printInstalledStandards()
×
351
    {
NEW
352
        echo self::prepareInstalledStandardsForDisplay(), PHP_EOL;
×
353

354
    }//end printInstalledStandards()
355

356

357
}//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