Make WordPress Core

Ticket #31982: PHP4ConstructorSniff.php

File PHP4ConstructorSniff.php, 3.1 KB (added by jdgrimes, 10 years ago)

PHP_CodeSniffer sniff used to generate the patch

Line 
1<?php
2
3/**
4 * Sniff for detecting PHP4 constructors.
5 */
6
7/**
8 * Warns about classes with PHP4 constructors that don't have PHP5 constructors.
9 */
10class JDGrimes_Sniffs_PHP7_PHP4ConstructorSniff extends JDGrimes_Sniff {
11
12        public function register() {
13                return array( T_FUNCTION );
14        }
15
16        public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {
17
18                $tokens = $phpcsFile->getTokens();
19
20                if ( ! isset( $tokens[ $stackPtr ]['scope_closer'] ) ) {
21                        return;
22                }
23
24                $parent = end( $tokens[ $stackPtr ]['conditions'] );
25
26                if ( ! $parent || T_CLASS !== $parent ) {
27                        return;
28                }
29
30                $class_ptr = key( $tokens[ $stackPtr ]['conditions'] );
31
32                $method_ptr = $phpcsFile->findNext( T_STRING, $stackPtr + 1 );
33                $method_name = $tokens[ $method_ptr ]['content'];
34
35                if ( '__construct' === $method_name ) {
36                        return $tokens[ $class_ptr ]['scope_closer'];
37                }
38
39                $class_name = $phpcsFile->getDeclarationName( $class_ptr );
40
41                if ( strtolower( $method_name ) === strtolower( $class_name ) ) {
42
43                        if (  isset( $phpcsFile->fixer ) ) {
44
45                                $fix = $phpcsFile->addFixableError(
46                                        'Found PHP4 constructor not proceeded by a PHP5 constructor.'
47                                        , $stackPtr
48                                        , 'NoPHP5Constructor'
49                                );
50
51                                if ( $fix ) {
52
53                                        $method_end_ptr = $tokens[ $stackPtr ]['scope_closer'];
54
55                                        // Get the list of arguments accepted by the function.
56                                        $args_def = $phpcsFile->getTokensAsString(
57                                                $tokens[ $stackPtr ]['parenthesis_opener'] + 1
58                                                , $tokens[ $stackPtr ]['parenthesis_closer'] - $tokens[ $stackPtr ]['parenthesis_opener'] - 1
59                                        );
60
61                                        if ( ! empty( $args_def ) ) {
62                                                $args_def = ' ' . trim( $args_def ) . ' ';
63                                                $args_only = preg_replace( '/\s?=[^,]*(,)?/', '\1', $args_def );
64                                                $args_only .= ' ';
65                                        } else {
66                                                $args_only = '';
67                                        }
68
69                                        $phpcsFile->fixer->beginChangeset();
70
71                                        // Change the name of the method to __construct().
72                                        $phpcsFile->fixer->replaceToken( $method_ptr, '__construct' );
73
74                                        $new_method = "\n\n\t/**";
75                                        $new_method .= "\n\t * PHP4 constructor.";
76                                        $new_method .= "\n\t */";
77                                        $new_method .= "\n\tpublic function {$method_name}({$args_def}) {";
78                                        $new_method .= "\n\t\tself::__construct({$args_only});";
79                                        $new_method .= "\n\t}";
80
81                                        $phpcsFile->fixer->addContent(
82                                                $method_end_ptr
83                                                , $new_method
84                                        );
85/*
86                                        // Add a the PHP4 constructor back, right after the PHP5 one.
87                                        $phpcsFile->fixer->addNewline( $method_end_ptr );
88                                        $phpcsFile->fixer->addNewline( $method_end_ptr );
89                                        $phpcsFile->fixer->addContent(
90                                                $method_end_ptr
91                                                , "\tpublic function {$method_name} ({$args}) {"
92                                        );
93                                        $phpcsFile->fixer->addNewline( $method_end_ptr );
94                                        $phpcsFile->fixer->addContent(
95                                                $method_end_ptr
96                                                , "\t\tself::__construct({$args});"
97                                        );
98                                        $phpcsFile->fixer->addNewline( $method_end_ptr );
99                                        $phpcsFile->fixer->addContent(
100                                                $method_end_ptr
101                                                , "\t}"
102                                        );
103*/
104                                        $phpcsFile->fixer->endChangeset();
105                                }
106
107                        } else {
108
109                                $phpcsFile->addError(
110                                        'Found PHP4 constructor not proceeded by a PHP5 constructor.'
111                                        , $stackPtr
112                                        , 'NoPHP5Constructor'
113                                );
114                        }
115
116                        return $tokens[ $class_ptr ]['scope_closer'];
117                }
118        }
119}
120
121// EOF