1 | <?php |
||
37 | class CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff extends |
||
38 | PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff |
||
39 | { |
||
40 | |||
41 | protected $exclusions = array( |
||
42 | // Don't match to the end of class name to allow "SomeEventHandlerFeature" format. |
||
43 | '/EventHandler/' => array( |
||
44 | 'SetCustomQuery', |
||
45 | 'CheckPermission', |
||
46 | 'BaseQuery', |
||
47 | 'ListPrepareQuery', |
||
48 | 'ItemPrepareQuery', |
||
49 | 'SetPagination', |
||
50 | 'SetSorting', |
||
51 | ), |
||
52 | // Don't match to the end of class name to allow "SomeTagProcessorFeature" format. |
||
53 | '/TagProcessor/' => array( |
||
54 | 'PrepareListElementParams', |
||
55 | ), |
||
56 | '/Formatter$/' => array( |
||
57 | 'Format', |
||
58 | 'Parse', |
||
59 | 'PrepareOptions', |
||
60 | ), |
||
61 | '/Validator$/' => array( |
||
62 | 'GetErrorMsg', |
||
63 | 'CustomValidation', |
||
64 | 'SetError', |
||
65 | ), |
||
66 | '/ShippingQuoteEngine$/' => array( |
||
67 | 'GetShippingQuotes', |
||
68 | 'GetAvailableTypes', |
||
69 | 'GetEngineFields', |
||
70 | 'MakeOrder', |
||
71 | ), |
||
72 | '/Helper$/' => array( |
||
73 | 'Init', |
||
74 | 'InitHelper', |
||
75 | ), |
||
76 | '/Item$/' => array('*'), |
||
77 | '/List$/' => array('*'), |
||
78 | '/DBConnection/' => array('*'), |
||
79 | '/DBLoadBalancer$/' => array('*'), |
||
80 | '/Application$/' => array('*'), |
||
81 | ); |
||
82 | |||
83 | /** |
||
84 | * Processes the tokens within the scope. |
||
85 | * |
||
86 | * @param PHP_CodeSniffer_File $phpcsFile The file being processed. |
||
87 | * @param int $stackPtr The position where this token was |
||
88 | * found. |
||
89 | * @param int $currScope The position of the current scope. |
||
90 | * |
||
91 | * @return void |
||
92 | */ |
||
93 | 1 | protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) |
|
94 | { |
||
95 | 1 | $methodName = $phpcsFile->getDeclarationName($stackPtr); |
|
96 | 1 | if ($methodName === null) { |
|
97 | // Ignore closures. |
||
98 | return; |
||
99 | } |
||
100 | |||
101 | 1 | $className = $phpcsFile->getDeclarationName($currScope); |
|
102 | 1 | $errorData = array($className.'::'.$methodName); |
|
103 | |||
104 | // Is this a magic method. i.e., is prefixed with "__" ? |
||
105 | 1 | if (preg_match('|^__|', $methodName) !== 0) { |
|
106 | 1 | $magicPart = strtolower(substr($methodName, 2)); |
|
107 | |||
108 | 1 | if (isset($this->magicMethods[$magicPart]) === false) { |
|
109 | 1 | $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; |
|
110 | 1 | $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData); |
|
111 | } |
||
112 | |||
113 | 1 | return; |
|
114 | } |
||
115 | |||
116 | // PHP4 constructors are allowed to break our rules. |
||
117 | 1 | if ($methodName === $className) { |
|
118 | 1 | return; |
|
119 | } |
||
120 | |||
121 | // PHP4 destructors are allowed to break our rules. |
||
122 | 1 | if ($methodName === '_'.$className) { |
|
123 | 1 | return; |
|
124 | } |
||
125 | |||
126 | 1 | $methodProps = $phpcsFile->getMethodProperties($stackPtr); |
|
127 | 1 | $isPublic = ($methodProps['scope'] === 'private') ? false : true; |
|
128 | 1 | $scope = $methodProps['scope']; |
|
129 | 1 | $scopeSpecified = $methodProps['scope_specified']; |
|
130 | |||
131 | // If it's a private method, it must have an underscore on the front. |
||
132 | 1 | if ($isPublic === false) { |
|
133 | 1 | if ($methodName{0} !== '_') { |
|
134 | 1 | $error = 'Private method name "%s" must be prefixed with an underscore'; |
|
135 | 1 | $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData); |
|
136 | |||
137 | 1 | if (isset($phpcsFile->fixer) === true) { |
|
138 | 1 | $phpcsFile->recordMetric($stackPtr, 'Private method prefixed with underscore', 'no'); |
|
139 | } |
||
140 | |||
141 | 1 | return; |
|
142 | } else { |
||
143 | 1 | if (isset($phpcsFile->fixer) === true) { |
|
144 | 1 | $phpcsFile->recordMetric($stackPtr, 'Private method prefixed with underscore', 'yes'); |
|
145 | } |
||
146 | } |
||
147 | } |
||
148 | |||
149 | // If it's not a private method, it must not have an underscore on the front. |
||
150 | 1 | if ($isPublic === true && $scopeSpecified === true && $methodName{0} === '_') { |
|
151 | 1 | $error = '%s method name "%s" must not be prefixed with an underscore'; |
|
152 | $data = array( |
||
153 | 1 | ucfirst($scope), |
|
154 | 1 | $errorData[0], |
|
155 | ); |
||
156 | 1 | $phpcsFile->addError($error, $stackPtr, 'PublicUnderscore', $data); |
|
157 | 1 | return; |
|
158 | } |
||
159 | |||
160 | // If the scope was specified on the method, then the method must be |
||
161 | // camel caps and an underscore should be checked for. If it wasn't |
||
162 | // specified, treat it like a public method and remove the underscore |
||
163 | // prefix if there is one because we cant determine if it is private or |
||
164 | // public. |
||
165 | 1 | $testMethodName = $methodName; |
|
166 | 1 | if ($scopeSpecified === false && $methodName{0} === '_') { |
|
167 | 1 | $testMethodName = substr($methodName, 1); |
|
168 | } |
||
169 | |||
170 | 1 | $methodParams = $phpcsFile->getMethodParameters($stackPtr); |
|
171 | |||
172 | 1 | if ($this->isExclusion($className, $methodName, $isPublic) === true |
|
173 | 1 | || $this->isEventHandlerExclusion($className, $methodName, $methodParams) === true |
|
174 | 1 | || $this->isTagProcessorExclusion($className, $methodName, $methodParams) === true |
|
175 | ) { |
||
176 | 1 | return; |
|
177 | } |
||
178 | |||
179 | 1 | if (PHP_CodeSniffer::isCamelCaps($testMethodName, false, $isPublic, false) === false) { |
|
180 | 1 | if ($scopeSpecified === true) { |
|
181 | 1 | $error = '%s method name "%s" is not in camel caps format'; |
|
182 | $data = array( |
||
183 | 1 | ucfirst($scope), |
|
184 | 1 | $errorData[0], |
|
185 | ); |
||
186 | 1 | $phpcsFile->addError($error, $stackPtr, 'ScopeNotCamelCaps', $data); |
|
187 | } else { |
||
188 | 1 | $error = 'Method name "%s" is not in camel caps format'; |
|
189 | 1 | $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData); |
|
190 | } |
||
191 | |||
192 | 1 | return; |
|
193 | } |
||
194 | |||
195 | 1 | }//end processTokenWithinScope() |
|
196 | |||
197 | /** |
||
198 | * Determines if a method name shouldn't be checked for camelCaps format. |
||
199 | * |
||
200 | * @param string $className Class name. |
||
201 | * @param string $methodName Method name. |
||
202 | * @param bool $isPublic Public. |
||
203 | * |
||
204 | * @return bool |
||
205 | */ |
||
206 | 1 | protected function isExclusion($className, $methodName, $isPublic) |
|
207 | { |
||
208 | 1 | foreach ($this->exclusions as $classRegExp => $excludedMethods) { |
|
209 | 1 | if (preg_match($classRegExp, $className)) { |
|
210 | 1 | return ($excludedMethods[0] == '*' && $isPublic) || in_array($methodName, $excludedMethods); |
|
211 | } |
||
212 | } |
||
213 | |||
214 | 1 | return false; |
|
215 | |||
216 | }//end isExclusion() |
||
217 | |||
218 | /** |
||
219 | * Determines if a method is an event in the event handler class. |
||
220 | * |
||
221 | * @param string $className Class name. |
||
222 | * @param string $methodName Method name. |
||
223 | * @param array $methodParams Method parameters. |
||
224 | * |
||
225 | * @return bool |
||
226 | */ |
||
227 | 1 | protected function isEventHandlerExclusion($className, $methodName, array $methodParams) |
|
237 | |||
238 | |||
239 | /** |
||
240 | * Determines if a method is an tag in the tag processor class. |
||
241 | * |
||
242 | * @param string $className Class name. |
||
243 | * @param string $methodName Method name. |
||
244 | * @param array $methodParams Method parameters. |
||
245 | * |
||
246 | * @return bool |
||
247 | */ |
||
248 | 1 | protected function isTagProcessorExclusion($className, $methodName, array $methodParams) |
|
258 | |||
259 | |||
260 | }//end class |
||
261 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.