3030 */
3131class ComponentsEscapeSniff extends EscapeOutputSniff
3232{
33+ /**
34+ * A fully qualified class name for Components class override
35+ *
36+ * You should put the fully qualified class name of the class you used
37+ * to override the EightshiftLibs\Helpers\Component class.
38+ *
39+ * For Example: namespace\\SomeSubNamespace\\MyComponents.
40+ *
41+ * @var string
42+ */
43+ public $ overriddenClass = '' ;
44+
3345 /**
3446 * Processes this test, when one of its tokens is encountered.
3547 *
@@ -42,21 +54,27 @@ public function process_token($stackPtr)
4254 {
4355 $ tokens = $ this ->tokens ;
4456 $ phpcsFile = $ this ->phpcsFile ;
45- $ importData = [];
57+ $ importData = [
58+ 'importExists ' => false ,
59+ 'fullImportExists ' => false
60+ ];
4661 $ importExists = false ;
4762
4863 // Check if the current token is a part of the import, if it is, skip the check.
4964 $ useToken = $ phpcsFile ->findPrevious (\T_USE , ($ stackPtr - 1 ), null , false , null , false );
5065
5166 if ($ useToken ) {
52- $ endOfUse = $ phpcsFile ->findNext (\T_SEMICOLON , $ useToken , null , false , null , false );
67+ // Find all use tokens.
68+ foreach ($ tokens as $ tokenPtr => $ token ) {
69+ if ($ token ['code ' ] === \T_USE ) {
70+ $ importData = $ this ->checkIfImportInformation ($ tokenPtr , $ importData );
5371
54- // Ignore all the tokens that are a part of the import statement. Every import statement ends in the semicolon.
55- if ($ stackPtr <= $ endOfUse ) {
56- return ;
72+ if ($ importData ['importExists ' ]) {
73+ break ;
74+ }
75+ }
5776 }
5877
59- $ importData = $ this ->checkIfImportInformation ($ stackPtr );
6078 $ importExists = $ importData ['importExists ' ];
6179 }
6280
@@ -110,8 +128,9 @@ public function process_token($stackPtr)
110128 if ($ importData ['fullImportExists ' ]) {
111129 // Components name is ok, \Components is not ok, \Anything\Components is not ok FQCN is ok.
112130 if (
113- $ className === 'Components ' ||
114- \strpos ($ className , 'EightshiftLibs \\Helpers \\Components ' ) !== false
131+ $ className === 'Components '
132+ || \strpos ($ className , 'EightshiftLibs \\Helpers \\Components ' ) !== false
133+ || (! empty ($ this ->overriddenClass ) && \strpos ($ className , $ this ->overriddenClass ) !== false )
115134 ) {
116135 // Check the static method name.
117136 $ methodNamePtr = $ phpcsFile ->findNext (
@@ -130,27 +149,13 @@ public function process_token($stackPtr)
130149 return ; // Skip sniffing allowed methods.
131150 } else {
132151 // Not allowed method, continue as usual.
133- $ echoPtr = $ phpcsFile ->findPrevious (
134- \T_ECHO ,
135- ($ componentsClassNamePtr - 1 ),
136- null ,
137- false ,
138- null ,
139- true
140- );
152+ $ echoPtr = $ this ->getEchoToken ($ componentsClassNamePtr );
141153
142154 return parent ::process_token ($ echoPtr );
143155 }
144156 } else {
145157 // Some other class we don't care about.
146- $ echoPtr = $ phpcsFile ->findPrevious (
147- \T_ECHO ,
148- ($ componentsClassNamePtr - 1 ),
149- null ,
150- false ,
151- null ,
152- true
153- );
158+ $ echoPtr = $ this ->getEchoToken ($ componentsClassNamePtr );
154159
155160 return parent ::process_token ($ echoPtr );
156161 }
@@ -180,34 +185,23 @@ public function process_token($stackPtr)
180185 return ; // Skip sniffing allowed methods.
181186 } else {
182187 // Not allowed method, continue as usual.
183- $ echoPtr = $ phpcsFile ->findPrevious (
184- \T_ECHO ,
185- ($ componentsClassNamePtr - 1 ),
186- null ,
187- false ,
188- null ,
189- true
190- );
188+ $ echoPtr = $ this ->getEchoToken ($ componentsClassNamePtr );
191189
192190 return parent ::process_token ($ echoPtr );
193191 }
194192 } else {
195193 // Wrongly imported, or class that is not related to the libs.
196- $ echoPtr = $ phpcsFile ->findPrevious (
197- \T_ECHO ,
198- ($ componentsClassNamePtr - 1 ),
199- null ,
200- false ,
201- null ,
202- true
203- );
194+ $ echoPtr = $ this ->getEchoToken ($ componentsClassNamePtr );
204195
205196 return parent ::process_token ($ echoPtr );
206197 }
207198 }
208199 } else {
209200 // Check if the class name is fully qualified and contains the helper part.
210- if (\strpos ($ className , 'EightshiftLibs \\Helpers \\Components ' ) !== false ) {
201+ if (
202+ \strpos ($ className , 'EightshiftLibs \\Helpers \\Components ' ) !== false
203+ || (! empty ($ this ->overriddenClass ) && \strpos ($ className , $ this ->overriddenClass ) !== false )
204+ ) {
211205 $ methodNamePtr = $ phpcsFile ->findNext (
212206 \T_STRING ,
213207 ($ componentsClassNamePtr + 1 ),
@@ -224,26 +218,12 @@ public function process_token($stackPtr)
224218 return ; // Skip sniffing allowed methods.
225219 } else {
226220 // Not allowed method, continue as usual.
227- $ echoPtr = $ phpcsFile ->findPrevious (
228- \T_ECHO ,
229- ($ componentsClassNamePtr - 1 ),
230- null ,
231- false ,
232- null ,
233- true
234- );
221+ $ echoPtr = $ this ->getEchoToken ($ componentsClassNamePtr );
235222
236223 return parent ::process_token ($ echoPtr );
237224 }
238225 } else {
239- $ echoPtr = $ phpcsFile ->findPrevious (
240- \T_ECHO ,
241- ($ componentsClassNamePtr - 1 ),
242- null ,
243- false ,
244- null ,
245- true
246- );
226+ $ echoPtr = $ this ->getEchoToken ($ componentsClassNamePtr );
247227
248228 return parent ::process_token ($ echoPtr );
249229 }
@@ -258,48 +238,57 @@ public function process_token($stackPtr)
258238 * Checks if the import statement exists in the current file, for the given stack pointer
259239 *
260240 * @param int $stackPtr The position of the current token in the stack.
241+ * @param String[] $importData Import data array.
261242 *
262243 * @return array<string, bool|string> Information about the imports
263244 */
264- private function checkIfImportInformation ($ stackPtr ): array
245+ private function checkIfImportInformation (int $ stackPtr, array $ importData ): array
265246 {
266- $ tokens = $ this ->tokens ;
267247 $ phpcsFile = $ this ->phpcsFile ;
268248
269- $ importData = [
270- 'importExists ' => false ,
271- 'fullImportExists ' => false
272- ];
249+ $ overriddenClass = \str_replace ('\\\\' , '\\' , $ this ->overriddenClass );
273250
274- // Check if the correct import exists at the top of the file.
275- $ importPtr = $ phpcsFile-> findPrevious (\ T_USE , ( $ stackPtr - 1 ), null , false , null , false );
251+ if (UseStatements:: isImportUse ( $ phpcsFile , $ stackPtr )) {
252+ $ importInfo = UseStatements:: splitImportUseStatement ( $ phpcsFile, $ stackPtr );
276253
277- if ($ tokens [$ importPtr ]['code ' ] === \T_USE ) {
278- if (UseStatements::isImportUse ($ phpcsFile , $ importPtr )) {
279- $ importInfo = UseStatements::splitImportUseStatement ($ phpcsFile , $ importPtr );
254+ if (!empty ($ importInfo )) {
255+ foreach ($ importInfo ['name ' ] as $ fullyQualifiedClassNameImport ) {
256+ if (
257+ \strpos ($ fullyQualifiedClassNameImport , 'EightshiftLibs \\Helpers ' ) !== false
258+ || (! empty ($ overriddenClass ) && \strpos ($ fullyQualifiedClassNameImport , $ overriddenClass ) !== false )
259+ ) {
260+ $ importData ['importExists ' ] = true ;
261+ $ importData ['importName ' ] = $ fullyQualifiedClassNameImport ;
280262
281- if (!empty ($ importInfo )) {
282- foreach ($ importInfo ['name ' ] as $ fullyQualifiedClassNameImport ) {
283- // Check for partial import.
284- if (\strpos ($ fullyQualifiedClassNameImport , 'EightshiftLibs \\Helpers ' ) !== false ) {
285- $ importData ['importExists ' ] = true ;
263+ // Check for fully qualified import.
264+ if (
265+ \strpos ($ fullyQualifiedClassNameImport , 'EightshiftLibs \\Helpers \\Components ' ) !== false
266+ || (! empty ($ overriddenClass ) && \strpos ($ fullyQualifiedClassNameImport , $ overriddenClass ) !== false )
267+ ) {
268+ $ importData ['fullImportExists ' ] = true ;
286269 $ importData ['importName ' ] = $ fullyQualifiedClassNameImport ;
287270
288- // Check for fully qualified import.
289- if (\strpos ($ fullyQualifiedClassNameImport , 'EightshiftLibs \\Helpers \\Components ' ) !== false ) {
290- $ importData ['fullImportExists ' ] = true ;
291- $ importData ['importName ' ] = $ fullyQualifiedClassNameImport ;
292-
293- break ;
294- }
295-
296271 break ;
297272 }
273+
274+ break ;
298275 }
299276 }
300277 }
301278 }
302279
303280 return $ importData ;
304281 }
282+
283+ /**
284+ * Return the position of the previous echo pointer
285+ *
286+ * @param int $stackPtr The position of the current token in the stack.
287+ *
288+ * @return int Token pointer number.
289+ */
290+ private function getEchoToken (int $ stackPtr ): int
291+ {
292+ return $ this ->phpcsFile ->findPrevious (\T_ECHO , ($ stackPtr - 1 ), null , false , null , true );
293+ }
305294}
0 commit comments