1<?php
2/**
3 * The base class for all PHP_CodeSniffer documentation generators.
4 *
5 * PHP version 5
6 *
7 * @category  PHP
8 * @package   PHP_CodeSniffer
9 * @author    Greg Sherwood <gsherwood@squiz.net>
10 * @author    Marc McIntyre <mmcintyre@squiz.net>
11 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13 * @link      http://pear.php.net/package/PHP_CodeSniffer
14 */
15
16/**
17 * The base class for all PHP_CodeSniffer documentation generators.
18 *
19 * Documentation generators are used to print documentation about code sniffs
20 * in a standard.
21 *
22 * @category  PHP
23 * @package   PHP_CodeSniffer
24 * @author    Greg Sherwood <gsherwood@squiz.net>
25 * @author    Marc McIntyre <mmcintyre@squiz.net>
26 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
27 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
28 * @version   Release: @package_version@
29 * @link      http://pear.php.net/package/PHP_CodeSniffer
30 */
31abstract class PHP_CodeSniffer_DocGenerators_Generator
32{
33
34    /**
35     * The name of the coding standard we are generating docs for.
36     *
37     * @var string
38     */
39    private $_standard = '';
40
41    /**
42     * An array of sniffs that we are limiting the generated docs to.
43     *
44     * If this array is empty, docs are generated for all sniffs in the
45     * supplied coding standard.
46     *
47     * @var string
48     */
49    private $_sniffs = array();
50
51
52    /**
53     * Constructs a PHP_CodeSniffer_DocGenerators_Generator object.
54     *
55     * @param string $standard The name of the coding standard to generate
56     *                         docs for.
57     * @param array  $sniffs   An array of sniffs that we are limiting the
58     *                         generated docs to.
59     *
60     * @see generate()
61     */
62    public function __construct($standard, array $sniffs=array())
63    {
64        $this->_standard = $standard;
65        $this->_sniffs   = $sniffs;
66
67    }//end __construct()
68
69
70    /**
71     * Retrieves the title of the sniff from the DOMNode supplied.
72     *
73     * @param DOMNode $doc The DOMNode object for the sniff.
74     *                     It represents the "documentation" tag in the XML
75     *                     standard file.
76     *
77     * @return string
78     */
79    protected function getTitle(DOMNode $doc)
80    {
81        return $doc->getAttribute('title');
82
83    }//end getTitle()
84
85
86    /**
87     * Retrieves the name of the standard we are generating docs for.
88     *
89     * @return string
90     */
91    protected function getStandard()
92    {
93        return $this->_standard;
94
95    }//end getStandard()
96
97
98    /**
99     * Generates the documentation for a standard.
100     *
101     * It's probably wise for doc generators to override this method so they
102     * have control over how the docs are produced. Otherwise, the processSniff
103     * method should be overridden to output content for each sniff.
104     *
105     * @return void
106     * @see    processSniff()
107     */
108    public function generate()
109    {
110        $standardFiles = $this->getStandardFiles();
111
112        foreach ($standardFiles as $standard) {
113            $doc = new DOMDocument();
114            $doc->load($standard);
115            $documentation = $doc->getElementsByTagName('documentation')->item(0);
116            $this->processSniff($documentation);
117        }
118
119    }//end generate()
120
121
122    /**
123     * Returns a list of paths to XML standard files for all sniffs in a standard.
124     *
125     * Any sniffs that do not have an XML standard file are obviously not included
126     * in the returned array. If documentation is only being generated for some
127     * sniffs (ie. $this->_sniffs is not empty) then all others sniffs will
128     * be filtered from the results as well.
129     *
130     * @return string[]
131     */
132    protected function getStandardFiles()
133    {
134        $phpcs = new PHP_CodeSniffer();
135        $phpcs->process(array(), $this->_standard);
136        $sniffs = $phpcs->getSniffs();
137
138        $standardFiles = array();
139        foreach ($sniffs as $className => $sniffClass) {
140            $object = new ReflectionObject($sniffClass);
141            $sniff  = $object->getFilename();
142            if (empty($this->_sniffs) === false) {
143                // We are limiting the docs to certain sniffs only, so filter
144                // out any unwanted sniffs.
145                $parts     = explode('_', $className);
146                $sniffName = $parts[0].'.'.$parts[2].'.'.substr($parts[3], 0, -5);
147                if (in_array($sniffName, $this->_sniffs) === false) {
148                    continue;
149                }
150            }
151
152            $standardFile = str_replace(
153                DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR,
154                DIRECTORY_SEPARATOR.'Docs'.DIRECTORY_SEPARATOR,
155                $sniff
156            );
157            $standardFile = str_replace('Sniff.php', 'Standard.xml', $standardFile);
158
159            if (is_file($standardFile) === true) {
160                $standardFiles[] = $standardFile;
161            }
162        }//end foreach
163
164        return $standardFiles;
165
166    }//end getStandardFiles()
167
168
169    /**
170     * Process the documentation for a single sniff.
171     *
172     * Doc generators must implement this function to produce output.
173     *
174     * @param DOMNode $doc The DOMNode object for the sniff.
175     *                     It represents the "documentation" tag in the XML
176     *                     standard file.
177     *
178     * @return void
179     * @see    generate()
180     */
181    protected abstract function processSniff(DOMNode $doc);
182
183
184}//end class
185