Version Description
- Fix: Mask Login cause issue when visiting /wp-admin/network/sites.php
Download this release
Release Info
Developer | hoang1213 |
Plugin | Defender Security – Malware Scanner, Login Security & Firewall |
Version | 2.1.4 |
Comparing to | |
See all releases |
Code changes from version 2.1.2 to 2.1.4
- app/behavior/utils.php +2 -2
- app/controller/requirement.php +1 -1
- app/module/advanced-tools/component/auth-api.php +0 -1
- app/module/advanced-tools/component/mask-api.php +48 -6
- app/module/advanced-tools/controller/main.php +4 -4
- app/module/advanced-tools/controller/mask-login.php +5 -7
- app/module/advanced-tools/view/2factor-otp-email-edit-from.php +2 -2
- app/module/advanced-tools/view/layouts/layout.php +10 -9
- app/module/advanced-tools/view/login/disabled.php +7 -7
- app/module/advanced-tools/view/main-free.php +2 -2
- app/module/advanced-tools/view/main.php +5 -5
- app/module/advanced-tools/view/mask-login/enabled.php +2 -2
- app/module/hardener/component/change-admin.php +4 -0
- app/module/hardener/component/db-prefix.php +8 -1
- app/module/hardener/component/disable-file-editor.php +4 -0
- app/module/hardener/component/disable-trackback.php +6 -2
- app/module/hardener/component/disable-xml-rpc.php +4 -0
- app/module/hardener/component/hide-error.php +4 -0
- app/module/hardener/component/login-duration.php +18 -6
- app/module/hardener/component/php-version.php +7 -0
- app/module/hardener/component/prevent-php.php +4 -0
- app/module/hardener/component/protect-information.php +4 -0
- app/module/hardener/component/security-key.php +4 -0
- app/module/hardener/component/wp-version.php +4 -0
- app/module/hardener/controller/main.php +49 -5
- app/module/hardener/rule.php +9 -3
- app/module/hardener/view/email/notification.php +366 -0
- app/module/hardener/view/layouts/layout.php +26 -15
- app/module/hardener/view/rules/db-prefix.php +13 -12
- app/module/hardener/view/rules/hide-error.php +21 -19
- app/module/hardener/view/rules/prevent-php-executed.php +21 -5
- app/module/hardener/view/rules/protect-information.php +20 -4
- app/module/hardener/view/rules/wp-version.php +12 -10
- app/module/ip-lockout/component/login-protection-api.php +5 -5
- app/module/ip-lockout/controller/main.php +3 -2
- app/module/ip-lockout/view/blacklist/enabled.php +8 -5
- app/module/ip-lockout/view/detect-404/enabled.php +1 -4
- app/module/ip-lockout/view/layouts/layout.php +5 -4
- app/module/ip-lockout/view/locked.php +4 -2
- app/module/ip-lockout/view/login-lockouts/enabled.php +0 -3
- app/module/ip-lockout/view/notification/enabled.php +4 -4
- app/module/ip-lockout/view/notification/report.php +2 -2
- app/module/scan/behavior/scan.php +0 -266
- app/module/scan/component/result-table.php +17 -11
- app/module/scan/component/scan-api.php +3 -1
- app/module/scan/component/token-utils.php +301 -10
- app/module/scan/controller/main.php +18 -6
- app/module/scan/js/prism.css +183 -0
- app/module/scan/js/prism.js +1350 -0
- app/module/scan/js/script.js +13 -24
- app/module/scan/model/settings.php +2 -1
- app/module/scan/view/automation.php +1 -1
- app/module/scan/view/ignored.php +1 -1
- app/module/scan/view/issues.php +2 -2
- app/module/scan/view/layouts/layout.php +19 -6
- app/module/scan/view/notification.php +27 -1
- app/module/scan/view/setting-free.php +1 -1
- app/module/scan/view/setting.php +7 -7
- app/module/setting/view/accessibility.php +1 -1
- app/module/setting/view/general.php +1 -1
- app/module/setting/view/layouts/layout.php +19 -12
- app/view/activator.php +4 -2
- app/view/dashboard.php +32 -5
- assets/css/styles.css +33 -73
- assets/css/styles.css.map +0 -7
- assets/email-assets/img/Blue-Copy.png +0 -0
- assets/email-assets/img/Blue-Copy@2x.png +0 -0
- assets/email-assets/img/Defender-widerec.png +0 -0
- assets/email-assets/img/Defender-widerec@2x.png +0 -0
- assets/email-assets/img/Warning.png +0 -0
- assets/email-assets/img/Warning@2x.png +0 -0
- readme.txt +27 -2
- vendor/hammer/base/db-model.php +1 -1
- vendor/hammer/wp/model.php +1 -2
- vendor/php_codesniffer-3.4.0/CONTRIBUTING.md +13 -0
- vendor/php_codesniffer-3.4.0/CodeSniffer.conf.dist +9 -0
- vendor/php_codesniffer-3.4.0/README.md +107 -0
- vendor/php_codesniffer-3.4.0/composer.json +40 -0
- vendor/php_codesniffer-3.4.0/licence.txt +24 -0
- vendor/php_codesniffer-3.4.0/phpcs.xml.dist +145 -0
- vendor/php_codesniffer-3.4.0/phpcs.xsd +108 -0
- vendor/php_codesniffer-3.4.0/src/Exceptions/DeepExitException.php +18 -0
- vendor/php_codesniffer-3.4.0/src/Exceptions/RuntimeException.php +15 -0
- vendor/php_codesniffer-3.4.0/src/Exceptions/TokenizerException.php +15 -0
- vendor/php_codesniffer-3.4.0/src/Tokenizers/CSS.php +534 -0
- vendor/php_codesniffer-3.4.0/src/Tokenizers/Comment.php +277 -0
- vendor/php_codesniffer-3.4.0/src/Tokenizers/JS.php +1264 -0
- vendor/php_codesniffer-3.4.0/src/Tokenizers/PHP.php +2014 -0
- vendor/php_codesniffer-3.4.0/src/Tokenizers/Tokenizer.php +1614 -0
- vendor/php_codesniffer-3.4.0/src/Util/Standards.php +137 -0
- vendor/php_codesniffer-3.4.0/src/Util/Tokens.php +644 -0
- vendor/phpqrcode/qrvect.php +1 -1
- wp-defender.php +3 -3
app/behavior/utils.php
CHANGED
@@ -685,11 +685,11 @@ class Utils extends Behavior {
|
|
685 |
public function checkRequirement( &$result = null ) {
|
686 |
$meet = true;
|
687 |
|
688 |
-
if ( version_compare( $this->getPHPVersion(), '5.
|
689 |
$meet = false;
|
690 |
$result['php'] = array(
|
691 |
'status' => $this->getPHPVersion(),
|
692 |
-
'message' => __( "Please upgrade to 5.
|
693 |
);
|
694 |
}
|
695 |
|
685 |
public function checkRequirement( &$result = null ) {
|
686 |
$meet = true;
|
687 |
|
688 |
+
if ( version_compare( $this->getPHPVersion(), '5.6', '>=' ) == false ) {
|
689 |
$meet = false;
|
690 |
$result['php'] = array(
|
691 |
'status' => $this->getPHPVersion(),
|
692 |
+
'message' => __( "Please upgrade to 5.6 or later", "defender-security" )
|
693 |
);
|
694 |
}
|
695 |
|
app/controller/requirement.php
CHANGED
@@ -49,7 +49,7 @@ class WD_Requirement {
|
|
49 |
<tr>
|
50 |
<td><?php _e( "PHP version", "defender-security" ) ?></td>
|
51 |
<td>
|
52 |
-
|
53 |
</td>
|
54 |
</tr>
|
55 |
</tbody>
|
49 |
<tr>
|
50 |
<td><?php _e( "PHP version", "defender-security" ) ?></td>
|
51 |
<td>
|
52 |
+
<?php _e( "Please upgrade to 5.6 or later.", "defender-security" ) ?>
|
53 |
</td>
|
54 |
</tr>
|
55 |
</tbody>
|
app/module/advanced-tools/component/auth-api.php
CHANGED
@@ -70,7 +70,6 @@ class Auth_API extends Component {
|
|
70 |
$secret = $base32->decode( $secret );
|
71 |
//timestep fixed at 30
|
72 |
if ( is_null( $counter ) ) {
|
73 |
-
|
74 |
$counter = time();
|
75 |
}
|
76 |
$input = floor( $counter / 30 );
|
70 |
$secret = $base32->decode( $secret );
|
71 |
//timestep fixed at 30
|
72 |
if ( is_null( $counter ) ) {
|
|
|
73 |
$counter = time();
|
74 |
}
|
75 |
$input = floor( $counter / 30 );
|
app/module/advanced-tools/component/mask-api.php
CHANGED
@@ -25,8 +25,8 @@ class Mask_Api extends Component {
|
|
25 |
$requestUri = $_SERVER['REQUEST_URI'];
|
26 |
}
|
27 |
//
|
28 |
-
$requestUri
|
29 |
-
$prefix
|
30 |
$requestPath = parse_url( $requestUri, PHP_URL_PATH );
|
31 |
//clean it a bit
|
32 |
if ( Utils::instance()->isActivatedSingle() == false
|
@@ -42,8 +42,11 @@ class Mask_Api extends Component {
|
|
42 |
$requestPath = substr( $requestPath, strlen( $path ) );
|
43 |
$requestPath = '/' . ltrim( $requestPath, '/' );
|
44 |
}
|
|
|
|
|
|
|
45 |
}
|
46 |
-
if ( strpos( $requestPath, $prefix ) === 0 ) {
|
47 |
$requestPath = substr( $requestPath, strlen( $prefix ) );
|
48 |
}
|
49 |
$requestPath = untrailingslashit( $requestPath );
|
@@ -104,13 +107,52 @@ class Mask_Api extends Component {
|
|
104 |
return $url;
|
105 |
}
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
/**
|
108 |
* @return string
|
109 |
*/
|
110 |
public static function getRedirectUrl() {
|
111 |
$settings = Mask_Settings::instance();
|
112 |
|
113 |
-
return untrailingslashit(
|
114 |
}
|
115 |
|
116 |
/**
|
@@ -119,7 +161,7 @@ class Mask_Api extends Component {
|
|
119 |
public static function getNewLoginUrl( $domain = null ) {
|
120 |
$settings = Mask_Settings::instance();
|
121 |
if ( $domain == null ) {
|
122 |
-
$domain = site_url();
|
123 |
}
|
124 |
|
125 |
return untrailingslashit( $domain . '/' . ltrim( $settings->maskUrl, '/' ) );
|
@@ -145,7 +187,7 @@ class Mask_Api extends Component {
|
|
145 |
}
|
146 |
//if context is login, we will check for exists page
|
147 |
if ( $context == 'login' ) {
|
148 |
-
if ( in_array( $slug, array( 'admin', 'backend', 'wp-login', 'wp-login.php' ) ) ) {
|
149 |
return new \WP_Error( Error_Code::VALIDATE, __( "A page already exists at this URL, please pick a unique page for your new login area.", "defender-security" ) );
|
150 |
}
|
151 |
|
25 |
$requestUri = $_SERVER['REQUEST_URI'];
|
26 |
}
|
27 |
//
|
28 |
+
$requestUri = '/' . ltrim( $requestUri, '/' );
|
29 |
+
$prefix = parse_url( self::site_url(), PHP_URL_PATH );
|
30 |
$requestPath = parse_url( $requestUri, PHP_URL_PATH );
|
31 |
//clean it a bit
|
32 |
if ( Utils::instance()->isActivatedSingle() == false
|
42 |
$requestPath = substr( $requestPath, strlen( $path ) );
|
43 |
$requestPath = '/' . ltrim( $requestPath, '/' );
|
44 |
}
|
45 |
+
} elseif ( self::get_home_url() != self::site_url() && strpos( $requestPath, (string) $prefix . '/' ) !== 0 ) {
|
46 |
+
//this case when a wp install inside a sub folder and domain changed into that subfolder
|
47 |
+
$prefix = parse_url( self::get_home_url(), PHP_URL_PATH );
|
48 |
}
|
49 |
+
if ( strlen( $prefix ) && strpos( $requestPath, (string) $prefix ) === 0 ) {
|
50 |
$requestPath = substr( $requestPath, strlen( $prefix ) );
|
51 |
}
|
52 |
$requestPath = untrailingslashit( $requestPath );
|
107 |
return $url;
|
108 |
}
|
109 |
|
110 |
+
/**
|
111 |
+
* clone from get_home_url function without the filter
|
112 |
+
*
|
113 |
+
* @param null $blog_id
|
114 |
+
* @param string $path
|
115 |
+
* @param null $scheme
|
116 |
+
*
|
117 |
+
* @return mixed|void
|
118 |
+
*/
|
119 |
+
private static function get_home_url( $blog_id = null, $path = '', $scheme = null ) {
|
120 |
+
global $pagenow;
|
121 |
+
|
122 |
+
$orig_scheme = $scheme;
|
123 |
+
|
124 |
+
if ( empty( $blog_id ) || ! is_multisite() ) {
|
125 |
+
$url = get_option( 'home' );
|
126 |
+
} else {
|
127 |
+
switch_to_blog( $blog_id );
|
128 |
+
$url = get_option( 'home' );
|
129 |
+
restore_current_blog();
|
130 |
+
}
|
131 |
+
|
132 |
+
if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) {
|
133 |
+
if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $pagenow ) {
|
134 |
+
$scheme = 'https';
|
135 |
+
} else {
|
136 |
+
$scheme = parse_url( $url, PHP_URL_SCHEME );
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
$url = set_url_scheme( $url, $scheme );
|
141 |
+
|
142 |
+
if ( $path && is_string( $path ) ) {
|
143 |
+
$url .= '/' . ltrim( $path, '/' );
|
144 |
+
}
|
145 |
+
|
146 |
+
return $url;
|
147 |
+
}
|
148 |
+
|
149 |
/**
|
150 |
* @return string
|
151 |
*/
|
152 |
public static function getRedirectUrl() {
|
153 |
$settings = Mask_Settings::instance();
|
154 |
|
155 |
+
return untrailingslashit( get_home_url( get_current_blog_id() ) ) . '/' . ltrim( $settings->redirectTrafficUrl, '/' );
|
156 |
}
|
157 |
|
158 |
/**
|
161 |
public static function getNewLoginUrl( $domain = null ) {
|
162 |
$settings = Mask_Settings::instance();
|
163 |
if ( $domain == null ) {
|
164 |
+
$domain = self::site_url();
|
165 |
}
|
166 |
|
167 |
return untrailingslashit( $domain . '/' . ltrim( $settings->maskUrl, '/' ) );
|
187 |
}
|
188 |
//if context is login, we will check for exists page
|
189 |
if ( $context == 'login' ) {
|
190 |
+
if ( in_array( $slug, array( 'admin', 'backend', 'wp-login', 'wp-login.php', 'login' ) ) ) {
|
191 |
return new \WP_Error( Error_Code::VALIDATE, __( "A page already exists at this URL, please pick a unique page for your new login area.", "defender-security" ) );
|
192 |
}
|
193 |
|
app/module/advanced-tools/controller/main.php
CHANGED
@@ -113,7 +113,7 @@ class Main extends Controller {
|
|
113 |
|
114 |
$screen = get_current_screen();
|
115 |
if ( $screen->id != 'profile' ) {
|
116 |
-
|
117 |
exit;
|
118 |
}
|
119 |
}
|
@@ -404,7 +404,7 @@ class Main extends Controller {
|
|
404 |
wp_set_current_user( $user->ID, $user->user_login );
|
405 |
wp_set_auth_cookie( $user->ID, true );
|
406 |
$redirect = apply_filters( 'login_redirect', $redirect, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '', $user );
|
407 |
-
|
408 |
exit;
|
409 |
} else {
|
410 |
$backupCode = get_user_meta( $user->ID, 'defenderBackupCode', true );
|
@@ -414,7 +414,7 @@ class Main extends Controller {
|
|
414 |
wp_set_current_user( $user->ID, $user->user_login );
|
415 |
wp_set_auth_cookie( $user->ID, true );
|
416 |
$redirect = apply_filters( 'login_redirect', $redirect, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '', $user );
|
417 |
-
|
418 |
exit;
|
419 |
} else {
|
420 |
$params['error'] = new \WP_Error( 'opt_fail', __( "Whoops, the passcode you entered was incorrect or expired.", "defender-security" ) );
|
@@ -595,7 +595,7 @@ class Main extends Controller {
|
|
595 |
}
|
596 |
$email_settings['email_subject'] = $subject;
|
597 |
$email_settings['email_sender'] = $sender;
|
598 |
-
$email_settings['email_body'] = $body;
|
599 |
|
600 |
$setting = Auth_Settings::instance();
|
601 |
$setting->import( $email_settings );
|
113 |
|
114 |
$screen = get_current_screen();
|
115 |
if ( $screen->id != 'profile' ) {
|
116 |
+
wp_safe_redirect( admin_url( 'profile.php' ) . '#show2AuthActivator' );
|
117 |
exit;
|
118 |
}
|
119 |
}
|
404 |
wp_set_current_user( $user->ID, $user->user_login );
|
405 |
wp_set_auth_cookie( $user->ID, true );
|
406 |
$redirect = apply_filters( 'login_redirect', $redirect, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '', $user );
|
407 |
+
wp_safe_redirect( $redirect );
|
408 |
exit;
|
409 |
} else {
|
410 |
$backupCode = get_user_meta( $user->ID, 'defenderBackupCode', true );
|
414 |
wp_set_current_user( $user->ID, $user->user_login );
|
415 |
wp_set_auth_cookie( $user->ID, true );
|
416 |
$redirect = apply_filters( 'login_redirect', $redirect, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '', $user );
|
417 |
+
wp_safe_redirect( $redirect );
|
418 |
exit;
|
419 |
} else {
|
420 |
$params['error'] = new \WP_Error( 'opt_fail', __( "Whoops, the passcode you entered was incorrect or expired.", "defender-security" ) );
|
595 |
}
|
596 |
$email_settings['email_subject'] = $subject;
|
597 |
$email_settings['email_sender'] = $sender;
|
598 |
+
$email_settings['email_body'] = wp_kses_post( $body );
|
599 |
|
600 |
$setting = Auth_Settings::instance();
|
601 |
$setting->import( $email_settings );
|
app/module/advanced-tools/controller/mask-login.php
CHANGED
@@ -46,9 +46,7 @@ class Mask_Login extends Controller {
|
|
46 |
remove_action( 'template_redirect', 'wp_redirect_admin_locations' );
|
47 |
//if prosite is activate and useremail is not defined, we need to update the
|
48 |
//email to match the new login URL
|
49 |
-
|
50 |
-
$this->add_filter( 'update_welcome_email', 'updateWelcomeEmailPrositeCase', 10, 6 );
|
51 |
-
}
|
52 |
} else {
|
53 |
if ( $isJetpackSSO ) {
|
54 |
wp_defender()->global['compatibility'][] = __( "We’ve detected a conflict with Jetpack’s Wordpress.com Log In feature. Please disable it and return to this page to continue setup.", "defender-security" );
|
@@ -88,8 +86,8 @@ class Mask_Login extends Controller {
|
|
88 |
* @return mixed
|
89 |
*/
|
90 |
public function updateWelcomeEmailPrositeCase( $welcome_email, $blog_id, $user_id, $password, $title, $meta ) {
|
91 |
-
$url
|
92 |
-
$welcome_email = str_replace( $url . 'wp-login.php', Mask_Api::getNewLoginUrl( rtrim( '/'
|
93 |
|
94 |
return $welcome_email;
|
95 |
}
|
@@ -134,7 +132,7 @@ class Mask_Login extends Controller {
|
|
134 |
* @return string
|
135 |
*/
|
136 |
private function alterLoginUrl( $currentUrl, $scheme = null ) {
|
137 |
-
if (
|
138 |
//this is URL go to old wp-login.php
|
139 |
$parts = parse_url( $currentUrl );
|
140 |
if ( isset( $parts['query'] ) ) {
|
@@ -217,7 +215,7 @@ class Mask_Login extends Controller {
|
|
217 |
}
|
218 |
|
219 |
private function _showLoginPage() {
|
220 |
-
global $error, $interim_login, $action, $user_login;
|
221 |
require_once ABSPATH . 'wp-login.php';
|
222 |
die;
|
223 |
}
|
46 |
remove_action( 'template_redirect', 'wp_redirect_admin_locations' );
|
47 |
//if prosite is activate and useremail is not defined, we need to update the
|
48 |
//email to match the new login URL
|
49 |
+
$this->add_filter( 'update_welcome_email', 'updateWelcomeEmailPrositeCase', 9999, 6 );
|
|
|
|
|
50 |
} else {
|
51 |
if ( $isJetpackSSO ) {
|
52 |
wp_defender()->global['compatibility'][] = __( "We’ve detected a conflict with Jetpack’s Wordpress.com Log In feature. Please disable it and return to this page to continue setup.", "defender-security" );
|
86 |
* @return mixed
|
87 |
*/
|
88 |
public function updateWelcomeEmailPrositeCase( $welcome_email, $blog_id, $user_id, $password, $title, $meta ) {
|
89 |
+
$url = get_blogaddress_by_id( $blog_id );
|
90 |
+
$welcome_email = str_replace( $url . 'wp-login.php', Mask_Api::getNewLoginUrl( rtrim( $url, '/' ) ), $welcome_email );
|
91 |
|
92 |
return $welcome_email;
|
93 |
}
|
132 |
* @return string
|
133 |
*/
|
134 |
private function alterLoginUrl( $currentUrl, $scheme = null ) {
|
135 |
+
if ( stristr( $currentUrl, 'wp-login.php' ) !== false ) {
|
136 |
//this is URL go to old wp-login.php
|
137 |
$parts = parse_url( $currentUrl );
|
138 |
if ( isset( $parts['query'] ) ) {
|
215 |
}
|
216 |
|
217 |
private function _showLoginPage() {
|
218 |
+
global $error, $interim_login, $action, $user_login, $user, $redirect_to;
|
219 |
require_once ABSPATH . 'wp-login.php';
|
220 |
die;
|
221 |
}
|
app/module/advanced-tools/view/2factor-otp-email-edit-from.php
CHANGED
@@ -20,7 +20,7 @@ $body = ! empty( $settings->email_body ) ? $settings->email_body : $settings-
|
|
20 |
</div>
|
21 |
</div>
|
22 |
<form method="post">
|
23 |
-
|
24 |
<div class="sui-box-body">
|
25 |
<p id="dialogDescription">
|
26 |
<?php _e( "This email sends a temporary passcode when the user can’t access their phone.", "defender-security" ) ?>
|
@@ -50,7 +50,7 @@ $body = ! empty( $settings->email_body ) ? $settings->email_body : $settings-
|
|
50 |
<?php _e( "Body", "defender-security" ) ?>
|
51 |
</label>
|
52 |
<textarea class="sui-form-control" name="body" rows="8"
|
53 |
-
id="email_body"><?php echo $body; ?></textarea>
|
54 |
</div>
|
55 |
</div>
|
56 |
<div class="sui-row">
|
20 |
</div>
|
21 |
</div>
|
22 |
<form method="post">
|
23 |
+
<?php wp_nonce_field( 'twoFactorOPTEmail' ) ?>
|
24 |
<div class="sui-box-body">
|
25 |
<p id="dialogDescription">
|
26 |
<?php _e( "This email sends a temporary passcode when the user can’t access their phone.", "defender-security" ) ?>
|
50 |
<?php _e( "Body", "defender-security" ) ?>
|
51 |
</label>
|
52 |
<textarea class="sui-form-control" name="body" rows="8"
|
53 |
+
id="email_body"><?php echo stripslashes( $body ); ?></textarea>
|
54 |
</div>
|
55 |
</div>
|
56 |
<div class="sui-row">
|
app/module/advanced-tools/view/layouts/layout.php
CHANGED
@@ -8,7 +8,8 @@
|
|
8 |
<?php if ( wp_defender()->hideDocLinks === false ): ?>
|
9 |
<div class="sui-actions-right">
|
10 |
<div class="sui-actions-right">
|
11 |
-
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/#advanced-tools"
|
|
|
12 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
13 |
</a>
|
14 |
</div>
|
@@ -39,13 +40,13 @@
|
|
39 |
<?php echo $contents ?>
|
40 |
</div>
|
41 |
</div>
|
42 |
-
|
43 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
44 |
-
|
45 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
<ul class="sui-footer-nav">
|
50 |
<li><a href="https://profiles.wordpress.org/wpmudev#content-plugins" target="_blank">Free
|
51 |
Plugins</a>
|
@@ -59,7 +60,7 @@
|
|
59 |
</li>
|
60 |
<li><a href="https://incsub.com/privacy-policy/" target="_blank">Privacy Policy</a></li>
|
61 |
</ul>
|
62 |
-
|
63 |
<ul class="sui-footer-nav">
|
64 |
<li><a href="https://premium.wpmudev.org/hub/" target="_blank">The Hub</a></li>
|
65 |
<li><a href="https://premium.wpmudev.org/projects/category/plugins/" target="_blank">Plugins</a>
|
@@ -72,7 +73,7 @@
|
|
72 |
</li>
|
73 |
<li><a href="https://incsub.com/privacy-policy/" target="_blank">Privacy Policy</a></li>
|
74 |
</ul>
|
75 |
-
|
76 |
<ul class="sui-footer-social">
|
77 |
<li><a href="https://www.facebook.com/wpmudev" target="_blank">
|
78 |
<i class="sui-icon-social-facebook" aria-hidden="true"></i>
|
@@ -87,6 +88,6 @@
|
|
87 |
<span class="sui-screen-reader-text">Instagram</span>
|
88 |
</a></li>
|
89 |
</ul>
|
90 |
-
|
91 |
</div>
|
92 |
</div>
|
8 |
<?php if ( wp_defender()->hideDocLinks === false ): ?>
|
9 |
<div class="sui-actions-right">
|
10 |
<div class="sui-actions-right">
|
11 |
+
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/#advanced-tools"
|
12 |
+
target="_blank" class="sui-button sui-button-ghost">
|
13 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
14 |
</a>
|
15 |
</div>
|
40 |
<?php echo $contents ?>
|
41 |
</div>
|
42 |
</div>
|
43 |
+
<?php if ( wp_defender()->changeFooter ): ?>
|
44 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
45 |
+
<?php else: ?>
|
46 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
47 |
+
<?php endif; ?>
|
48 |
+
<?php if ( wp_defender()->hideDocLinks == false ): ?>
|
49 |
+
<?php if ( wp_defender()->isFree ): ?>
|
50 |
<ul class="sui-footer-nav">
|
51 |
<li><a href="https://profiles.wordpress.org/wpmudev#content-plugins" target="_blank">Free
|
52 |
Plugins</a>
|
60 |
</li>
|
61 |
<li><a href="https://incsub.com/privacy-policy/" target="_blank">Privacy Policy</a></li>
|
62 |
</ul>
|
63 |
+
<?php else: ?>
|
64 |
<ul class="sui-footer-nav">
|
65 |
<li><a href="https://premium.wpmudev.org/hub/" target="_blank">The Hub</a></li>
|
66 |
<li><a href="https://premium.wpmudev.org/projects/category/plugins/" target="_blank">Plugins</a>
|
73 |
</li>
|
74 |
<li><a href="https://incsub.com/privacy-policy/" target="_blank">Privacy Policy</a></li>
|
75 |
</ul>
|
76 |
+
<?php endif; ?>
|
77 |
<ul class="sui-footer-social">
|
78 |
<li><a href="https://www.facebook.com/wpmudev" target="_blank">
|
79 |
<i class="sui-icon-social-facebook" aria-hidden="true"></i>
|
88 |
<span class="sui-screen-reader-text">Instagram</span>
|
89 |
</a></li>
|
90 |
</ul>
|
91 |
+
<?php endif; ?>
|
92 |
</div>
|
93 |
</div>
|
app/module/advanced-tools/view/login/disabled.php
CHANGED
@@ -52,10 +52,7 @@
|
|
52 |
<div class="line"></div>
|
53 |
<p><strong><?php _e( "2. Scan the barcode", "defender-security" ) ?></strong></p>
|
54 |
<p><?php _e( "Open the Google Authenticator app you just downloaded, tap the “+” symbol and then use your phone’s camera to scan the barcode below.", "defender-security" ) ?></p>
|
55 |
-
|
56 |
-
<!-- src="-->
|
57 |
-
<?php //echo \WP_Defender\Module\Advanced_Tools\Component\Auth_API::generateQRCode( urlencode( get_bloginfo( 'name' ) ) . ':' . $email, $secretKey, 149, 149, urlencode( get_bloginfo( 'name' ) ) ) ?><!--"/>-->
|
58 |
-
<?php echo \WP_Defender\Module\Advanced_Tools\Component\Auth_API::generateQRCode( urlencode( get_bloginfo( 'name' ) ) , $email, $secretKey, 149, 149, urlencode( get_bloginfo( 'name' ) ) ) ?>
|
59 |
<div class="line"></div>
|
60 |
<p><strong><?php _e( "3. Enter passcode", "defender-security" ) ?></strong></p>
|
61 |
<p>
|
@@ -75,6 +72,8 @@
|
|
75 |
</tr>
|
76 |
</tbody>
|
77 |
</table>
|
|
|
|
|
78 |
<script type="text/javascript">
|
79 |
jQuery(function ($) {
|
80 |
$('#def2qr').hide();
|
@@ -144,8 +143,9 @@
|
|
144 |
</script>
|
145 |
<?php if ( $settings->forceAuth ): ?>
|
146 |
<script type="text/javascript">
|
147 |
-
|
148 |
-
|
149 |
-
}
|
150 |
</script>
|
151 |
<?php endif; ?>
|
|
52 |
<div class="line"></div>
|
53 |
<p><strong><?php _e( "2. Scan the barcode", "defender-security" ) ?></strong></p>
|
54 |
<p><?php _e( "Open the Google Authenticator app you just downloaded, tap the “+” symbol and then use your phone’s camera to scan the barcode below.", "defender-security" ) ?></p>
|
55 |
+
<?php echo \WP_Defender\Module\Advanced_Tools\Component\Auth_API::generateQRCode( urlencode( get_bloginfo( 'name' ) ), $email, $secretKey, 149, 149, urlencode( get_bloginfo( 'name' ) ) ) ?>
|
|
|
|
|
|
|
56 |
<div class="line"></div>
|
57 |
<p><strong><?php _e( "3. Enter passcode", "defender-security" ) ?></strong></p>
|
58 |
<p>
|
72 |
</tr>
|
73 |
</tbody>
|
74 |
</table>
|
75 |
+
<script type="text/javascript"
|
76 |
+
src="<?php echo wp_defender()->getPluginUrl() . 'app/module/advanced-tools/js/qrcode.min.js' ?>"></script>
|
77 |
<script type="text/javascript">
|
78 |
jQuery(function ($) {
|
79 |
$('#def2qr').hide();
|
143 |
</script>
|
144 |
<?php if ( $settings->forceAuth ): ?>
|
145 |
<script type="text/javascript">
|
146 |
+
jQuery(function ($) {
|
147 |
+
$('html, body').animate({scrollTop: $("#show2AuthActivator").offset().top}, 1000);
|
148 |
+
});
|
149 |
</script>
|
150 |
<?php endif; ?>
|
151 |
+
|
app/module/advanced-tools/view/main-free.php
CHANGED
@@ -89,8 +89,8 @@
|
|
89 |
</div>
|
90 |
<div class="sui-box-settings-col-2">
|
91 |
<div class="sui-form-field">
|
|
|
92 |
<label class="sui-toggle">
|
93 |
-
<input type="hidden" name="lostPhone" value="0"/>
|
94 |
<input role="presentation" type="checkbox" name="lostPhone" class="toggle-checkbox"
|
95 |
id="lostPhone" value="1"
|
96 |
<?php checked( true, $settings->lostPhone ) ?>/>
|
@@ -113,8 +113,8 @@
|
|
113 |
</div>
|
114 |
<div class="sui-box-settings-col-2">
|
115 |
<div class="sui-form-field">
|
|
|
116 |
<label class="sui-toggle">
|
117 |
-
<input type="hidden" name="forceAuth" value="0"/>
|
118 |
<input role="presentation" type="checkbox" name="forceAuth" class="toggle-checkbox"
|
119 |
id="forceAuth" value="1"
|
120 |
<?php checked( true, $settings->forceAuth ) ?>/>
|
89 |
</div>
|
90 |
<div class="sui-box-settings-col-2">
|
91 |
<div class="sui-form-field">
|
92 |
+
<input type="hidden" name="lostPhone" value="0"/>
|
93 |
<label class="sui-toggle">
|
|
|
94 |
<input role="presentation" type="checkbox" name="lostPhone" class="toggle-checkbox"
|
95 |
id="lostPhone" value="1"
|
96 |
<?php checked( true, $settings->lostPhone ) ?>/>
|
113 |
</div>
|
114 |
<div class="sui-box-settings-col-2">
|
115 |
<div class="sui-form-field">
|
116 |
+
<input type="hidden" name="forceAuth" value="0"/>
|
117 |
<label class="sui-toggle">
|
|
|
118 |
<input role="presentation" type="checkbox" name="forceAuth" class="toggle-checkbox"
|
119 |
id="forceAuth" value="1"
|
120 |
<?php checked( true, $settings->forceAuth ) ?>/>
|
app/module/advanced-tools/view/main.php
CHANGED
@@ -87,8 +87,8 @@
|
|
87 |
</div>
|
88 |
<div class="sui-box-settings-col-2">
|
89 |
<div class="sui-form-field">
|
|
|
90 |
<label class="sui-toggle">
|
91 |
-
<input type="hidden" name="lostPhone" value="0"/>
|
92 |
<input role="presentation" type="checkbox" name="lostPhone" class="toggle-checkbox"
|
93 |
id="lostPhone" value="1"
|
94 |
<?php checked( true, $settings->lostPhone ) ?>/>
|
@@ -111,8 +111,8 @@
|
|
111 |
</div>
|
112 |
<div class="sui-box-settings-col-2">
|
113 |
<div class="sui-form-field">
|
|
|
114 |
<label class="sui-toggle">
|
115 |
-
<input type="hidden" name="forceAuth" value="0"/>
|
116 |
<input role="presentation" type="checkbox" name="forceAuth" class="toggle-checkbox"
|
117 |
id="forceAuth" value="1"
|
118 |
<?php checked( true, $settings->forceAuth ) ?>/>
|
@@ -163,8 +163,8 @@
|
|
163 |
</span>
|
164 |
</div>
|
165 |
<div class="sui-box-settings-col-2">
|
|
|
166 |
<label class="sui-toggle">
|
167 |
-
<input type="hidden" name="customGraphic" value="0"/>
|
168 |
<input role="presentation" type="checkbox" name="customGraphic" class="toggle-checkbox"
|
169 |
id="customGraphic" value="1"
|
170 |
<?php checked( true, $settings->customGraphic ) ?>/>
|
@@ -238,7 +238,7 @@
|
|
238 |
<?php _e( "App Download", "defender-security" ) ?>
|
239 |
</span>
|
240 |
<span class="sui-description">
|
241 |
-
<?php _e( 'Need the app? Here’s links to the official Google Authenticator apps.', "defender-security" ); ?>
|
242 |
</span>
|
243 |
</div>
|
244 |
<div class="sui-box-settings-col-2">
|
@@ -256,7 +256,7 @@
|
|
256 |
<?php _e( "Active Users", "defender-security" ) ?>
|
257 |
</span>
|
258 |
<span class="sui-description">
|
259 |
-
<?php _e( "Here’s a quick link to see which of your users have enabled two-factor
|
260 |
</span>
|
261 |
</div>
|
262 |
<div class="sui-box-settings-col-2">
|
87 |
</div>
|
88 |
<div class="sui-box-settings-col-2">
|
89 |
<div class="sui-form-field">
|
90 |
+
<input type="hidden" name="lostPhone" value="0"/>
|
91 |
<label class="sui-toggle">
|
|
|
92 |
<input role="presentation" type="checkbox" name="lostPhone" class="toggle-checkbox"
|
93 |
id="lostPhone" value="1"
|
94 |
<?php checked( true, $settings->lostPhone ) ?>/>
|
111 |
</div>
|
112 |
<div class="sui-box-settings-col-2">
|
113 |
<div class="sui-form-field">
|
114 |
+
<input type="hidden" name="forceAuth" value="0"/>
|
115 |
<label class="sui-toggle">
|
|
|
116 |
<input role="presentation" type="checkbox" name="forceAuth" class="toggle-checkbox"
|
117 |
id="forceAuth" value="1"
|
118 |
<?php checked( true, $settings->forceAuth ) ?>/>
|
163 |
</span>
|
164 |
</div>
|
165 |
<div class="sui-box-settings-col-2">
|
166 |
+
<input type="hidden" name="customGraphic" value="0"/>
|
167 |
<label class="sui-toggle">
|
|
|
168 |
<input role="presentation" type="checkbox" name="customGraphic" class="toggle-checkbox"
|
169 |
id="customGraphic" value="1"
|
170 |
<?php checked( true, $settings->customGraphic ) ?>/>
|
238 |
<?php _e( "App Download", "defender-security" ) ?>
|
239 |
</span>
|
240 |
<span class="sui-description">
|
241 |
+
<?php _e( 'Need the app? Here’s links to the official Google Authenticator iOS and Android apps.', "defender-security" ); ?>
|
242 |
</span>
|
243 |
</div>
|
244 |
<div class="sui-box-settings-col-2">
|
256 |
<?php _e( "Active Users", "defender-security" ) ?>
|
257 |
</span>
|
258 |
<span class="sui-description">
|
259 |
+
<?php _e( "Here’s a quick link to see which of your users have enabled two-factor authentication.", "defender-security" ) ?>
|
260 |
</span>
|
261 |
</div>
|
262 |
<div class="sui-box-settings-col-2">
|
app/module/advanced-tools/view/mask-login/enabled.php
CHANGED
@@ -66,14 +66,14 @@
|
|
66 |
</div>
|
67 |
|
68 |
<div class="sui-box-settings-col-2">
|
|
|
69 |
<label class="sui-toggle">
|
70 |
-
<input type="hidden" name="redirectTraffic" value="0"/>
|
71 |
<input role="presentation" type="checkbox" name="redirectTraffic" class="toggle-checkbox"
|
72 |
id="redirectTraffic" value="1"
|
73 |
<?php checked( true, $settings->redirectTraffic ) ?>/>
|
74 |
<span class="sui-toggle-slider"></span>
|
75 |
</label>
|
76 |
-
<label for="
|
77 |
<?php _e( "Enable 404 redirection", "defender-security" ) ?>
|
78 |
</label>
|
79 |
<div id="redirectTrafficContainer" class="sui-border-frame sui-toggle-content"
|
66 |
</div>
|
67 |
|
68 |
<div class="sui-box-settings-col-2">
|
69 |
+
<input type="hidden" name="redirectTraffic" value="0"/>
|
70 |
<label class="sui-toggle">
|
|
|
71 |
<input role="presentation" type="checkbox" name="redirectTraffic" class="toggle-checkbox"
|
72 |
id="redirectTraffic" value="1"
|
73 |
<?php checked( true, $settings->redirectTraffic ) ?>/>
|
74 |
<span class="sui-toggle-slider"></span>
|
75 |
</label>
|
76 |
+
<label for="redirectTraffic" class="sui-toggle-label">
|
77 |
<?php _e( "Enable 404 redirection", "defender-security" ) ?>
|
78 |
</label>
|
79 |
<div id="redirectTrafficContainer" class="sui-border-frame sui-toggle-content"
|
app/module/hardener/component/change-admin.php
CHANGED
@@ -17,6 +17,10 @@ class Change_Admin extends Rule {
|
|
17 |
$this->renderPartial( 'rules/change-admin' );
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
20 |
public function check() {
|
21 |
return $this->getService()->check();
|
22 |
}
|
17 |
$this->renderPartial( 'rules/change-admin' );
|
18 |
}
|
19 |
|
20 |
+
public function getSubDescription() {
|
21 |
+
return __( "You have a user account with the admin username.", "defender-security" );
|
22 |
+
}
|
23 |
+
|
24 |
public function check() {
|
25 |
return $this->getService()->check();
|
26 |
}
|
app/module/hardener/component/db-prefix.php
CHANGED
@@ -22,6 +22,13 @@ class DB_Prefix extends Rule {
|
|
22 |
return $this->getService()->check();
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
function addHooks() {
|
26 |
$this->add_action( 'processingHardener' . self::$slug, 'process' );
|
27 |
$this->add_action( 'processRevert' . self::$slug, 'revert' );
|
@@ -60,7 +67,7 @@ class DB_Prefix extends Rule {
|
|
60 |
wp_send_json_error( array(
|
61 |
'message' => $ret->get_error_message()
|
62 |
) );
|
63 |
-
}
|
64 |
}
|
65 |
|
66 |
/**
|
22 |
return $this->getService()->check();
|
23 |
}
|
24 |
|
25 |
+
/**
|
26 |
+
* @return mixed
|
27 |
+
*/
|
28 |
+
function getSubDescription() {
|
29 |
+
return __( "Your database prefix is the default wp_ prefix.", "defender-security" );
|
30 |
+
}
|
31 |
+
|
32 |
function addHooks() {
|
33 |
$this->add_action( 'processingHardener' . self::$slug, 'process' );
|
34 |
$this->add_action( 'processRevert' . self::$slug, 'revert' );
|
67 |
wp_send_json_error( array(
|
68 |
'message' => $ret->get_error_message()
|
69 |
) );
|
70 |
+
};
|
71 |
}
|
72 |
|
73 |
/**
|
app/module/hardener/component/disable-file-editor.php
CHANGED
@@ -16,6 +16,10 @@ class Disable_File_Editor extends Rule {
|
|
16 |
$this->renderPartial( 'rules/disable-file-editor' );
|
17 |
}
|
18 |
|
|
|
|
|
|
|
|
|
19 |
function check() {
|
20 |
return $this->getService()->check();
|
21 |
}
|
16 |
$this->renderPartial( 'rules/disable-file-editor' );
|
17 |
}
|
18 |
|
19 |
+
function getSubDescription() {
|
20 |
+
return __( "The file editor is currently enabled.", "defender-security" );
|
21 |
+
}
|
22 |
+
|
23 |
function check() {
|
24 |
return $this->getService()->check();
|
25 |
}
|
app/module/hardener/component/disable-trackback.php
CHANGED
@@ -17,6 +17,10 @@ class Disable_Trackback extends Rule {
|
|
17 |
$this->renderPartial( 'rules/disable-trackback' );
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
20 |
/**
|
21 |
* @return bool
|
22 |
*/
|
@@ -66,8 +70,8 @@ class Disable_Trackback extends Rule {
|
|
66 |
if ( ! $this->verifyNonce() ) {
|
67 |
return;
|
68 |
}
|
69 |
-
$process_posts
|
70 |
-
$this->getService()->process_posts
|
71 |
|
72 |
$ret = $this->getService()->process();
|
73 |
if ( ! is_wp_error( $ret ) ) {
|
17 |
$this->renderPartial( 'rules/disable-trackback' );
|
18 |
}
|
19 |
|
20 |
+
function getSubDescription() {
|
21 |
+
return __( "Trackbacks and pingbacks are currently enabled.", "defender-security" );
|
22 |
+
}
|
23 |
+
|
24 |
/**
|
25 |
* @return bool
|
26 |
*/
|
70 |
if ( ! $this->verifyNonce() ) {
|
71 |
return;
|
72 |
}
|
73 |
+
$process_posts = HTTP_Helper::retrieve_post( 'updatePosts' );
|
74 |
+
$this->getService()->process_posts = $process_posts;
|
75 |
|
76 |
$ret = $this->getService()->process();
|
77 |
if ( ! is_wp_error( $ret ) ) {
|
app/module/hardener/component/disable-xml-rpc.php
CHANGED
@@ -17,6 +17,10 @@ class Disable_Xml_Rpc extends Rule {
|
|
17 |
$this->renderPartial( 'rules/disable-xml-rpc' );
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
20 |
/**
|
21 |
* @return bool
|
22 |
*/
|
17 |
$this->renderPartial( 'rules/disable-xml-rpc' );
|
18 |
}
|
19 |
|
20 |
+
function getSubDescription() {
|
21 |
+
return __( "XML-RPC is currently enabled.", "defender-security" );
|
22 |
+
}
|
23 |
+
|
24 |
/**
|
25 |
* @return bool
|
26 |
*/
|
app/module/hardener/component/hide-error.php
CHANGED
@@ -29,6 +29,10 @@ class Hide_Error extends Rule {
|
|
29 |
return $stat;
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
32 |
public function getTitle() {
|
33 |
return __( "Hide error reporting", "defender-security" );
|
34 |
}
|
29 |
return $stat;
|
30 |
}
|
31 |
|
32 |
+
function getSubDescription() {
|
33 |
+
return __( "Error debugging is currently allowed.", "defender-security" );
|
34 |
+
}
|
35 |
+
|
36 |
public function getTitle() {
|
37 |
return __( "Hide error reporting", "defender-security" );
|
38 |
}
|
app/module/hardener/component/login-duration.php
CHANGED
@@ -32,6 +32,12 @@ class Login_Duration extends Rule {
|
|
32 |
$this->renderPartial( 'rules/login-duration' );
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
/**
|
36 |
* @return string
|
37 |
*/
|
@@ -53,7 +59,7 @@ class Login_Duration extends Rule {
|
|
53 |
if ( $this->check() ) {
|
54 |
$this->add_filter( 'auth_cookie_expiration', 'cookie_duration', 10, 3 );
|
55 |
$this->add_filter( 'login_message', 'login_message' );
|
56 |
-
|
57 |
}
|
58 |
|
59 |
}
|
@@ -113,6 +119,8 @@ class Login_Duration extends Rule {
|
|
113 |
|
114 |
/**
|
115 |
* Check login of users
|
|
|
|
|
116 |
*/
|
117 |
function check_login() {
|
118 |
$defender_logout = HTTP_Helper::retrieve_get( 'defender_logout', false );
|
@@ -212,13 +220,17 @@ class Login_Duration extends Rule {
|
|
212 |
* @return Integer $duration
|
213 |
*/
|
214 |
function cookie_duration( $duration, $user_id, $remember ) {
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
|
|
|
|
217 |
}
|
218 |
|
|
|
219 |
return $duration;
|
220 |
}
|
221 |
|
222 |
-
}
|
223 |
-
|
224 |
-
?>
|
32 |
$this->renderPartial( 'rules/login-duration' );
|
33 |
}
|
34 |
|
35 |
+
function getSubDescription() {
|
36 |
+
$days = $this->getService()->getDuration();
|
37 |
+
|
38 |
+
return sprintf( __( "Your current login duration is the default %d days.", "defender-security" ), $days );
|
39 |
+
}
|
40 |
+
|
41 |
/**
|
42 |
* @return string
|
43 |
*/
|
59 |
if ( $this->check() ) {
|
60 |
$this->add_filter( 'auth_cookie_expiration', 'cookie_duration', 10, 3 );
|
61 |
$this->add_filter( 'login_message', 'login_message' );
|
62 |
+
//$this->add_action( 'wp_loaded', 'check_login' );
|
63 |
}
|
64 |
|
65 |
}
|
119 |
|
120 |
/**
|
121 |
* Check login of users
|
122 |
+
* @deprecated since 2.1.3
|
123 |
+
* We just need to alter the cookies time so wordpress will do the rest
|
124 |
*/
|
125 |
function check_login() {
|
126 |
$defender_logout = HTTP_Helper::retrieve_get( 'defender_logout', false );
|
220 |
* @return Integer $duration
|
221 |
*/
|
222 |
function cookie_duration( $duration, $user_id, $remember ) {
|
223 |
+
$dur = $this->getService()->getDuration( true );
|
224 |
+
if ( $dur < 2 ) {
|
225 |
+
//duration set smaller than 2 days, use the custom for both remember & non remeber
|
226 |
+
return $dur;
|
227 |
+
} elseif ( $remember ) {
|
228 |
+
//this case only
|
229 |
+
return $dur;
|
230 |
}
|
231 |
|
232 |
+
//return default
|
233 |
return $duration;
|
234 |
}
|
235 |
|
236 |
+
}
|
|
|
|
app/module/hardener/component/php-version.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
|
6 |
namespace WP_Defender\Module\Hardener\Component;
|
7 |
|
|
|
8 |
use WP_Defender\Module\Hardener\Rule;
|
9 |
|
10 |
class PHP_Version extends Rule {
|
@@ -15,6 +16,12 @@ class PHP_Version extends Rule {
|
|
15 |
$this->renderPartial( 'rules/php-version' );
|
16 |
}
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* @return bool
|
20 |
*/
|
5 |
|
6 |
namespace WP_Defender\Module\Hardener\Component;
|
7 |
|
8 |
+
use WP_Defender\Module\Hardener\Model\Settings;
|
9 |
use WP_Defender\Module\Hardener\Rule;
|
10 |
|
11 |
class PHP_Version extends Rule {
|
16 |
$this->renderPartial( 'rules/php-version' );
|
17 |
}
|
18 |
|
19 |
+
function getSubDescription() {
|
20 |
+
$settings = Settings::instance();
|
21 |
+
|
22 |
+
return sprintf( __( "PHP versions older than %s are no longer supported. For security and stability we strongly recommend you upgrade your PHP version to version %s or newer as soon as possible. ", "defender-security" ), $settings->min_php_version, $settings->min_php_version );
|
23 |
+
}
|
24 |
+
|
25 |
/**
|
26 |
* @return bool
|
27 |
*/
|
app/module/hardener/component/prevent-php.php
CHANGED
@@ -22,6 +22,10 @@ class Prevent_Php extends Rule {
|
|
22 |
$this->renderPartial( 'rules/prevent-php-executed' );
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
25 |
/**
|
26 |
* @return bool|false|mixed|null
|
27 |
*/
|
22 |
$this->renderPartial( 'rules/prevent-php-executed' );
|
23 |
}
|
24 |
|
25 |
+
function getSubDescription() {
|
26 |
+
return __( "PHP execution is currently allowed in all directories.", "defender-security" );
|
27 |
+
}
|
28 |
+
|
29 |
/**
|
30 |
* @return bool|false|mixed|null
|
31 |
*/
|
app/module/hardener/component/protect-information.php
CHANGED
@@ -17,6 +17,10 @@ class Protect_Information extends Rule {
|
|
17 |
$this->renderPartial( 'rules/protect-information' );
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
20 |
/**
|
21 |
* @return bool|false|mixed|null
|
22 |
*/
|
17 |
$this->renderPartial( 'rules/protect-information' );
|
18 |
}
|
19 |
|
20 |
+
function getSubDescription() {
|
21 |
+
return __( "You don't have information disclosure protection active.", "defender-security" );
|
22 |
+
}
|
23 |
+
|
24 |
/**
|
25 |
* @return bool|false|mixed|null
|
26 |
*/
|
app/module/hardener/component/security-key.php
CHANGED
@@ -34,6 +34,10 @@ class Security_Key extends Rule {
|
|
34 |
) );
|
35 |
}
|
36 |
|
|
|
|
|
|
|
|
|
37 |
/**
|
38 |
* @return string
|
39 |
*/
|
34 |
) );
|
35 |
}
|
36 |
|
37 |
+
function getSubDescription() {
|
38 |
+
return sprintf( __( "Your current security keys are %s days old. Time to update them!", "defender-security" ), $this->check() );
|
39 |
+
}
|
40 |
+
|
41 |
/**
|
42 |
* @return string
|
43 |
*/
|
app/module/hardener/component/wp-version.php
CHANGED
@@ -22,6 +22,10 @@ class WP_Version extends Rule {
|
|
22 |
return $this->getService()->check();
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
25 |
function revert() {
|
26 |
// TODO: Implement revert() method.
|
27 |
}
|
22 |
return $this->getService()->check();
|
23 |
}
|
24 |
|
25 |
+
function getSubDescription() {
|
26 |
+
return sprintf( __( "Your current WordPress version is out of date, which means you could be missing out on the latest security patches in v%s", "defender-security" ), $this->getService()->getLatestVersion() );
|
27 |
+
}
|
28 |
+
|
29 |
function revert() {
|
30 |
// TODO: Implement revert() method.
|
31 |
}
|
app/module/hardener/controller/main.php
CHANGED
@@ -47,11 +47,14 @@ class Main extends Controller {
|
|
47 |
$this->add_ajax_action( 'restoreHardener', 'restoreHardener' );
|
48 |
$this->add_ajax_action( 'updateHardener', 'updateHardener' );
|
49 |
$this->add_ajax_action( 'saveTweaksSettings', 'saveTweaksSettings' );
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
|
54 |
$this->add_action( 'tweaksSendNotification', 'tweaksSendNotification' );
|
|
|
|
|
|
|
55 |
|
56 |
$view = HTTP_Helper::retrieve_get( 'view' );
|
57 |
$id = isset( $_REQUEST['id'] ) ? $_REQUEST['id'] : 0;
|
@@ -99,13 +102,22 @@ class Main extends Controller {
|
|
99 |
//no honey no email
|
100 |
return;
|
101 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
|
|
|
|
|
|
|
103 |
if ( $settings->last_sent == null ) {
|
104 |
//this is the case user install this and never check the page
|
105 |
//send report
|
106 |
foreach ( $settings->receipts as $receipt ) {
|
107 |
$email = $receipt['email'];
|
108 |
-
wp_mail( $email,
|
109 |
}
|
110 |
$settings->last_sent = time();
|
111 |
$settings->save();
|
@@ -118,13 +130,45 @@ class Main extends Controller {
|
|
118 |
|
119 |
foreach ( $settings->receipts as $receipt ) {
|
120 |
$email = $receipt['email'];
|
121 |
-
wp_mail( $email,
|
122 |
}
|
123 |
$settings->last_sent = time();
|
124 |
$settings->save();
|
125 |
}
|
126 |
}
|
127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
public function saveTweaksSettings() {
|
129 |
if ( ! $this->checkPermission() ) {
|
130 |
return;
|
47 |
$this->add_ajax_action( 'restoreHardener', 'restoreHardener' );
|
48 |
$this->add_ajax_action( 'updateHardener', 'updateHardener' );
|
49 |
$this->add_ajax_action( 'saveTweaksSettings', 'saveTweaksSettings' );
|
50 |
+
if ( ! wp_next_scheduled( 'tweaksSendNotification' ) ) {
|
51 |
+
wp_schedule_event( time(), 'twicedaily', 'tweaksSendNotification' );
|
52 |
+
}
|
53 |
|
54 |
$this->add_action( 'tweaksSendNotification', 'tweaksSendNotification' );
|
55 |
+
if ( isset( $_GET['email'] ) ) {
|
56 |
+
$this->tweaksSendNotification();
|
57 |
+
}
|
58 |
|
59 |
$view = HTTP_Helper::retrieve_get( 'view' );
|
60 |
$id = isset( $_REQUEST['id'] ) ? $_REQUEST['id'] : 0;
|
102 |
//no honey no email
|
103 |
return;
|
104 |
}
|
105 |
+
$no_reply_email = "noreply@" . parse_url( get_site_url(), PHP_URL_HOST );
|
106 |
+
$no_reply_email = apply_filters( 'wd_scan_noreply_email', $no_reply_email );
|
107 |
+
$headers = array(
|
108 |
+
'From: Defender <' . $no_reply_email . '>',
|
109 |
+
'Content-Type: text/html; charset=UTF-8'
|
110 |
+
);
|
111 |
|
112 |
+
$subject = _n( 'Security Tweak Report for %s. %s tweak needs attention.', 'Security Tweak Report for %s. %s tweaks needs attention.', count( $tweaks ), "defender-security" );
|
113 |
+
$subject = sprintf( $subject, network_site_url(), count( $tweaks ) );
|
114 |
+
|
115 |
if ( $settings->last_sent == null ) {
|
116 |
//this is the case user install this and never check the page
|
117 |
//send report
|
118 |
foreach ( $settings->receipts as $receipt ) {
|
119 |
$email = $receipt['email'];
|
120 |
+
wp_mail( $email, $subject, $this->prepareEmailContent( $receipt['first_name'] ), $headers );
|
121 |
}
|
122 |
$settings->last_sent = time();
|
123 |
$settings->save();
|
130 |
|
131 |
foreach ( $settings->receipts as $receipt ) {
|
132 |
$email = $receipt['email'];
|
133 |
+
wp_mail( $email, $subject, $this->prepareEmailContent( $receipt['first_name'] ), $headers );
|
134 |
}
|
135 |
$settings->last_sent = time();
|
136 |
$settings->save();
|
137 |
}
|
138 |
}
|
139 |
|
140 |
+
private function prepareEmailContent( $firstName ) {
|
141 |
+
$issues = "";
|
142 |
+
foreach ( Hardener\Model\Settings::instance()->getIssues() as $issue ) {
|
143 |
+
$issue = '<tr style="border:none;padding:0;text-align:left;vertical-align:top">
|
144 |
+
<td class="wpmudev-table__row--label"
|
145 |
+
style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;border-radius:0 0 0 4px;border-top:.5px solid #d8d8d8;color:#333;font-family:\'Open Sans\',Helvetica,Arial,sans-serif;font-size:16px;font-weight:600;hyphens:auto;line-height:20px;margin:0;padding:10px 15px;text-align:left;vertical-align:top;word-wrap:break-word">
|
146 |
+
<img class="wpmudev-table__icon"
|
147 |
+
src="' . wp_defender()->getPluginUrl() . 'assets/email-assets/img/Warning@2x.png"
|
148 |
+
alt="Hero Image"
|
149 |
+
style="-ms-interpolation-mode:bicubic;clear:both;display:inline-block;margin-right:10px;max-width:100%;outline:0;text-decoration:none;vertical-align:middle;width:18px">
|
150 |
+
' . $issue->getTitle() . '
|
151 |
+
<span style="color: #888888;font-family: \'Open Sans\';padding-left: 32px;font-size: 13px;font-weight:300;letter-spacing: -0.25px;line-height: 22px;display: block">
|
152 |
+
' . $issue->getSubDescription() . '
|
153 |
+
</span>
|
154 |
+
</td>
|
155 |
+
<td class="wpmudev-table__row--warning text-right"
|
156 |
+
style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;border-radius:0 0 4px 0;border-top:.5px solid #d8d8d8;color:#FACD25;font-family:\'Open Sans\',Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;hyphens:auto;line-height:20px;margin:0;padding:10px 15px;text-align:right;vertical-align:top;word-wrap:break-word">
|
157 |
+
</td>
|
158 |
+
</tr>';
|
159 |
+
$issues .= $issue;
|
160 |
+
}
|
161 |
+
$contents = $this->renderPartial( 'email/notification', array(
|
162 |
+
'userName' => $firstName,
|
163 |
+
'siteUrl' => network_site_url(),
|
164 |
+
'viewUrl' => network_admin_url( 'admin.php?page=wdf-hardener' ),
|
165 |
+
'issues' => $issues,
|
166 |
+
'count' => count( Hardener\Model\Settings::instance()->getIssues() )
|
167 |
+
), false );
|
168 |
+
|
169 |
+
return $contents;
|
170 |
+
}
|
171 |
+
|
172 |
public function saveTweaksSettings() {
|
173 |
if ( ! $this->checkPermission() ) {
|
174 |
return;
|
app/module/hardener/rule.php
CHANGED
@@ -28,6 +28,12 @@ abstract class Rule extends Component {
|
|
28 |
*/
|
29 |
abstract function getDescription();
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
/**
|
32 |
* @return mixed
|
33 |
*/
|
@@ -130,15 +136,15 @@ abstract class Rule extends Component {
|
|
130 |
<div class="sui-accordion-item-header">
|
131 |
<div class="sui-accordion-item-title">
|
132 |
<i aria-hidden="true" class="sui-icon-eye-hide"></i>
|
133 |
-
|
134 |
<div class="sui-actions-right">
|
135 |
<form method="post" class="float-r hardener-frm rule-process">
|
136 |
-
|
137 |
<input type="hidden" name="action" value="restoreHardener"/>
|
138 |
<input type="hidden" name="slug" value="<?php echo static::$slug ?>"/>
|
139 |
<button type="submit" class="sui-button sui-button-ghost">
|
140 |
<i class="sui-icon-update" aria-hidden="true"></i>
|
141 |
-
|
142 |
</button>
|
143 |
</form>
|
144 |
</div>
|
28 |
*/
|
29 |
abstract function getDescription();
|
30 |
|
31 |
+
/**
|
32 |
+
* Return this rule reason
|
33 |
+
* @return mixed
|
34 |
+
*/
|
35 |
+
abstract function getSubDescription();
|
36 |
+
|
37 |
/**
|
38 |
* @return mixed
|
39 |
*/
|
136 |
<div class="sui-accordion-item-header">
|
137 |
<div class="sui-accordion-item-title">
|
138 |
<i aria-hidden="true" class="sui-icon-eye-hide"></i>
|
139 |
+
<?php echo $this->getTitle(); ?>
|
140 |
<div class="sui-actions-right">
|
141 |
<form method="post" class="float-r hardener-frm rule-process">
|
142 |
+
<?php $this->createNonceField(); ?>
|
143 |
<input type="hidden" name="action" value="restoreHardener"/>
|
144 |
<input type="hidden" name="slug" value="<?php echo static::$slug ?>"/>
|
145 |
<button type="submit" class="sui-button sui-button-ghost">
|
146 |
<i class="sui-icon-update" aria-hidden="true"></i>
|
147 |
+
<?php _e( "Restore", "defender-security" ) ?>
|
148 |
</button>
|
149 |
</form>
|
150 |
</div>
|
app/module/hardener/view/email/notification.php
ADDED
@@ -0,0 +1,366 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2 |
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3 |
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="background:#f3f3f3!important">
|
4 |
+
<head>
|
5 |
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
6 |
+
<meta name="viewport" content="width=device-width"><!-- Import Open Sans Webfont -->
|
7 |
+
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i,700,700i" rel="stylesheet">
|
8 |
+
<title></title>
|
9 |
+
<style>@media only screen {
|
10 |
+
html {
|
11 |
+
min-height: 100%;
|
12 |
+
background: #f3f3f3
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
@media only screen and (max-width: 615px) {
|
17 |
+
.small-float-center {
|
18 |
+
margin: 0 auto !important;
|
19 |
+
float: none !important;
|
20 |
+
text-align: center !important
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
@media only screen and (max-width: 615px) {
|
25 |
+
table.body img {
|
26 |
+
width: auto;
|
27 |
+
height: auto
|
28 |
+
}
|
29 |
+
|
30 |
+
table.body center {
|
31 |
+
min-width: 0 !important
|
32 |
+
}
|
33 |
+
|
34 |
+
table.body .container {
|
35 |
+
width: 95% !important
|
36 |
+
}
|
37 |
+
|
38 |
+
table.body .columns {
|
39 |
+
height: auto !important;
|
40 |
+
-moz-box-sizing: border-box;
|
41 |
+
-webkit-box-sizing: border-box;
|
42 |
+
box-sizing: border-box;
|
43 |
+
padding-left: 15px !important;
|
44 |
+
padding-right: 15px !important
|
45 |
+
}
|
46 |
+
|
47 |
+
th.small-12 {
|
48 |
+
display: inline-block !important;
|
49 |
+
width: 100% !important
|
50 |
+
}
|
51 |
+
|
52 |
+
table.menu {
|
53 |
+
width: 100% !important
|
54 |
+
}
|
55 |
+
|
56 |
+
table.menu td, table.menu th {
|
57 |
+
width: auto !important;
|
58 |
+
display: inline-block !important
|
59 |
+
}
|
60 |
+
|
61 |
+
table.menu.vertical td, table.menu.vertical th {
|
62 |
+
display: block !important
|
63 |
+
}
|
64 |
+
|
65 |
+
table.menu[align=center] {
|
66 |
+
width: auto !important
|
67 |
+
}
|
68 |
+
}</style>
|
69 |
+
<style type="text/css">@media only screen and (min-width: 615px) {
|
70 |
+
h1 {
|
71 |
+
padding-top: 40px !important
|
72 |
+
}
|
73 |
+
|
74 |
+
table.body .column.first, table.body .columns.first {
|
75 |
+
padding-left: 60px !important
|
76 |
+
}
|
77 |
+
|
78 |
+
table.body .column.last, table.body .columns.last {
|
79 |
+
padding-right: 60px !important
|
80 |
+
}
|
81 |
+
|
82 |
+
.article-block .article-block__heading {
|
83 |
+
font-size: 15px !important;
|
84 |
+
line-height: 20px !important;
|
85 |
+
Margin: 20px 0 20px -15px !important;
|
86 |
+
font-weight: 400 !important
|
87 |
+
}
|
88 |
+
|
89 |
+
.article-block .article-block__img {
|
90 |
+
height: 90px !important;
|
91 |
+
width: 130px !important
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
@media only screen and (min-width: 450px) {
|
96 |
+
span.whip-issue-tag {
|
97 |
+
position: relative !important;
|
98 |
+
left: 0 !important;
|
99 |
+
transform: translateX(0) !important;
|
100 |
+
display: inline-block !important
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
@media only screen and (max-width: 450px) {
|
105 |
+
h1.whip-orange:first-of-type {
|
106 |
+
padding-top: 55px !important
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
@media only screen {
|
111 |
+
table.button:hover table td {
|
112 |
+
background: #0092CA !important
|
113 |
+
}
|
114 |
+
|
115 |
+
table.button.secondary:hover table td {
|
116 |
+
background: #6F6F6F !important
|
117 |
+
}
|
118 |
+
|
119 |
+
table.button.success:hover table td {
|
120 |
+
background: #01A383 !important
|
121 |
+
}
|
122 |
+
|
123 |
+
table.button.warning:hover table td {
|
124 |
+
background: #E1B40C !important
|
125 |
+
}
|
126 |
+
|
127 |
+
table.button.alert:hover table td {
|
128 |
+
background: #D33F27 !important
|
129 |
+
}
|
130 |
+
}</style>
|
131 |
+
</head>
|
132 |
+
<body style="-moz-box-sizing:border-box;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-text-size-adjust:100%;Margin:0;background:#f3f3f3!important;box-sizing:border-box;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;min-width:100%;padding:0;text-align:left;width:100%!important">
|
133 |
+
<table class="body"
|
134 |
+
style="Margin:0;background:#f3f3f3!important;border-collapse:collapse;border-spacing:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;height:100%;line-height:25px;margin:0;padding:0;text-align:left;vertical-align:top;width:100%">
|
135 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
136 |
+
<td class="center" align="center" valign="top"
|
137 |
+
style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;hyphens:auto;line-height:25px;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
|
138 |
+
<center data-parsed style="min-width:600px;width:100%">
|
139 |
+
<table align="center" class="container view-in-browser float-center"
|
140 |
+
style="Margin:0 auto;background:0 0;border-collapse:collapse;border-spacing:0;float:none;height:50px;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:600px">
|
141 |
+
<tbody>
|
142 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
143 |
+
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;hyphens:auto;line-height:25px;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
|
144 |
+
<div class="text-right" style="text-align:right"><a href="https://premium.wpmudev.org"
|
145 |
+
style="Margin:0;color:#888;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:50px;margin:0;margin-right:10px;padding:0;text-align:right;text-decoration:none">View
|
146 |
+
in browser</a></div>
|
147 |
+
</td>
|
148 |
+
</tr>
|
149 |
+
</tbody>
|
150 |
+
</table>
|
151 |
+
<table align="center" class="container main-content float-center"
|
152 |
+
style="Margin:0 auto;background:#fff;border-collapse:collapse;border-radius:4px;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:600px">
|
153 |
+
<tbody>
|
154 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
155 |
+
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;hyphens:auto;line-height:25px;margin:0;padding:0;padding-bottom:55px!important;text-align:left;vertical-align:top;word-wrap:break-word">
|
156 |
+
<div class="hero-image" style="height:150px"><img
|
157 |
+
src="<?php echo wp_defender()->getPluginUrl() ?>assets/email-assets/img/Defender-widerec@2x.png"
|
158 |
+
alt="Hero Image"
|
159 |
+
style="-ms-interpolation-mode:bicubic;border-radius:4px 4px 0 0;clear:both;display:block;height:100%;max-width:100%;object-fit:cover;outline:0;text-decoration:none;width:auto">
|
160 |
+
</div>
|
161 |
+
<table class="row"
|
162 |
+
style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
|
163 |
+
<tbody>
|
164 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
165 |
+
<th class="small-12 large-12 columns first last"
|
166 |
+
style="Margin:0 auto;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0 auto;padding:0;padding-bottom:15px;padding-left:15px;padding-right:15px;text-align:left;width:585px">
|
167 |
+
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
|
168 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
169 |
+
<th style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0;text-align:left">
|
170 |
+
<h1 style="-webkit-font-smoothing:antialiased;Margin:0;Margin-bottom:10px;color:inherit;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:22px;font-smoothing:antialiased;font-weight:600;line-height:25px;margin:0;margin-bottom:30px;padding:0;padding-top:30px;text-align:left;word-wrap:normal">
|
171 |
+
<?php printf( __( "Security tweak report for %s", "defender-security" ), $siteUrl ) ?>
|
172 |
+
</h1>
|
173 |
+
<p style="-webkit-font-smoothing:antialiased;Margin:0;Margin-bottom:10px;color:#333;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-smoothing:antialiased;font-weight:400;line-height:25px;margin:0;margin-bottom:30px;padding:0;text-align:left">
|
174 |
+
<?php printf( __( "Hi %s,", "defender-security" ), $userName ) ?>
|
175 |
+
</p>
|
176 |
+
<p style="-webkit-font-smoothing:antialiased;Margin:0;Margin-bottom:10px;color:#333;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-smoothing:antialiased;font-weight:400;line-height:25px;margin:0;margin-bottom:30px;padding:0;text-align:left">
|
177 |
+
<?php printf( __( "You have %d unresolved security tweaks on %s. We recommend you action what you can to prevent any issues, and ignore anything you don't want to fix up.", "defender-security" ), $count, $siteUrl ) ?>
|
178 |
+
</p>
|
179 |
+
</th>
|
180 |
+
<th class="expander"
|
181 |
+
style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
|
182 |
+
</tr>
|
183 |
+
</table>
|
184 |
+
</th>
|
185 |
+
</tr>
|
186 |
+
</tbody>
|
187 |
+
</table>
|
188 |
+
<table class="row"
|
189 |
+
style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
|
190 |
+
<tbody>
|
191 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
192 |
+
<th class="small-12 large-12 columns first last"
|
193 |
+
style="Margin:0 auto;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0 auto;padding:0;padding-bottom:15px;padding-left:15px;padding-right:15px;text-align:left;width:585px">
|
194 |
+
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
|
195 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
196 |
+
<th style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0;text-align:left">
|
197 |
+
<table class="wpmudev-table"
|
198 |
+
style="border-collapse:separate;border-radius:4px;border-spacing:0;margin-bottom:10px;padding:0;text-align:left;vertical-align:top;width:100%">
|
199 |
+
<tbody>
|
200 |
+
<?php echo $issues ?>
|
201 |
+
</tbody>
|
202 |
+
</table>
|
203 |
+
</th>
|
204 |
+
<th class="expander"
|
205 |
+
style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
|
206 |
+
</tr>
|
207 |
+
</table>
|
208 |
+
</th>
|
209 |
+
</tr>
|
210 |
+
</tbody>
|
211 |
+
</table>
|
212 |
+
<table class="row"
|
213 |
+
style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
|
214 |
+
<tbody>
|
215 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
216 |
+
<th class="small-12 large-12 columns first last"
|
217 |
+
style="Margin:0 auto;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0 auto;padding:0;padding-bottom:15px;padding-left:15px;padding-right:15px;text-align:left;width:585px">
|
218 |
+
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
|
219 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
220 |
+
<th style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0;text-align:left">
|
221 |
+
<table class="button btn-center"
|
222 |
+
style="Margin:0 auto 30px!important;border-collapse:collapse;border-spacing:0;margin:0 0 30px 0;padding:0;text-align:left;vertical-align:top;width:auto">
|
223 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
224 |
+
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;hyphens:auto;line-height:25px;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
|
225 |
+
<table style="border-collapse:collapse;border-radius:4px;border-spacing:0;overflow:hidden;padding:0;text-align:left;vertical-align:top;width:100%">
|
226 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
227 |
+
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:#17ABE3;border:none;border-collapse:collapse!important;color:#fff;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;hyphens:auto;line-height:25px;margin:0;padding:0;text-align:center;vertical-align:top;word-wrap:break-word">
|
228 |
+
<a href="<?php echo $viewUrl ?>"
|
229 |
+
style="Margin:0;border:0 solid #17ABE3;border-radius:4px;color:#fff;display:inline-block;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:15px;font-weight:400;line-height:25px;margin:0;min-width:275px;padding:8px 16px 8px 16px;text-align:center;text-decoration:none;text-transform:uppercase">
|
230 |
+
<?php _e( "View All", "defender-security" ) ?>
|
231 |
+
</a></td>
|
232 |
+
</tr>
|
233 |
+
</table>
|
234 |
+
</td>
|
235 |
+
</tr>
|
236 |
+
</table>
|
237 |
+
</th>
|
238 |
+
<th class="expander"
|
239 |
+
style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
|
240 |
+
</tr>
|
241 |
+
</table>
|
242 |
+
</th>
|
243 |
+
</tr>
|
244 |
+
</tbody>
|
245 |
+
</table>
|
246 |
+
<table class="row cheers"
|
247 |
+
style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
|
248 |
+
<tbody>
|
249 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
250 |
+
<th class="small-12 large-12 columns first last"
|
251 |
+
style="Margin:0 auto;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0 auto;padding:0;padding-bottom:15px;padding-left:15px;padding-right:15px;text-align:left;width:585px">
|
252 |
+
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
|
253 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
254 |
+
<th style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0;text-align:left">
|
255 |
+
<p style="-webkit-font-smoothing:antialiased;Margin:0;Margin-bottom:10px;color:#333;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:15px;font-smoothing:antialiased;font-weight:400;line-height:25px;margin:0;margin-bottom:30px;padding:0;text-align:left">
|
256 |
+
<?php _e( "Stay safe,", "defender-security" ) ?>
|
257 |
+
</p>
|
258 |
+
<p style="-webkit-font-smoothing:antialiased;Margin:0;color:#333;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:15px;font-smoothing:antialiased;font-weight:400;line-height:25px;margin:0;padding:0;text-align:left">
|
259 |
+
<?php _e( "Defender,", "defender-security" ) ?>
|
260 |
+
</p>
|
261 |
+
<p style="-webkit-font-smoothing:antialiased;Margin:0;color:#333;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:15px;font-smoothing:antialiased;font-weight:400;line-height:25px;margin:0;margin-bottom:30px;padding:0;text-align:left">
|
262 |
+
<?php _e( "WPMU DEV Security Hero", "defender-security" ) ?></p>
|
263 |
+
<th class="expander"
|
264 |
+
style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
|
265 |
+
</tr>
|
266 |
+
</table>
|
267 |
+
</th>
|
268 |
+
</tr>
|
269 |
+
</tbody>
|
270 |
+
</table>
|
271 |
+
</td>
|
272 |
+
</tr>
|
273 |
+
</tbody>
|
274 |
+
</table>
|
275 |
+
<table align="center" class="container footer float-center"
|
276 |
+
style="Margin:0 auto;background:0 0;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:600px">
|
277 |
+
<tbody>
|
278 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
279 |
+
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;hyphens:auto;line-height:25px;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
|
280 |
+
<table class="row"
|
281 |
+
style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
|
282 |
+
<tbody>
|
283 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
284 |
+
<th class="small-12 large-12 columns first last"
|
285 |
+
style="Margin:0 auto;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0 auto;padding:0;padding-bottom:15px;padding-left:15px;padding-right:15px;text-align:left;width:585px">
|
286 |
+
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
|
287 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
288 |
+
<th style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0;text-align:left">
|
289 |
+
<center data-parsed style="min-width:555px;width:100%"><img
|
290 |
+
class="footer__logo float-center"
|
291 |
+
src="<?php echo wp_defender()->getPluginUrl() ?>assets/email-assets/img/Blue-Copy@2x.png"
|
292 |
+
alt="WPMUDEV Logo"
|
293 |
+
align="center"
|
294 |
+
style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;height:23px;margin:0 auto;max-width:100%;outline:0;padding-bottom:26px;padding-top:40px;text-align:center;text-decoration:none;width:auto">
|
295 |
+
</center>
|
296 |
+
<center data-parsed style="min-width:555px;width:100%"><span
|
297 |
+
class="text-center footer__italic float-center"
|
298 |
+
align="center"
|
299 |
+
style="color:#666;display:block;font-size:14px;font-style:italic;line-height:20px;text-align:center;width:100%">Everything You Need For WordPress.</span>
|
300 |
+
<span class="text-center footer__italic float-center"
|
301 |
+
align="center"
|
302 |
+
style="color:#666;display:block;font-size:14px;font-style:italic;line-height:20px;text-align:center;width:100%">One place, one low price, unlimited sites.</span>
|
303 |
+
</center>
|
304 |
+
<center data-parsed style="min-width:555px;width:100%"><span
|
305 |
+
class="text-center footer__address float-center"
|
306 |
+
align="center"
|
307 |
+
style="color:#AAA;display:block;font-size:10px;line-height:30px;padding-top:30px;text-align:center;width:100%">INCSUB PO BOX 163, ALBERT PARK, VICTORIA.3206 AUSTRALIA</span>
|
308 |
+
</center>
|
309 |
+
<center data-parsed style="min-width:555px;width:100%">
|
310 |
+
<table align="center"
|
311 |
+
class="menu text-center footer__menu float-center"
|
312 |
+
style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;padding-bottom:100px;text-align:center;vertical-align:top;width:auto!important">
|
313 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
314 |
+
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;hyphens:auto;line-height:25px;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
|
315 |
+
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
|
316 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
317 |
+
<th class="menu-item float-center"
|
318 |
+
style="Margin:0 auto;color:#000;float:none;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0 auto;padding:0;padding-right:10px;text-align:center">
|
319 |
+
<a href="#"
|
320 |
+
style="Margin:0;color:#888;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:30px;margin:0;padding:0;text-align:center;text-decoration:underline">Manage
|
321 |
+
your email preferences</a></th>
|
322 |
+
<th class="menu-item float-center"
|
323 |
+
style="Margin:0 auto;color:#000;float:none;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0 auto;padding:0;padding-right:10px;text-align:center">
|
324 |
+
<a href="#"
|
325 |
+
style="Margin:0;color:#888;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:30px;margin:0;padding:0;text-align:center;text-decoration:underline">Unsubscribe</a>
|
326 |
+
</th>
|
327 |
+
</tr>
|
328 |
+
</table>
|
329 |
+
</td>
|
330 |
+
</tr>
|
331 |
+
</table>
|
332 |
+
</center>
|
333 |
+
<table class="spacer"
|
334 |
+
style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
|
335 |
+
<tbody>
|
336 |
+
<tr style="padding:0;text-align:left;vertical-align:top">
|
337 |
+
<td height="96px"
|
338 |
+
style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:96px;font-weight:400;hyphens:auto;line-height:96px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
|
339 |
+
 
|
340 |
+
</td>
|
341 |
+
</tr>
|
342 |
+
</tbody>
|
343 |
+
</table>
|
344 |
+
</th>
|
345 |
+
<th class="expander"
|
346 |
+
style="Margin:0;color:#000;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:25px;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
|
347 |
+
</tr>
|
348 |
+
</table>
|
349 |
+
</th>
|
350 |
+
</tr>
|
351 |
+
</tbody>
|
352 |
+
</table>
|
353 |
+
</td>
|
354 |
+
</tr>
|
355 |
+
</tbody>
|
356 |
+
</table>
|
357 |
+
</center>
|
358 |
+
</td>
|
359 |
+
</tr>
|
360 |
+
</table><!-- prevent Gmail on iOS font size manipulation -->
|
361 |
+
<div style="display:none;white-space:nowrap;font:15px courier;line-height:0">
|
362 |
+
|
363 |
+
|
364 |
+
</div>
|
365 |
+
</body>
|
366 |
+
</html>
|
app/module/hardener/view/layouts/layout.php
CHANGED
@@ -2,11 +2,12 @@
|
|
2 |
$countAll = $controller->getCount( 'issues' );
|
3 |
$resolved = $controller->getCount( 'fixed' );
|
4 |
$ignore = $controller->getCount( 'ignore' );
|
5 |
-
$
|
6 |
$class = '';
|
7 |
-
if ( $countAll
|
8 |
-
$
|
9 |
-
|
|
|
10 |
}
|
11 |
$inlineHeroImage = strlen( wp_defender()->heroImage ) > 0 ? 'background-image: url(\'' . wp_defender()->heroImage . '\')' : null;
|
12 |
?>
|
@@ -17,15 +18,16 @@ $inlineHeroImage = strlen( wp_defender()->heroImage ) > 0 ? 'background-image: u
|
|
17 |
<h1 class="sui-header-title">
|
18 |
<?php _e( "Security Tweaks", "defender-security" ) ?>
|
19 |
</h1>
|
20 |
-
|
21 |
<div class="sui-actions-right">
|
22 |
<div class="sui-actions-right">
|
23 |
-
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender
|
|
|
24 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
25 |
</a>
|
26 |
</div>
|
27 |
</div>
|
28 |
-
|
29 |
</div>
|
30 |
<div class="sui-box sui-summary sui-summary-sm <?php echo \WP_Defender\Behavior\Utils::instance()->getSummaryClass() ?>">
|
31 |
<div class="sui-summary-image-space"
|
@@ -36,11 +38,17 @@ $inlineHeroImage = strlen( wp_defender()->heroImage ) > 0 ? 'background-image: u
|
|
36 |
|
37 |
<div class="sui-summary-details issues">
|
38 |
|
39 |
-
<span class="sui-summary-large
|
40 |
<?php if ( $countAll > 0 ): ?>
|
|
|
|
|
41 |
<i aria-hidden="true" class="sui-icon-info sui-warning"></i>
|
|
|
42 |
<?php else: ?>
|
|
|
|
|
43 |
<i class="sui-icon-check-tick sui-success" aria-hidden="true"></i>
|
|
|
44 |
<?php endif; ?>
|
45 |
<span class="sui-summary-sub"><?php _e( "Security issues", "defender-security" ) ?></span>
|
46 |
</div>
|
@@ -89,10 +97,11 @@ $inlineHeroImage = strlen( wp_defender()->heroImage ) > 0 ? 'background-image: u
|
|
89 |
<?php _e( "Ignored", "defender-security" ) ?></a>
|
90 |
<span class="sui-tag count-ignored <?php echo $ignore ? '' : 'wd-hide' ?>"><?php echo $ignore ?></span>
|
91 |
</li>
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
96 |
</ul>
|
97 |
<div class="sui-sidenav-hide-lg">
|
98 |
<select class="sui-mobile-nav" style="display: none;">
|
@@ -102,8 +111,10 @@ $inlineHeroImage = strlen( wp_defender()->heroImage ) > 0 ? 'background-image: u
|
|
102 |
value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=resolved' ) ?>"><?php _e( "Resolved", "defender-security" ) ?></option>
|
103 |
<option <?php selected( 'ignored', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
|
104 |
value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=ignored' ) ?>"><?php _e( "Ignored", "defender-security" ) ?></option>
|
105 |
-
|
106 |
-
|
|
|
|
|
107 |
</select>
|
108 |
</div>
|
109 |
</div>
|
@@ -112,7 +123,7 @@ $inlineHeroImage = strlen( wp_defender()->heroImage ) > 0 ? 'background-image: u
|
|
112 |
</div>
|
113 |
</div>
|
114 |
</div>
|
115 |
-
<?php if ( wp_defender()->changeFooter
|
116 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
117 |
<?php else: ?>
|
118 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
2 |
$countAll = $controller->getCount( 'issues' );
|
3 |
$resolved = $controller->getCount( 'fixed' );
|
4 |
$ignore = $controller->getCount( 'ignore' );
|
5 |
+
$tooltips = __( "You don't have any outstanding security issues, nice work!", "defender-security" );
|
6 |
$class = '';
|
7 |
+
if ( $countAll == 1 ) {
|
8 |
+
$tooltips = __( "You have one security tweak left to do. We recommend you action it, or ignore it if it's irrelevant.", "defender-security" );
|
9 |
+
} elseif ( $countAll > 1 ) {
|
10 |
+
$tooltips = sprintf( __( "You have %s security tweaks left to do. We recommend you take a look and action fixes, or ignore the issues if they are harmless." ), $countAll );
|
11 |
}
|
12 |
$inlineHeroImage = strlen( wp_defender()->heroImage ) > 0 ? 'background-image: url(\'' . wp_defender()->heroImage . '\')' : null;
|
13 |
?>
|
18 |
<h1 class="sui-header-title">
|
19 |
<?php _e( "Security Tweaks", "defender-security" ) ?>
|
20 |
</h1>
|
21 |
+
<?php if ( wp_defender()->hideDocLinks === false ): ?>
|
22 |
<div class="sui-actions-right">
|
23 |
<div class="sui-actions-right">
|
24 |
+
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/#security-tweaks" target="_blank"
|
25 |
+
class="sui-button sui-button-ghost">
|
26 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
27 |
</a>
|
28 |
</div>
|
29 |
</div>
|
30 |
+
<?php endif; ?>
|
31 |
</div>
|
32 |
<div class="sui-box sui-summary sui-summary-sm <?php echo \WP_Defender\Behavior\Utils::instance()->getSummaryClass() ?>">
|
33 |
<div class="sui-summary-image-space"
|
38 |
|
39 |
<div class="sui-summary-details issues">
|
40 |
|
41 |
+
<span class="sui-summary-large count-issues"><?php echo $countAll ?></span>
|
42 |
<?php if ( $countAll > 0 ): ?>
|
43 |
+
<span class="sui-tooltip sui-tooltip-top-left sui-tooltip-constrained"
|
44 |
+
data-tooltip="<?php echo $tooltips ?>">
|
45 |
<i aria-hidden="true" class="sui-icon-info sui-warning"></i>
|
46 |
+
</span>
|
47 |
<?php else: ?>
|
48 |
+
<span class="sui-tooltip sui-tooltip-top-left sui-tooltip-constrained"
|
49 |
+
data-tooltip="<?php echo $tooltips ?>">
|
50 |
<i class="sui-icon-check-tick sui-success" aria-hidden="true"></i>
|
51 |
+
</span>
|
52 |
<?php endif; ?>
|
53 |
<span class="sui-summary-sub"><?php _e( "Security issues", "defender-security" ) ?></span>
|
54 |
</div>
|
97 |
<?php _e( "Ignored", "defender-security" ) ?></a>
|
98 |
<span class="sui-tag count-ignored <?php echo $ignore ? '' : 'wd-hide' ?>"><?php echo $ignore ?></span>
|
99 |
</li>
|
100 |
+
<li class="sui-vertical-tab <?php echo $controller->isView( 'notification' ) ? 'current' : null ?>">
|
101 |
+
<a href="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=notification' ) ?>">
|
102 |
+
<?php _e( "Notification", "defender-security" ) ?>
|
103 |
+
</a>
|
104 |
+
</li>
|
105 |
</ul>
|
106 |
<div class="sui-sidenav-hide-lg">
|
107 |
<select class="sui-mobile-nav" style="display: none;">
|
111 |
value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=resolved' ) ?>"><?php _e( "Resolved", "defender-security" ) ?></option>
|
112 |
<option <?php selected( 'ignored', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
|
113 |
value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=ignored' ) ?>"><?php _e( "Ignored", "defender-security" ) ?></option>
|
114 |
+
<option <?php selected( 'notification', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
|
115 |
+
value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=notification' ) ?>">
|
116 |
+
<?php _e( "Notification", "defender-security" ) ?>
|
117 |
+
</option>
|
118 |
</select>
|
119 |
</div>
|
120 |
</div>
|
123 |
</div>
|
124 |
</div>
|
125 |
</div>
|
126 |
+
<?php if ( wp_defender()->changeFooter ): ?>
|
127 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
128 |
<?php else: ?>
|
129 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
app/module/hardener/view/rules/db-prefix.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
$checked = $controller->check();
|
3 |
global $wpdb;
|
4 |
-
$prefix = uniqid();
|
5 |
?>
|
6 |
<div id="db_prefix" class="sui-accordion-item <?php echo $controller->getCssClass() ?>">
|
7 |
<div class="sui-accordion-item-header">
|
@@ -20,10 +20,10 @@ $prefix = uniqid();
|
|
20 |
<div class="sui-box">
|
21 |
<div class="sui-box-body">
|
22 |
<strong>
|
23 |
-
|
24 |
</strong>
|
25 |
<p>
|
26 |
-
|
27 |
</p>
|
28 |
<?php if ( $checked ): ?>
|
29 |
<div class="sui-notice sui-notice-success">
|
@@ -50,21 +50,22 @@ $prefix = uniqid();
|
|
50 |
<div class="sui-border-frame">
|
51 |
<div class="sui-form-field ">
|
52 |
<label class="sui-label"><?php _e( "New database prefix", "defender-security" ) ?></label>
|
53 |
-
<input type="text" value="<?php echo $prefix ?>" name="dbprefix" id="dbprefix"
|
|
|
54 |
</div>
|
55 |
</div>
|
56 |
<?php endif; ?>
|
57 |
</div>
|
58 |
<div class="sui-box-footer">
|
59 |
<?php if ( $checked ): ?>
|
60 |
-
<!-- <form method="post" class="hardener-frm rule-process">-->
|
61 |
-
<!-- --><?php //$controller->createNonceField(); ?>
|
62 |
-
<!-- <input type="hidden" name="action" value="processRevert"/>-->
|
63 |
-
<!-- <input type="hidden" name="slug" value="--><?php //echo $controller::$slug ?><!--"/>-->
|
64 |
-
<!-- <button class="sui-button" type="submit">-->
|
65 |
-
<!-- <i class="sui-icon-undo" aria-hidden="true"></i>-->
|
66 |
-
<!-- --><?php //_e( "Revert", "defender-security" ) ?><!--</button>-->
|
67 |
-
<!-- </form>-->
|
68 |
<?php else: ?>
|
69 |
<div class="sui-actions-left">
|
70 |
<?php $controller->showIgnoreForm() ?>
|
1 |
<?php
|
2 |
$checked = $controller->check();
|
3 |
global $wpdb;
|
4 |
+
$prefix = 'wp_' . uniqid();
|
5 |
?>
|
6 |
<div id="db_prefix" class="sui-accordion-item <?php echo $controller->getCssClass() ?>">
|
7 |
<div class="sui-accordion-item-header">
|
20 |
<div class="sui-box">
|
21 |
<div class="sui-box-body">
|
22 |
<strong>
|
23 |
+
<?php _e( "Overview", "defender-security" ) ?>
|
24 |
</strong>
|
25 |
<p>
|
26 |
+
<?php _e( "When you first install WordPress on a new database, the default settings start with wp_ as the prefix to anything that gets stored in the tables. This makes it easier for hackers to perform SQL injection attacks if they find a code vulnerability. ", "defender-security" ) ?>
|
27 |
</p>
|
28 |
<?php if ( $checked ): ?>
|
29 |
<div class="sui-notice sui-notice-success">
|
50 |
<div class="sui-border-frame">
|
51 |
<div class="sui-form-field ">
|
52 |
<label class="sui-label"><?php _e( "New database prefix", "defender-security" ) ?></label>
|
53 |
+
<input type="text" value="<?php echo $prefix ?>" name="dbprefix" id="dbprefix"
|
54 |
+
class="sui-form-control"/>
|
55 |
</div>
|
56 |
</div>
|
57 |
<?php endif; ?>
|
58 |
</div>
|
59 |
<div class="sui-box-footer">
|
60 |
<?php if ( $checked ): ?>
|
61 |
+
<!-- <form method="post" class="hardener-frm rule-process">-->
|
62 |
+
<!-- --><?php //$controller->createNonceField(); ?>
|
63 |
+
<!-- <input type="hidden" name="action" value="processRevert"/>-->
|
64 |
+
<!-- <input type="hidden" name="slug" value="--><?php //echo $controller::$slug ?><!--"/>-->
|
65 |
+
<!-- <button class="sui-button" type="submit">-->
|
66 |
+
<!-- <i class="sui-icon-undo" aria-hidden="true"></i>-->
|
67 |
+
<!-- --><?php //_e( "Revert", "defender-security" ) ?><!--</button>-->
|
68 |
+
<!-- </form>-->
|
69 |
<?php else: ?>
|
70 |
<div class="sui-actions-left">
|
71 |
<?php $controller->showIgnoreForm() ?>
|
app/module/hardener/view/rules/hide-error.php
CHANGED
@@ -57,27 +57,29 @@ $checked = $controller->check();
|
|
57 |
</p>
|
58 |
<?php endif; ?>
|
59 |
</div>
|
60 |
-
<?php if (
|
61 |
-
|
62 |
-
<div class="sui-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
<
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
73 |
</div>
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
</div>
|
80 |
-
|
81 |
<?php endif; ?>
|
82 |
</div>
|
83 |
</div>
|
57 |
</p>
|
58 |
<?php endif; ?>
|
59 |
</div>
|
60 |
+
<?php if ( !$checked ): ?>
|
61 |
+
<?php if ( WP_DEBUG == true && ( ! defined( 'WP_DEBUG_DISPLAY' ) || WP_DEBUG_DISPLAY != false ) ): ?>
|
62 |
+
<div class="sui-box-footer">
|
63 |
+
<div class="sui-actions-left">
|
64 |
+
<?php $controller->showIgnoreForm() ?>
|
65 |
+
</div>
|
66 |
+
<div class="sui-actions-right">
|
67 |
+
<form method="post" class="hardener-frm rule-process hardener-frm-process-xml-rpc">
|
68 |
+
<?php $controller->createNonceField(); ?>
|
69 |
+
<input type="hidden" name="action" value="processHardener"/>
|
70 |
+
<input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
|
71 |
+
<button class="sui-button sui-button-blue" type="submit">
|
72 |
+
<?php _e( "Disable error debugging", "defender-security" ) ?></button>
|
73 |
+
</form>
|
74 |
+
</div>
|
75 |
</div>
|
76 |
+
<?php else: ?>
|
77 |
+
<div class="sui-box-footer">
|
78 |
+
<div class="sui-actions-left">
|
79 |
+
<?php $controller->showIgnoreForm() ?>
|
80 |
+
</div>
|
81 |
</div>
|
82 |
+
<?php endif; ?>
|
83 |
<?php endif; ?>
|
84 |
</div>
|
85 |
</div>
|
app/module/hardener/view/rules/prevent-php-executed.php
CHANGED
@@ -48,7 +48,7 @@ $checked = $controller->check();
|
|
48 |
<?php if ( $checked ): ?>
|
49 |
<div class="sui-notice sui-notice-success">
|
50 |
<p>
|
51 |
-
|
52 |
</p>
|
53 |
</div>
|
54 |
<?php else: ?>
|
@@ -105,11 +105,27 @@ $checked = $controller->check();
|
|
105 |
</div>
|
106 |
<?php endif; ?>
|
107 |
</div>
|
108 |
-
|
109 |
-
<div class="sui-
|
110 |
-
|
|
|
|
|
111 |
</div>
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
</div>
|
114 |
</div>
|
115 |
</div>
|
48 |
<?php if ( $checked ): ?>
|
49 |
<div class="sui-notice sui-notice-success">
|
50 |
<p>
|
51 |
+
<?php _e( "You've automatically disabled PHP execution..", "defender-security" ) ?>
|
52 |
</p>
|
53 |
</div>
|
54 |
<?php else: ?>
|
105 |
</div>
|
106 |
<?php endif; ?>
|
107 |
</div>
|
108 |
+
<?php if ( ! $checked ): ?>
|
109 |
+
<div class="sui-box-footer">
|
110 |
+
<div class="sui-actions-left">
|
111 |
+
<?php $controller->showIgnoreForm() ?>
|
112 |
+
</div>
|
113 |
</div>
|
114 |
+
<?php else: ?>
|
115 |
+
<?php if ( $setting->active_server == 'apache' || $setting->active_server == 'lite_speed' ): ?>
|
116 |
+
<div class="sui-box-footer">
|
117 |
+
<div class="sui-actions-left">
|
118 |
+
<form method="post" class="hardener-frm rule-process">
|
119 |
+
<?php $controller->createNonceField(); ?>
|
120 |
+
<input type="hidden" name="action" value="processRevert"/>
|
121 |
+
<input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
|
122 |
+
<button class="sui-button sui-button-gray"
|
123 |
+
type="submit"><?php _e( "Revert", "defender-security" ) ?></button>
|
124 |
+
</form>
|
125 |
+
</div>
|
126 |
+
</div>
|
127 |
+
<?php endif; ?>
|
128 |
+
<?php endif; ?>
|
129 |
</div>
|
130 |
</div>
|
131 |
</div>
|
app/module/hardener/view/rules/protect-information.php
CHANGED
@@ -95,11 +95,27 @@ if ( $is_nginx ) {
|
|
95 |
</div>
|
96 |
<?php endif; ?>
|
97 |
</div>
|
98 |
-
|
99 |
-
<div class="sui-
|
100 |
-
|
|
|
|
|
101 |
</div>
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
</div>
|
104 |
</div>
|
105 |
</div>
|
95 |
</div>
|
96 |
<?php endif; ?>
|
97 |
</div>
|
98 |
+
<?php if ( ! $checked ): ?>
|
99 |
+
<div class="sui-box-footer">
|
100 |
+
<div class="sui-actions-left">
|
101 |
+
<?php $controller->showIgnoreForm() ?>
|
102 |
+
</div>
|
103 |
</div>
|
104 |
+
<?php else: ?>
|
105 |
+
<?php if ( $setting->active_server == 'apache' || $setting->active_server == 'lite_speed' ): ?>
|
106 |
+
<div class="sui-box-footer">
|
107 |
+
<div class="sui-actions-left">
|
108 |
+
<form method="post" class="hardener-frm rule-process">
|
109 |
+
<?php $controller->createNonceField(); ?>
|
110 |
+
<input type="hidden" name="action" value="processRevert"/>
|
111 |
+
<input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
|
112 |
+
<button class="sui-button sui-button-gray"
|
113 |
+
type="submit"><?php _e( "Revert", "defender-security" ) ?></button>
|
114 |
+
</form>
|
115 |
+
</div>
|
116 |
+
</div>
|
117 |
+
<?php endif; ?>
|
118 |
+
<?php endif; ?>
|
119 |
</div>
|
120 |
</div>
|
121 |
</div>
|
app/module/hardener/view/rules/wp-version.php
CHANGED
@@ -56,17 +56,19 @@ $checked = $controller->check();
|
|
56 |
</p>
|
57 |
<?php endif; ?>
|
58 |
</div>
|
59 |
-
|
60 |
-
<div class="sui-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
<
|
65 |
-
|
66 |
-
|
67 |
-
|
|
|
|
|
68 |
</div>
|
69 |
-
|
70 |
</div>
|
71 |
</div>
|
72 |
</div>
|
56 |
</p>
|
57 |
<?php endif; ?>
|
58 |
</div>
|
59 |
+
<?php if ( ! $checked ): ?>
|
60 |
+
<div class="sui-box-footer">
|
61 |
+
<div class="sui-actions-left">
|
62 |
+
<?php $controller->showIgnoreForm() ?>
|
63 |
+
</div>
|
64 |
+
<div class="sui-actions-right">
|
65 |
+
<a href="<?php echo network_admin_url( 'update-core.php' ) ?>"
|
66 |
+
class="sui-button sui-button-ghost">
|
67 |
+
<?php esc_html_e( "Update WordPress", "defender-security" ) ?>
|
68 |
+
</a>
|
69 |
+
</div>
|
70 |
</div>
|
71 |
+
<?php endif; ?>
|
72 |
</div>
|
73 |
</div>
|
74 |
</div>
|
app/module/ip-lockout/component/login-protection-api.php
CHANGED
@@ -56,7 +56,7 @@ class Login_Protection_Api extends Component {
|
|
56 |
$model->attempt = $attempt;
|
57 |
if ( $model->attempt >= $settings->login_protection_login_attempt || $force == true ) {
|
58 |
$model->status = IP_Model::STATUS_BLOCKED;
|
59 |
-
$model->release_time = strtotime( '+ ' . $settings->login_protection_lockout_duration . '
|
60 |
if ( $blacklist && $force ) {
|
61 |
$model->lockout_message = esc_html__( "You have been locked out by the administrator for attempting to login with a banned username", "defender-security" );
|
62 |
} else {
|
@@ -143,7 +143,7 @@ class Login_Protection_Api extends Component {
|
|
143 |
if ( count( $logs ) >= $settings->detect_404_threshold ) {
|
144 |
//we need to check the extension
|
145 |
$model->status = IP_Model::STATUS_BLOCKED;
|
146 |
-
$model->release_time = strtotime( '+ ' . $settings->detect_404_lockout_duration . '
|
147 |
$model->lockout_message = $settings->detect_404_lockout_message;
|
148 |
$model->lock_time_404 = time();
|
149 |
$model->save();
|
@@ -168,8 +168,8 @@ class Login_Protection_Api extends Component {
|
|
168 |
/**
|
169 |
* @param null $time - unix timestamp
|
170 |
*
|
171 |
-
* @deprecated
|
172 |
* @return int
|
|
|
173 |
*/
|
174 |
public static function get404Lockouts( $time = null ) {
|
175 |
$logs = Log_Model::count( array(
|
@@ -186,8 +186,8 @@ class Login_Protection_Api extends Component {
|
|
186 |
/**
|
187 |
* @param null $time - unix timestamp
|
188 |
*
|
189 |
-
* @deprecated
|
190 |
* @return int
|
|
|
191 |
*/
|
192 |
public static function getLoginLockouts( $time = null ) {
|
193 |
$logs = Log_Model::count( array(
|
@@ -204,8 +204,8 @@ class Login_Protection_Api extends Component {
|
|
204 |
/**
|
205 |
* @param null $time - unix timestamp
|
206 |
*
|
207 |
-
* @deprecated
|
208 |
* @return int
|
|
|
209 |
*/
|
210 |
public static function getAllLockouts( $time = null ) {
|
211 |
$logs = Log_Model::count( array(
|
56 |
$model->attempt = $attempt;
|
57 |
if ( $model->attempt >= $settings->login_protection_login_attempt || $force == true ) {
|
58 |
$model->status = IP_Model::STATUS_BLOCKED;
|
59 |
+
$model->release_time = strtotime( '+ ' . $settings->login_protection_lockout_duration . ' ' . $settings->login_protection_lockout_duration_unit );
|
60 |
if ( $blacklist && $force ) {
|
61 |
$model->lockout_message = esc_html__( "You have been locked out by the administrator for attempting to login with a banned username", "defender-security" );
|
62 |
} else {
|
143 |
if ( count( $logs ) >= $settings->detect_404_threshold ) {
|
144 |
//we need to check the extension
|
145 |
$model->status = IP_Model::STATUS_BLOCKED;
|
146 |
+
$model->release_time = strtotime( '+ ' . $settings->detect_404_lockout_duration . ' ' . $settings->detect_404_lockout_duration_unit );
|
147 |
$model->lockout_message = $settings->detect_404_lockout_message;
|
148 |
$model->lock_time_404 = time();
|
149 |
$model->save();
|
168 |
/**
|
169 |
* @param null $time - unix timestamp
|
170 |
*
|
|
|
171 |
* @return int
|
172 |
+
* @deprecated
|
173 |
*/
|
174 |
public static function get404Lockouts( $time = null ) {
|
175 |
$logs = Log_Model::count( array(
|
186 |
/**
|
187 |
* @param null $time - unix timestamp
|
188 |
*
|
|
|
189 |
* @return int
|
190 |
+
* @deprecated
|
191 |
*/
|
192 |
public static function getLoginLockouts( $time = null ) {
|
193 |
$logs = Log_Model::count( array(
|
204 |
/**
|
205 |
* @param null $time - unix timestamp
|
206 |
*
|
|
|
207 |
* @return int
|
208 |
+
* @deprecated
|
209 |
*/
|
210 |
public static function getAllLockouts( $time = null ) {
|
211 |
$logs = Log_Model::count( array(
|
app/module/ip-lockout/controller/main.php
CHANGED
@@ -310,6 +310,7 @@ class Main extends Controller {
|
|
310 |
* Determine if an ip get lockout or not
|
311 |
*/
|
312 |
public function maybeLockouts() {
|
|
|
313 |
$settings = Settings::instance();
|
314 |
$isTest = HTTP_Helper::retrieve_get( 'def-lockout-demo', false ) == 1;
|
315 |
if ( $isTest ) {
|
@@ -618,7 +619,7 @@ class Main extends Controller {
|
|
618 |
$ext = trim( $ext );
|
619 |
$model = new Log_Model();
|
620 |
$model->ip = $this->getUserIp();
|
621 |
-
$model->user_agent = $_SERVER['HTTP_USER_AGENT'];
|
622 |
$model->log = esc_url( $uri );
|
623 |
$model->date = time();
|
624 |
if ( strlen( $ext ) > 0 && in_array( $ext, $settings->get404Ignorelist() ) ) {
|
@@ -667,7 +668,7 @@ class Main extends Controller {
|
|
667 |
public function recordFailLogin( $username ) {
|
668 |
$model = new Log_Model();
|
669 |
$model->ip = $this->getUserIp();
|
670 |
-
$model->user_agent = $_SERVER['HTTP_USER_AGENT'];
|
671 |
$model->log = sprintf( esc_html__( "Failed login attempt with username %s", "defender-security" ), $username );
|
672 |
$model->date = time();
|
673 |
$model->type = 'auth_fail';
|
310 |
* Determine if an ip get lockout or not
|
311 |
*/
|
312 |
public function maybeLockouts() {
|
313 |
+
do_action('wd_before_lockout');
|
314 |
$settings = Settings::instance();
|
315 |
$isTest = HTTP_Helper::retrieve_get( 'def-lockout-demo', false ) == 1;
|
316 |
if ( $isTest ) {
|
619 |
$ext = trim( $ext );
|
620 |
$model = new Log_Model();
|
621 |
$model->ip = $this->getUserIp();
|
622 |
+
$model->user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : null;
|
623 |
$model->log = esc_url( $uri );
|
624 |
$model->date = time();
|
625 |
if ( strlen( $ext ) > 0 && in_array( $ext, $settings->get404Ignorelist() ) ) {
|
668 |
public function recordFailLogin( $username ) {
|
669 |
$model = new Log_Model();
|
670 |
$model->ip = $this->getUserIp();
|
671 |
+
$model->user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : null;
|
672 |
$model->log = sprintf( esc_html__( "Failed login attempt with username %s", "defender-security" ), $username );
|
673 |
$model->date = time();
|
674 |
$model->type = 'auth_fail';
|
app/module/ip-lockout/view/blacklist/enabled.php
CHANGED
@@ -15,30 +15,33 @@
|
|
15 |
<?php _e( "IP Addresses", "defender-security" ) ?>
|
16 |
</span>
|
17 |
<span class="sui-description">
|
18 |
-
<?php _e( "Add IP addresses you want to permanently ban from, or always allow access to your website.", "defender-security" ) ?>
|
19 |
</span>
|
20 |
</div>
|
21 |
<div class="sui-box-settings-col-2">
|
22 |
<strong><?php _e( "Blacklist", "defender-security" ) ?></strong>
|
23 |
<p class="sui-description">
|
24 |
-
<?php _e( "Any
|
25 |
</p>
|
26 |
<div class="sui-border-frame">
|
27 |
<label class="sui-label"><?php _e( "Banned IPs", "defender-security" ) ?></label>
|
28 |
<textarea class="sui-form-control"
|
29 |
id="ip_blacklist" name="ip_blacklist"
|
30 |
-
placeholder="<?php esc_attr_e( "Add
|
31 |
rows="8"><?php echo $settings->ip_blacklist ?></textarea>
|
32 |
<span class="sui-description">
|
33 |
<?php _e( "Both IPv4 and IPv6 are supported. IP ranges are also accepted in format xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx.", "defender-security" ) ?>
|
34 |
</span>
|
35 |
</div>
|
36 |
<strong><?php _e( "Whitelist", "defender-security" ) ?></strong>
|
|
|
|
|
|
|
37 |
<div class="sui-border-frame">
|
38 |
<label class="sui-label"><?php _e( "Allowed IPs", "defender-security" ) ?></label>
|
39 |
<textarea class="sui-form-control"
|
40 |
id="ip_whitelist" name="ip_whitelist"
|
41 |
-
placeholder="<?php esc_attr_e( "Add
|
42 |
rows="8"><?php echo $settings->ip_whitelist ?></textarea>
|
43 |
<span class="sui-description">
|
44 |
<?php _e( "One IP address per line. Both IPv4 and IPv6 are supported. IP ranges are also accepted in format xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx.", "defender-security" ) ?>
|
@@ -87,7 +90,7 @@
|
|
87 |
<?php else: ?>
|
88 |
<strong><?php _e( "Blacklist", "defender-security" ) ?></strong>
|
89 |
<p class="sui-description no-margin-bottom">
|
90 |
-
<?php _e( "Any countries you select will not
|
91 |
</p>
|
92 |
<div class="sui-border-frame">
|
93 |
<div class="sui-control-with-icon">
|
15 |
<?php _e( "IP Addresses", "defender-security" ) ?>
|
16 |
</span>
|
17 |
<span class="sui-description">
|
18 |
+
<?php _e( "Add IP addresses you want to permanently ban from, or always allow access to your website. ", "defender-security" ) ?>
|
19 |
</span>
|
20 |
</div>
|
21 |
<div class="sui-box-settings-col-2">
|
22 |
<strong><?php _e( "Blacklist", "defender-security" ) ?></strong>
|
23 |
<p class="sui-description">
|
24 |
+
<?php _e( "Any IP addresses you list here will be completely blocked from accessing your website, including admins.", "defender-security" ) ?>
|
25 |
</p>
|
26 |
<div class="sui-border-frame">
|
27 |
<label class="sui-label"><?php _e( "Banned IPs", "defender-security" ) ?></label>
|
28 |
<textarea class="sui-form-control"
|
29 |
id="ip_blacklist" name="ip_blacklist"
|
30 |
+
placeholder="<?php esc_attr_e( "Add IP addresses here, one per line", "defender-security" ) ?>"
|
31 |
rows="8"><?php echo $settings->ip_blacklist ?></textarea>
|
32 |
<span class="sui-description">
|
33 |
<?php _e( "Both IPv4 and IPv6 are supported. IP ranges are also accepted in format xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx.", "defender-security" ) ?>
|
34 |
</span>
|
35 |
</div>
|
36 |
<strong><?php _e( "Whitelist", "defender-security" ) ?></strong>
|
37 |
+
<p class="sui-description">
|
38 |
+
<?php _e( "Any IP addresses you list here will be exempt any existing or new ban rules outlined in login protection, 404 detection or IP ban lists.", "defender-security" ) ?>
|
39 |
+
</p>
|
40 |
<div class="sui-border-frame">
|
41 |
<label class="sui-label"><?php _e( "Allowed IPs", "defender-security" ) ?></label>
|
42 |
<textarea class="sui-form-control"
|
43 |
id="ip_whitelist" name="ip_whitelist"
|
44 |
+
placeholder="<?php esc_attr_e( "Add IP addresses here, one per line", "defender-security" ) ?>"
|
45 |
rows="8"><?php echo $settings->ip_whitelist ?></textarea>
|
46 |
<span class="sui-description">
|
47 |
<?php _e( "One IP address per line. Both IPv4 and IPv6 are supported. IP ranges are also accepted in format xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx.", "defender-security" ) ?>
|
90 |
<?php else: ?>
|
91 |
<strong><?php _e( "Blacklist", "defender-security" ) ?></strong>
|
92 |
<p class="sui-description no-margin-bottom">
|
93 |
+
<?php _e( "Any countries you select will not be able to access any area of your website.", "defender-security" ) ?>
|
94 |
</p>
|
95 |
<div class="sui-border-frame">
|
96 |
<div class="sui-control-with-icon">
|
app/module/ip-lockout/view/detect-404/enabled.php
CHANGED
@@ -61,9 +61,6 @@
|
|
61 |
</div>
|
62 |
<div data-panes>
|
63 |
<div class="sui-tab-boxed <?php echo $settings->detect_404_lockout_ban == 0 ? 'active' : null ?>">
|
64 |
-
<p class="sui-description">
|
65 |
-
<?php _e( "Choose a timeframe to temporarily lock out blocked the IP for.", "defender-security" ) ?>
|
66 |
-
</p>
|
67 |
<div class="sui-row">
|
68 |
<div class="sui-col-md-3">
|
69 |
<input value="<?php echo $settings->detect_404_lockout_duration ?>" size="8"
|
@@ -157,8 +154,8 @@
|
|
157 |
</div>
|
158 |
<div class="sui-box-settings-col-2">
|
159 |
<div class="sui-form-field">
|
|
|
160 |
<label class="sui-toggle">
|
161 |
-
<input type="hidden" name="detect_404_logged" value="0"/>
|
162 |
<input id="detect_404_logged" <?php checked( 1, $settings->detect_404_logged ) ?>
|
163 |
type="checkbox"
|
164 |
name="detect_404_logged" value="1">
|
61 |
</div>
|
62 |
<div data-panes>
|
63 |
<div class="sui-tab-boxed <?php echo $settings->detect_404_lockout_ban == 0 ? 'active' : null ?>">
|
|
|
|
|
|
|
64 |
<div class="sui-row">
|
65 |
<div class="sui-col-md-3">
|
66 |
<input value="<?php echo $settings->detect_404_lockout_duration ?>" size="8"
|
154 |
</div>
|
155 |
<div class="sui-box-settings-col-2">
|
156 |
<div class="sui-form-field">
|
157 |
+
<input type="hidden" name="detect_404_logged" value="0"/>
|
158 |
<label class="sui-toggle">
|
|
|
159 |
<input id="detect_404_logged" <?php checked( 1, $settings->detect_404_logged ) ?>
|
160 |
type="checkbox"
|
161 |
name="detect_404_logged" value="1">
|
app/module/ip-lockout/view/layouts/layout.php
CHANGED
@@ -3,15 +3,16 @@
|
|
3 |
<div class="iplockout">
|
4 |
<div class="sui-header">
|
5 |
<h1 class="sui-header-title"><?php _e( "IP Lockout", "defender-security" ) ?></h1>
|
6 |
-
|
7 |
<div class="sui-actions-right">
|
8 |
<div class="sui-actions-right">
|
9 |
-
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/#ip-lockouts"
|
|
|
10 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
11 |
</a>
|
12 |
</div>
|
13 |
</div>
|
14 |
-
|
15 |
</div>
|
16 |
<div class="sui-box sui-summary <?php echo \WP_Defender\Behavior\Utils::instance()->getSummaryClass() ?>"
|
17 |
id="lockoutSummary">
|
@@ -92,7 +93,7 @@
|
|
92 |
<?php echo $contents ?>
|
93 |
</div>
|
94 |
</div>
|
95 |
-
<?php if ( wp_defender()->changeFooter
|
96 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
97 |
<?php else: ?>
|
98 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
3 |
<div class="iplockout">
|
4 |
<div class="sui-header">
|
5 |
<h1 class="sui-header-title"><?php _e( "IP Lockout", "defender-security" ) ?></h1>
|
6 |
+
<?php if ( wp_defender()->hideDocLinks === false ): ?>
|
7 |
<div class="sui-actions-right">
|
8 |
<div class="sui-actions-right">
|
9 |
+
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/#ip-lockouts"
|
10 |
+
target="_blank" class="sui-button sui-button-ghost">
|
11 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
12 |
</a>
|
13 |
</div>
|
14 |
</div>
|
15 |
+
<?php endif; ?>
|
16 |
</div>
|
17 |
<div class="sui-box sui-summary <?php echo \WP_Defender\Behavior\Utils::instance()->getSummaryClass() ?>"
|
18 |
id="lockoutSummary">
|
93 |
<?php echo $contents ?>
|
94 |
</div>
|
95 |
</div>
|
96 |
+
<?php if ( wp_defender()->changeFooter ): ?>
|
97 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
98 |
<?php else: ?>
|
99 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
app/module/ip-lockout/view/locked.php
CHANGED
@@ -67,8 +67,10 @@
|
|
67 |
<body>
|
68 |
<div class="wp-defender">
|
69 |
<div class="container">
|
70 |
-
|
71 |
-
|
|
|
|
|
72 |
<p><?php echo $message ?></p>
|
73 |
</div>
|
74 |
<div class="powered"><?php esc_html_e( "Powered by", "defender-security" ) ?>
|
67 |
<body>
|
68 |
<div class="wp-defender">
|
69 |
<div class="container">
|
70 |
+
<?php if ( strlen( wp_defender()->heroImage ) == 0 ): ?>
|
71 |
+
<div class="image">
|
72 |
+
</div>
|
73 |
+
<?php endif; ?>
|
74 |
<p><?php echo $message ?></p>
|
75 |
</div>
|
76 |
<div class="powered"><?php esc_html_e( "Powered by", "defender-security" ) ?>
|
app/module/ip-lockout/view/login-lockouts/enabled.php
CHANGED
@@ -67,9 +67,6 @@
|
|
67 |
</div>
|
68 |
<div data-panes>
|
69 |
<div class="sui-tab-boxed <?php echo $settings->login_protection_lockout_ban == 0 ? 'active' : null ?>">
|
70 |
-
<p class="sui-description">
|
71 |
-
<?php _e( "Choose a timeframe to temporarily lock out blocked the IP for.", "defender-security" ) ?>
|
72 |
-
</p>
|
73 |
<div class="sui-row">
|
74 |
<div class="sui-col-md-3">
|
75 |
<input value="<?php echo $settings->login_protection_lockout_duration ?>"
|
67 |
</div>
|
68 |
<div data-panes>
|
69 |
<div class="sui-tab-boxed <?php echo $settings->login_protection_lockout_ban == 0 ? 'active' : null ?>">
|
|
|
|
|
|
|
70 |
<div class="sui-row">
|
71 |
<div class="sui-col-md-3">
|
72 |
<input value="<?php echo $settings->login_protection_lockout_duration ?>"
|
app/module/ip-lockout/view/notification/enabled.php
CHANGED
@@ -16,8 +16,8 @@
|
|
16 |
|
17 |
<div class="sui-box-settings-col-2">
|
18 |
<div class="sui-form-field">
|
|
|
19 |
<label class="sui-toggle">
|
20 |
-
<input type="hidden" name="login_lockout_notification" value="0"/>
|
21 |
<input role="presentation" type="checkbox" name="login_lockout_notification"
|
22 |
class="toggle-checkbox"
|
23 |
id="login_lockout_notification" value="1"
|
@@ -32,8 +32,8 @@
|
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="sui-form-field">
|
|
|
35 |
<label class="sui-toggle">
|
36 |
-
<input type="hidden" name="ip_lockout_notification" value="0"/>
|
37 |
<input role="presentation" type="checkbox" name="ip_lockout_notification"
|
38 |
class="toggle-checkbox"
|
39 |
id="ip_lockout_notification" value="1"
|
@@ -74,15 +74,15 @@
|
|
74 |
</div>
|
75 |
|
76 |
<div class="sui-box-settings-col-2">
|
|
|
77 |
<label class="sui-toggle">
|
78 |
-
<input type="hidden" name="cooldown_enabled" value="0"/>
|
79 |
<input role="presentation" type="checkbox" name="cooldown_enabled"
|
80 |
class="toggle-checkbox"
|
81 |
id="cooldown_enabled" value="1"
|
82 |
<?php checked( true, $settings->cooldown_enabled ) ?>/>
|
83 |
<span class="sui-toggle-slider"></span>
|
84 |
</label>
|
85 |
-
<label for="
|
86 |
<?php esc_html_e( "Limit email notifications for repeat lockouts", "defender-security" ) ?>
|
87 |
</label>
|
88 |
<div class="sui-border-frame sui-toggle-content">
|
16 |
|
17 |
<div class="sui-box-settings-col-2">
|
18 |
<div class="sui-form-field">
|
19 |
+
<input type="hidden" name="login_lockout_notification" value="0"/>
|
20 |
<label class="sui-toggle">
|
|
|
21 |
<input role="presentation" type="checkbox" name="login_lockout_notification"
|
22 |
class="toggle-checkbox"
|
23 |
id="login_lockout_notification" value="1"
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="sui-form-field">
|
35 |
+
<input type="hidden" name="ip_lockout_notification" value="0"/>
|
36 |
<label class="sui-toggle">
|
|
|
37 |
<input role="presentation" type="checkbox" name="ip_lockout_notification"
|
38 |
class="toggle-checkbox"
|
39 |
id="ip_lockout_notification" value="1"
|
74 |
</div>
|
75 |
|
76 |
<div class="sui-box-settings-col-2">
|
77 |
+
<input type="hidden" name="cooldown_enabled" value="0"/>
|
78 |
<label class="sui-toggle">
|
|
|
79 |
<input role="presentation" type="checkbox" name="cooldown_enabled"
|
80 |
class="toggle-checkbox"
|
81 |
id="cooldown_enabled" value="1"
|
82 |
<?php checked( true, $settings->cooldown_enabled ) ?>/>
|
83 |
<span class="sui-toggle-slider"></span>
|
84 |
</label>
|
85 |
+
<label for="cooldown_enabled" class="sui-toggle-label">
|
86 |
<?php esc_html_e( "Limit email notifications for repeat lockouts", "defender-security" ) ?>
|
87 |
</label>
|
88 |
<div class="sui-border-frame sui-toggle-content">
|
app/module/ip-lockout/view/notification/report.php
CHANGED
@@ -18,15 +18,15 @@
|
|
18 |
|
19 |
<div class="sui-box-settings-col-2">
|
20 |
<div class="sui-form-field">
|
|
|
21 |
<label class="sui-toggle">
|
22 |
-
<input type="hidden" name="report" value="0"/>
|
23 |
<input role="presentation" type="checkbox" name="report"
|
24 |
class="toggle-checkbox"
|
25 |
id="report" value="1"
|
26 |
<?php checked( true, $settings->report ) ?>/>
|
27 |
<span class="sui-toggle-slider"></span>
|
28 |
</label>
|
29 |
-
<label for="
|
30 |
<?php esc_html_e( "Send regular email report", "defender-security" ) ?>
|
31 |
</label>
|
32 |
<div class="sui-border-frame sui-toggle-content">
|
18 |
|
19 |
<div class="sui-box-settings-col-2">
|
20 |
<div class="sui-form-field">
|
21 |
+
<input type="hidden" name="report" value="0"/>
|
22 |
<label class="sui-toggle">
|
|
|
23 |
<input role="presentation" type="checkbox" name="report"
|
24 |
class="toggle-checkbox"
|
25 |
id="report" value="1"
|
26 |
<?php checked( true, $settings->report ) ?>/>
|
27 |
<span class="sui-toggle-slider"></span>
|
28 |
</label>
|
29 |
+
<label for="report" class="sui-toggle-label">
|
30 |
<?php esc_html_e( "Send regular email report", "defender-security" ) ?>
|
31 |
</label>
|
32 |
<div class="sui-border-frame sui-toggle-content">
|
app/module/scan/behavior/scan.php
DELETED
@@ -1,266 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Author: Hoang Ngo
|
4 |
-
*/
|
5 |
-
|
6 |
-
namespace WP_Defender\Module\Scan\Behavior;
|
7 |
-
|
8 |
-
use Hammer\Base\Behavior;
|
9 |
-
use WP_Defender\Behavior\Utils;
|
10 |
-
use WP_Defender\Module\Scan\Component\Scan_Api;
|
11 |
-
use WP_Defender\Module\Scan\Model\Result_Item;
|
12 |
-
use WP_Defender\Module\Scan\Model\Settings;
|
13 |
-
|
14 |
-
class Scan extends Behavior {
|
15 |
-
private $lastScan;
|
16 |
-
private $activeScan;
|
17 |
-
private $settled = false;
|
18 |
-
private $countAll;
|
19 |
-
|
20 |
-
private function pullStatus() {
|
21 |
-
if ( $this->settled == false ) {
|
22 |
-
$this->activeScan = Scan_Api::getActiveScan();
|
23 |
-
$this->lastScan = Scan_Api::getLastScan();
|
24 |
-
$this->countAll = is_object( $this->lastScan ) ? $this->lastScan->countAll( Result_Item::STATUS_ISSUE ) : 0;
|
25 |
-
$this->settled = true;
|
26 |
-
}
|
27 |
-
}
|
28 |
-
|
29 |
-
public function renderScanWidget() {
|
30 |
-
$this->pullStatus();
|
31 |
-
|
32 |
-
?>
|
33 |
-
<div class="sui-box">
|
34 |
-
<div class="sui-box-header">
|
35 |
-
<h3 class="sui-box-title">
|
36 |
-
<i class="sui-icon-layers" aria-hidden="true"></i>
|
37 |
-
<?php _e("File Scanning") ?>
|
38 |
-
</h3>
|
39 |
-
<?php if($this->countAll > 0):?>
|
40 |
-
<div class="sui-actions-left">
|
41 |
-
<span class="sui-tag sui-tag-error">
|
42 |
-
<?php echo $this->countAll; ?>
|
43 |
-
</span>
|
44 |
-
</div>
|
45 |
-
<?php endif; ?>
|
46 |
-
</div>
|
47 |
-
<?php
|
48 |
-
$activeScan = $this->activeScan;
|
49 |
-
$lastScan = $this->lastScan;
|
50 |
-
if ( ! is_object( $activeScan ) && ! is_object( $lastScan ) ) {
|
51 |
-
echo $this->_renderNewScan();
|
52 |
-
} elseif ( is_object( $activeScan ) && $activeScan->status != \WP_Defender\Module\Scan\Model\Scan::STATUS_ERROR ) {
|
53 |
-
echo $this->_renderScanning( $activeScan );
|
54 |
-
} elseif ( is_object( $activeScan ) && $activeScan->status == \WP_Defender\Module\Scan\Model\Scan::STATUS_ERROR ) {
|
55 |
-
|
56 |
-
} else {
|
57 |
-
echo $this->_renderResult( $lastScan );
|
58 |
-
}
|
59 |
-
?>
|
60 |
-
<!-- <div class="sui-box-body">-->
|
61 |
-
<!-- --><?php
|
62 |
-
// $activeScan = $this->activeScan;
|
63 |
-
// $lastScan = $this->lastScan;
|
64 |
-
// if ( ! is_object( $activeScan ) && ! is_object( $lastScan ) ) {
|
65 |
-
// echo $this->_renderNewScan();
|
66 |
-
// } elseif ( is_object( $activeScan ) && $activeScan->status != \WP_Defender\Module\Scan\Model\Scan::STATUS_ERROR ) {
|
67 |
-
// echo $this->_renderScanning( $activeScan );
|
68 |
-
// } elseif ( is_object( $activeScan ) && $activeScan->status == \WP_Defender\Module\Scan\Model\Scan::STATUS_ERROR ) {
|
69 |
-
//
|
70 |
-
// } else {
|
71 |
-
// echo $this->_renderResult( $lastScan );
|
72 |
-
// }
|
73 |
-
// ?>
|
74 |
-
<!-- </div>-->
|
75 |
-
</div>
|
76 |
-
<?php
|
77 |
-
}
|
78 |
-
|
79 |
-
public function renderScanStatusText() {
|
80 |
-
$this->pullStatus();
|
81 |
-
$activeScan = $this->activeScan;
|
82 |
-
$lastScan = $this->lastScan;
|
83 |
-
if ( ! is_object( $activeScan ) && ! is_object( $lastScan ) ) {
|
84 |
-
?>
|
85 |
-
<form id="start-a-scan" method="post" class="scan-frm">
|
86 |
-
<?php
|
87 |
-
wp_nonce_field( 'startAScan' );
|
88 |
-
?>
|
89 |
-
<input type="hidden" name="action" value="startAScan"/>
|
90 |
-
<button type="submit"
|
91 |
-
class="button button-small"><?php _e( "RUN SCAN", "defender-security" ) ?></button>
|
92 |
-
</form>
|
93 |
-
<?php
|
94 |
-
} elseif ( is_object( $activeScan ) && $activeScan->status != \WP_Defender\Module\Scan\Model\Scan::STATUS_ERROR ) {
|
95 |
-
?>
|
96 |
-
<img src="<?php echo wp_defender()->getPluginUrl() ?>assets/img/loading.gif" width="18"
|
97 |
-
height="18"/> <?php _e( "Scanning…", "defender-security" ) ?>
|
98 |
-
<?php
|
99 |
-
} elseif ( is_object( $activeScan ) && $activeScan->status == \WP_Defender\Module\Scan\Model\Scan::STATUS_ERROR ) {
|
100 |
-
echo $this->activeScan->statusText;
|
101 |
-
} else {
|
102 |
-
?>
|
103 |
-
<?php
|
104 |
-
if ( $this->countAll == 0 ): ?>
|
105 |
-
<span class="def-tag tag-success">
|
106 |
-
<?php else:
|
107 |
-
?>
|
108 |
-
<span class="def-tag tag-error">
|
109 |
-
<?php endif;
|
110 |
-
echo $this->countAll;
|
111 |
-
?>
|
112 |
-
</span>
|
113 |
-
<?php
|
114 |
-
}
|
115 |
-
}
|
116 |
-
|
117 |
-
private function _renderResult(\WP_Defender\Module\Scan\Model\Scan $model){
|
118 |
-
ob_start();
|
119 |
-
?>
|
120 |
-
<div class="sui-box-body no-padding-bottom">
|
121 |
-
<p>
|
122 |
-
<?php _e( "Scan your website for file changes, vulnerabilities and injected code and get and get notified about anything suspicious.", "defender-security" ) ?>
|
123 |
-
</p>
|
124 |
-
<?php
|
125 |
-
if ( $this->countAll == 0 ) {
|
126 |
-
?>
|
127 |
-
<div class="sui-notice sui-notice-success">
|
128 |
-
<p><?php _e( "Your code is clean, the skies are clear.", "defender-security" ) ?></p>
|
129 |
-
</div>
|
130 |
-
<?php
|
131 |
-
} else {
|
132 |
-
?>
|
133 |
-
<div class="sui-field-list sui-flushed no-border">
|
134 |
-
<div class="sui-field-list-body">
|
135 |
-
<div class="sui-field-list-item">
|
136 |
-
<label class="sui-field-list-item-label">
|
137 |
-
<?php _e( "WordPress Core", "defender-security" ) ?>
|
138 |
-
</label>
|
139 |
-
<?php echo $model->getCount( 'core' ) == 0 ? ' <i class="sui-icon-check" aria-hidden="true"></i>' : '<span class="sui-tag sui-tag-error">' . $model->getCount( 'core' ) . '</span>' ?>
|
140 |
-
</div>
|
141 |
-
<div class="sui-field-list-item">
|
142 |
-
<label class="sui-field-list-item-label">
|
143 |
-
<?php _e( "Plugins & Themes", "defender-security" ) ?>
|
144 |
-
</label>
|
145 |
-
<?php if ( Utils::instance()->getAPIKey() ): ?>
|
146 |
-
<?php echo $model->getCount( 'vuln' ) == 0 ? ' <i class="sui-icon-check" aria-hidden="true"></i>' : '<span class="sui-tag sui-tag-error">' . $model->getCount( 'vuln' ) . '</span>' ?>
|
147 |
-
<?php else: ?>
|
148 |
-
<a href="<?php echo Utils::instance()->campaignURL('defender_dash_filescan_pro_tag') ?>" target="_blank" class="sui-button sui-button-purple"
|
149 |
-
data-tooltip="<?php esc_attr_e( "Try Defender Pro free today", "defender-security" ) ?>">
|
150 |
-
<?php _e( "Pro Feature", "defender-security" ) ?>
|
151 |
-
</a>
|
152 |
-
<?php endif; ?>
|
153 |
-
</div>
|
154 |
-
<div class="sui-field-list-item">
|
155 |
-
<label class="sui-field-list-item-label">
|
156 |
-
<?php _e( "Suspicious Code", "defender-security" ) ?>
|
157 |
-
</label>
|
158 |
-
<?php if ( Utils::instance()->getAPIKey() ): ?>
|
159 |
-
<?php echo $model->getCount( 'content' ) == 0 ? ' <i class="sui-icon-check" aria-hidden="true"></i>' : '<span class="sui-tag sui-tag-error">' . $model->getCount( 'content' ) . '</span>' ?>
|
160 |
-
<?php else: ?>
|
161 |
-
<a href="<?php echo Utils::instance()->campaignURL('defender_dash_filescan_pro_tag') ?>" target="_blank" class="sui-button sui-button-purple"
|
162 |
-
tooltip="<?php esc_attr_e( "Try Defender Pro free today", "defender-security" ) ?>">
|
163 |
-
<?php _e( "Pro Feature", "defender-security" ) ?>
|
164 |
-
</a>
|
165 |
-
<?php endif; ?>
|
166 |
-
</div>
|
167 |
-
</div>
|
168 |
-
</div>
|
169 |
-
<?php
|
170 |
-
}
|
171 |
-
?>
|
172 |
-
</div>
|
173 |
-
|
174 |
-
<div class="sui-box-footer">
|
175 |
-
<div class="sui-actions-left">
|
176 |
-
<a href="<?php echo network_admin_url( 'admin.php?page=wdf-scan' ) ?>"
|
177 |
-
class="sui-button sui-button-ghost">
|
178 |
-
<?php _e( "View Report", "defender-security" ) ?>
|
179 |
-
</a>
|
180 |
-
</div>
|
181 |
-
<?php if(!wp_defender()->isFree): ?>
|
182 |
-
<div class="sui-actions-right">
|
183 |
-
<?php
|
184 |
-
if ( !empty( Settings::instance()->notification ) ) {
|
185 |
-
switch ( Settings::instance()->frequency ) {
|
186 |
-
case '1':
|
187 |
-
_e( "Automatic scans are running daily", "defender-security" );
|
188 |
-
break;
|
189 |
-
case '7':
|
190 |
-
_e( "Automatic scans are running weekly", "defender-security" );
|
191 |
-
break;
|
192 |
-
case '30':
|
193 |
-
_e( "Automatic scans are running monthly", "defender-security" );
|
194 |
-
break;
|
195 |
-
}
|
196 |
-
}
|
197 |
-
?>
|
198 |
-
</div>
|
199 |
-
<?php endif; ?>
|
200 |
-
</div>
|
201 |
-
<?php
|
202 |
-
return ob_get_clean();
|
203 |
-
}
|
204 |
-
|
205 |
-
private function _renderNewScan() {
|
206 |
-
ob_start();
|
207 |
-
?>
|
208 |
-
<div class="sui-box-body">
|
209 |
-
<p>
|
210 |
-
<?php _e( "Scan your website for file changes, vulnerabilities and injected code and get
|
211 |
-
notified about anything suspicious.", "defender-security" ) ?>
|
212 |
-
</p>
|
213 |
-
<form id="start-a-scan" method="post" class="scan-frm">
|
214 |
-
<?php
|
215 |
-
wp_nonce_field( 'startAScan' );
|
216 |
-
?>
|
217 |
-
<input type="hidden" name="action" value="startAScan"/>
|
218 |
-
<button type="submit" class="sui-button sui-button-blue"><?php _e( "Run Scan", "defender-security" ) ?></button>
|
219 |
-
</form>
|
220 |
-
</div>
|
221 |
-
<?php
|
222 |
-
return ob_get_clean();
|
223 |
-
}
|
224 |
-
|
225 |
-
private function _renderScanning( $model ) {
|
226 |
-
ob_start();
|
227 |
-
$percent = Scan_Api::getScanProgress();
|
228 |
-
?>
|
229 |
-
<div class="wdf-scanning"></div>
|
230 |
-
<div class="sui-box-body">
|
231 |
-
<p>
|
232 |
-
<?php _e( "Defender is scanning your files for malicious code. This will take a few minutes depending on the size of your website.", "defender-security" ) ?>
|
233 |
-
</p>
|
234 |
-
<div class="sui-progress-block sui-progress-can-close">
|
235 |
-
<div class="sui-progress">
|
236 |
-
<div class="sui-progress-text sui-icon-loader sui-loading">
|
237 |
-
<span><?php echo $percent ?>%</span>
|
238 |
-
</div>
|
239 |
-
<div class="sui-progress-bar">
|
240 |
-
<span style="width: <?php echo $percent ?>%"></span>
|
241 |
-
</div>
|
242 |
-
<form method="post" class="scan-frm">
|
243 |
-
<input type="hidden" name="action" value="cancelScan"/>
|
244 |
-
<?php wp_nonce_field( 'cancelScan', '_wpnonce', true ) ?>
|
245 |
-
<button class="sui-button-icon" type="submit">
|
246 |
-
<i class="sui-icon-close"></i>
|
247 |
-
</button>
|
248 |
-
</form>
|
249 |
-
</div>
|
250 |
-
</div>
|
251 |
-
<div class="sui-progress-state">
|
252 |
-
<span class="sui-progress-state-text">
|
253 |
-
<?php echo $model->statusText ?>
|
254 |
-
</span>
|
255 |
-
</div>
|
256 |
-
</div>
|
257 |
-
<form method="post" id="process-scan" class="scan-frm">
|
258 |
-
<input type="hidden" name="action" value="processScan"/>
|
259 |
-
<?php
|
260 |
-
wp_nonce_field( 'processScan' );
|
261 |
-
?>
|
262 |
-
</form>
|
263 |
-
<?php
|
264 |
-
return ob_get_clean();
|
265 |
-
}
|
266 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/module/scan/component/result-table.php
CHANGED
@@ -103,25 +103,29 @@ class Result_Table extends \WP_List_Table {
|
|
103 |
function prepare_items() {
|
104 |
$model = Scan_Api::getLastScan();
|
105 |
$itemsPerPage = 40;
|
106 |
-
$totalItems = $model->countAll( $this->type );
|
107 |
|
108 |
-
$this->set_pagination_args( array(
|
109 |
-
'total_items' => $totalItems,
|
110 |
-
'total_pages' => ceil( $totalItems / $itemsPerPage ),
|
111 |
-
'per_page' => $itemsPerPage
|
112 |
-
) );
|
113 |
$offset = ( $this->get_pagenum() - 1 ) * $itemsPerPage;
|
114 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
115 |
$issueType = HTTP_Helper::retrieve_get( 'type', null );
|
116 |
if ( ! in_array( $issueType, array(
|
117 |
'core',
|
118 |
'vuln',
|
119 |
-
'
|
120 |
) ) ) {
|
121 |
$issueType = null;
|
122 |
}
|
123 |
|
124 |
$this->items = $model->getItems( $offset . ',' . $itemsPerPage, $this->type, $issueType );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
}
|
126 |
|
127 |
/**
|
@@ -203,8 +207,8 @@ class Result_Table extends \WP_List_Table {
|
|
203 |
<input type="hidden" name="action" value="scanBulkAction"/>
|
204 |
<?php wp_nonce_field( 'scanBulkAction' ) ?>
|
205 |
<div class="bulk-action-bar">
|
206 |
-
<label class="sui-checkbox
|
207 |
-
<input type="checkbox"
|
208 |
<span aria-hidden="true"></span>
|
209 |
</label>
|
210 |
<select name="bulk" class="sui-select-sm bulk-action">
|
@@ -239,10 +243,11 @@ class Result_Table extends \WP_List_Table {
|
|
239 |
/**
|
240 |
* Generates content for a single row of the table
|
241 |
*
|
|
|
|
|
242 |
* @since 3.1.0
|
243 |
* @access public
|
244 |
*
|
245 |
-
* @param object $item The current item
|
246 |
*/
|
247 |
public function single_row( $item ) {
|
248 |
echo '<tr id="mid-' . $item->id . '" class="sui-accordion-item sui-error">';
|
@@ -320,9 +325,10 @@ class Result_Table extends \WP_List_Table {
|
|
320 |
/**
|
321 |
* Generates the columns for a single row of the table
|
322 |
*
|
|
|
|
|
323 |
* @since 3.1.0
|
324 |
*
|
325 |
-
* @param object $item The current item
|
326 |
*/
|
327 |
protected function single_row_columns( $item ) {
|
328 |
list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
|
103 |
function prepare_items() {
|
104 |
$model = Scan_Api::getLastScan();
|
105 |
$itemsPerPage = 40;
|
|
|
106 |
|
|
|
|
|
|
|
|
|
|
|
107 |
$offset = ( $this->get_pagenum() - 1 ) * $itemsPerPage;
|
108 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
109 |
$issueType = HTTP_Helper::retrieve_get( 'type', null );
|
110 |
if ( ! in_array( $issueType, array(
|
111 |
'core',
|
112 |
'vuln',
|
113 |
+
'content'
|
114 |
) ) ) {
|
115 |
$issueType = null;
|
116 |
}
|
117 |
|
118 |
$this->items = $model->getItems( $offset . ',' . $itemsPerPage, $this->type, $issueType );
|
119 |
+
$totalItems = Result_Item::count( [
|
120 |
+
'type' => $issueType,
|
121 |
+
'status' => $this->type
|
122 |
+
] );
|
123 |
+
|
124 |
+
$this->set_pagination_args( array(
|
125 |
+
'total_items' => $totalItems,
|
126 |
+
'total_pages' => ceil( $totalItems / $itemsPerPage ),
|
127 |
+
'per_page' => $itemsPerPage
|
128 |
+
) );
|
129 |
}
|
130 |
|
131 |
/**
|
207 |
<input type="hidden" name="action" value="scanBulkAction"/>
|
208 |
<?php wp_nonce_field( 'scanBulkAction' ) ?>
|
209 |
<div class="bulk-action-bar">
|
210 |
+
<label class="sui-checkbox">
|
211 |
+
<input type="checkbox" class="apply-all"/>
|
212 |
<span aria-hidden="true"></span>
|
213 |
</label>
|
214 |
<select name="bulk" class="sui-select-sm bulk-action">
|
243 |
/**
|
244 |
* Generates content for a single row of the table
|
245 |
*
|
246 |
+
* @param object $item The current item
|
247 |
+
*
|
248 |
* @since 3.1.0
|
249 |
* @access public
|
250 |
*
|
|
|
251 |
*/
|
252 |
public function single_row( $item ) {
|
253 |
echo '<tr id="mid-' . $item->id . '" class="sui-accordion-item sui-error">';
|
325 |
/**
|
326 |
* Generates the columns for a single row of the table
|
327 |
*
|
328 |
+
* @param object $item The current item
|
329 |
+
*
|
330 |
* @since 3.1.0
|
331 |
*
|
|
|
332 |
*/
|
333 |
protected function single_row_columns( $item ) {
|
334 |
list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
|
app/module/scan/component/scan-api.php
CHANGED
@@ -25,6 +25,8 @@ class Scan_Api extends Component {
|
|
25 |
|
26 |
private static $ignoreList = false;
|
27 |
|
|
|
|
|
28 |
/**
|
29 |
* @return Scan|\WP_Error
|
30 |
*/
|
@@ -139,7 +141,7 @@ class Scan_Api extends Component {
|
|
139 |
$files = File_Helper::findFiles( WP_CONTENT_DIR, true, false, array(), array(
|
140 |
'ext' => array( 'php' )
|
141 |
), true, $settings->max_filesize, true );
|
142 |
-
// $files
|
143 |
// 'ext' => array( 'php' )
|
144 |
// ), true, $settings->max_filesize );
|
145 |
//include wp-config.php here
|
25 |
|
26 |
private static $ignoreList = false;
|
27 |
|
28 |
+
public static $scanResults = array();
|
29 |
+
|
30 |
/**
|
31 |
* @return Scan|\WP_Error
|
32 |
*/
|
141 |
$files = File_Helper::findFiles( WP_CONTENT_DIR, true, false, array(), array(
|
142 |
'ext' => array( 'php' )
|
143 |
), true, $settings->max_filesize, true );
|
144 |
+
// $files = File_Helper::findFiles( ABSPATH . 'wp-content/randomly/a', true, false, array(), array(
|
145 |
// 'ext' => array( 'php' )
|
146 |
// ), true, $settings->max_filesize );
|
147 |
//include wp-config.php here
|
app/module/scan/component/token-utils.php
CHANGED
@@ -13,6 +13,7 @@ class Token_Utils extends Component {
|
|
13 |
* @var array
|
14 |
*/
|
15 |
static $tokens = array();
|
|
|
16 |
|
17 |
/**
|
18 |
* @param $token
|
@@ -31,6 +32,45 @@ class Token_Utils extends Component {
|
|
31 |
return false;
|
32 |
}
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
/**
|
35 |
* @param $token
|
36 |
* @param $from
|
@@ -47,7 +87,7 @@ class Token_Utils extends Component {
|
|
47 |
$token = array( $token );
|
48 |
}
|
49 |
|
50 |
-
for ( $i = $from; $i
|
51 |
if ( ! isset( self::$tokens[ $i ] ) ) {
|
52 |
return false;
|
53 |
}
|
@@ -80,6 +120,21 @@ class Token_Utils extends Component {
|
|
80 |
return $str;
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
/**
|
84 |
* @param $start
|
85 |
* @param $end
|
@@ -89,18 +144,46 @@ class Token_Utils extends Component {
|
|
89 |
public static function findParams( $start, $end ) {
|
90 |
$params = array();
|
91 |
for ( $i = $start; $i < $end; $i ++ ) {
|
92 |
-
$params[] = self::$tokens[ $i ];
|
93 |
}
|
94 |
|
95 |
return $params;
|
96 |
}
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
/**
|
99 |
* @param $token
|
100 |
*
|
101 |
* @return bool
|
102 |
*/
|
103 |
-
public static function isUserInput(
|
|
|
|
|
104 |
if ( $token['code'] == T_VARIABLE
|
105 |
&& preg_match( '/\$\{?_(GET|POST|REQUEST|COOKIE|SERVER|FILES|ENV)/', $token['content'] ) ) {
|
106 |
return true;
|
@@ -109,6 +192,166 @@ class Token_Utils extends Component {
|
|
109 |
return false;
|
110 |
}
|
111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
//Borrow from https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/Utils.php
|
113 |
//Point to RIPs and SO https://stackoverflow.com/questions/3115559/exploitable-php-functions
|
114 |
public static function getCallbackFunctions() {
|
@@ -116,10 +359,10 @@ class Token_Utils extends Component {
|
|
116 |
'ob_start',
|
117 |
'array_diff_uassoc',
|
118 |
'array_diff_ukey',
|
119 |
-
'array_filter',
|
120 |
'array_intersect_uassoc',
|
121 |
'array_intersect_ukey',
|
122 |
-
'array_map',
|
123 |
'array_reduce',
|
124 |
'array_udiff_assoc',
|
125 |
'array_udiff_uassoc',
|
@@ -130,9 +373,6 @@ class Token_Utils extends Component {
|
|
130 |
'array_walk_recursive',
|
131 |
'array_walk',
|
132 |
'assert_options',
|
133 |
-
'uasort',
|
134 |
-
'uksort',
|
135 |
-
'usort',
|
136 |
'preg_replace_callback',
|
137 |
'spl_autoload_register',
|
138 |
'iterator_apply',
|
@@ -166,11 +406,15 @@ class Token_Utils extends Component {
|
|
166 |
* @return array
|
167 |
*/
|
168 |
public static function getsuspiciousFunctions() {
|
169 |
-
return array_merge( self::
|
|
|
|
|
|
|
|
|
170 |
'assert',
|
171 |
'eval',
|
172 |
'gzinflate'
|
173 |
-
)
|
174 |
}
|
175 |
|
176 |
/**
|
@@ -330,4 +574,51 @@ class Token_Utils extends Component {
|
|
330 |
'crc32',
|
331 |
);
|
332 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
}
|
13 |
* @var array
|
14 |
*/
|
15 |
static $tokens = array();
|
16 |
+
static $code;
|
17 |
|
18 |
/**
|
19 |
* @param $token
|
32 |
return false;
|
33 |
}
|
34 |
|
35 |
+
/**
|
36 |
+
* Find the first token it met, can skip things dont need
|
37 |
+
*
|
38 |
+
* @param $from
|
39 |
+
* @param null $end
|
40 |
+
* @param array $skips
|
41 |
+
*
|
42 |
+
* @return bool|mixed
|
43 |
+
*/
|
44 |
+
public static function findFirstPrevious( $from, $end = 0, $skips = array() ) {
|
45 |
+
for ( $i = $from; $i >= $end; $i -- ) {
|
46 |
+
if ( isset( self::$tokens[ $i ] ) && ! in_array( self::$tokens[ $i ]['code'], $skips ) ) {
|
47 |
+
return $i;
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
return false;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @param $from
|
56 |
+
* @param null $end
|
57 |
+
* @param array $skips
|
58 |
+
*
|
59 |
+
* @return bool
|
60 |
+
*/
|
61 |
+
public static function findFirstNext( $from, $end = null, $skips = array() ) {
|
62 |
+
if ( $end == null ) {
|
63 |
+
$end = count( self::$tokens ) - 1;
|
64 |
+
}
|
65 |
+
for ( $i = $from; $i <= $end; $i ++ ) {
|
66 |
+
if ( isset( self::$tokens[ $i ] ) && ! in_array( self::$tokens[ $i ]['code'], $skips ) ) {
|
67 |
+
return $i;
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
return false;
|
72 |
+
}
|
73 |
+
|
74 |
/**
|
75 |
* @param $token
|
76 |
* @param $from
|
87 |
$token = array( $token );
|
88 |
}
|
89 |
|
90 |
+
for ( $i = $from; $i <= $end; $i ++ ) {
|
91 |
if ( ! isset( self::$tokens[ $i ] ) ) {
|
92 |
return false;
|
93 |
}
|
120 |
return $str;
|
121 |
}
|
122 |
|
123 |
+
/**
|
124 |
+
* @param $start
|
125 |
+
* @param $end
|
126 |
+
*
|
127 |
+
* @return string
|
128 |
+
*/
|
129 |
+
public static function getTokensAsStringByIndex( $start, $end ) {
|
130 |
+
$str = '';
|
131 |
+
for ( $i = $start; $i < $end; $i ++ ) {
|
132 |
+
$str .= self::$tokens[ $i ]['content'];
|
133 |
+
}
|
134 |
+
|
135 |
+
return $str;
|
136 |
+
}
|
137 |
+
|
138 |
/**
|
139 |
* @param $start
|
140 |
* @param $end
|
144 |
public static function findParams( $start, $end ) {
|
145 |
$params = array();
|
146 |
for ( $i = $start; $i < $end; $i ++ ) {
|
147 |
+
$params[ $i ] = self::$tokens[ $i ];
|
148 |
}
|
149 |
|
150 |
return $params;
|
151 |
}
|
152 |
|
153 |
+
public static function prepareParams() {
|
154 |
+
$results = array();
|
155 |
+
foreach ( self::$tokens as $index => $token ) {
|
156 |
+
if ( $token['code'] == T_VARIABLE ) {
|
157 |
+
$next = self::findFirstNext( $index + 1, null, array( T_WHITESPACE ) );
|
158 |
+
//this should be the =
|
159 |
+
$params = array();
|
160 |
+
if ( self::$tokens[ $next ]['code'] == T_EQUAL ) {
|
161 |
+
//capture this
|
162 |
+
$end = self::findNext( T_SEMICOLON, $index + 2 );
|
163 |
+
$params = self::findParams( $index + 2, $end );
|
164 |
+
|
165 |
+
} elseif ( self::$tokens[ $next ]['code'] == T_OPEN_PARENTHESIS ) {
|
166 |
+
//a variable function
|
167 |
+
}
|
168 |
+
|
169 |
+
$results[] = array(
|
170 |
+
'variable' => $token['content'],
|
171 |
+
'args' => $params
|
172 |
+
);
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
return $results;
|
177 |
+
}
|
178 |
+
|
179 |
/**
|
180 |
* @param $token
|
181 |
*
|
182 |
* @return bool
|
183 |
*/
|
184 |
+
public static function isUserInput(
|
185 |
+
$token
|
186 |
+
) {
|
187 |
if ( $token['code'] == T_VARIABLE
|
188 |
&& preg_match( '/\$\{?_(GET|POST|REQUEST|COOKIE|SERVER|FILES|ENV)/', $token['content'] ) ) {
|
189 |
return true;
|
192 |
return false;
|
193 |
}
|
194 |
|
195 |
+
/**
|
196 |
+
* Borrow from https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/Utils.php
|
197 |
+
* @return array
|
198 |
+
*/
|
199 |
+
public static function getFilesystemFunctions() {
|
200 |
+
return array(
|
201 |
+
// From http://www.php.net/manual/en/book.filesystem.php
|
202 |
+
'chgrp',
|
203 |
+
'chown',
|
204 |
+
'clearstatcache',
|
205 |
+
'copy',
|
206 |
+
'delete',
|
207 |
+
'disk_free_space',
|
208 |
+
'disk_total_space',
|
209 |
+
'diskfreespace',
|
210 |
+
'fclose',
|
211 |
+
'feof',
|
212 |
+
'fflush',
|
213 |
+
'fgetc',
|
214 |
+
'fgetcsv',
|
215 |
+
'fgets',
|
216 |
+
'fgetss',
|
217 |
+
'file_get_contents',
|
218 |
+
'file_put_contents',
|
219 |
+
'file',
|
220 |
+
'fileatime',
|
221 |
+
'filectime',
|
222 |
+
'filegroup',
|
223 |
+
'fileinode',
|
224 |
+
'filemtime',
|
225 |
+
'fileowner',
|
226 |
+
'fileperms',
|
227 |
+
'filesize',
|
228 |
+
'filetype',
|
229 |
+
'flock',
|
230 |
+
'fopen',
|
231 |
+
'fpassthru',
|
232 |
+
'fputcsv',
|
233 |
+
'fputs',
|
234 |
+
'ftruncate',
|
235 |
+
'fwrite',
|
236 |
+
'glob',
|
237 |
+
'is_executable',
|
238 |
+
'is_readable',
|
239 |
+
'is_uploaded_file',
|
240 |
+
'is_writable',
|
241 |
+
'is_writeable',
|
242 |
+
'lchgrp',
|
243 |
+
'lchown',
|
244 |
+
'link',
|
245 |
+
'linkinfo',
|
246 |
+
'lstat',
|
247 |
+
'mkdir',
|
248 |
+
'move_uploaded_file',
|
249 |
+
'parse_ini_file',
|
250 |
+
'parse_ini_string',
|
251 |
+
'readfile',
|
252 |
+
'readlink',
|
253 |
+
'realpath_cache_get',
|
254 |
+
'realpath_cache_size',
|
255 |
+
//'realpath',
|
256 |
+
'rename',
|
257 |
+
'rewind',
|
258 |
+
'rmdir',
|
259 |
+
'set_file_buffer',
|
260 |
+
'stat',
|
261 |
+
'symlink',
|
262 |
+
'tempnam',
|
263 |
+
'tmpfile',
|
264 |
+
'touch',
|
265 |
+
'umask',
|
266 |
+
'unlink',
|
267 |
+
// From http://www.php.net/manual/en/ref.dir.php except function that use directory handle as parameter
|
268 |
+
'chdir',
|
269 |
+
'chroot',
|
270 |
+
'dir',
|
271 |
+
'opendir',
|
272 |
+
'scandir',
|
273 |
+
// From http://ca2.php.net/manual/en/function.mime-content-type.php
|
274 |
+
'finfo_open',
|
275 |
+
// From http://ca2.php.net/manual/en/book.xattr.php
|
276 |
+
'xattr_get',
|
277 |
+
'xattr_list',
|
278 |
+
'xattr_remove',
|
279 |
+
'xattr_set',
|
280 |
+
'xattr_supported',
|
281 |
+
// From http://www.php.net/manual/en/function.readgzfile.php
|
282 |
+
'readgzfile',
|
283 |
+
'gzopen',
|
284 |
+
'gzfile',
|
285 |
+
// From http://www.php.net/manual/en/ref.image.php
|
286 |
+
'getimagesize',
|
287 |
+
'imagecreatefromgd2',
|
288 |
+
'imagecreatefromgd2part',
|
289 |
+
'imagecreatefromgd',
|
290 |
+
'imagecreatefromgif',
|
291 |
+
'imagecreatefromjpeg',
|
292 |
+
'imagecreatefrompng',
|
293 |
+
'imagecreatefromwbmp',
|
294 |
+
'imagecreatefromwebp',
|
295 |
+
'imagecreatefromxbm',
|
296 |
+
'imagecreatefromxpm',
|
297 |
+
'imagepsloadfont',
|
298 |
+
'jpeg2wbmp',
|
299 |
+
'png2wbmp',
|
300 |
+
// 2nd params only, maybe make it standalone and check just the second param?
|
301 |
+
'image2wbmp',
|
302 |
+
'imagegd2',
|
303 |
+
'imagegd',
|
304 |
+
'imagegif',
|
305 |
+
'imagejpeg',
|
306 |
+
'imagepng',
|
307 |
+
'imagewbmp',
|
308 |
+
'imagewebp',
|
309 |
+
'imagexbm',
|
310 |
+
// From http://www.php.net/manual/en/ref.exif.php
|
311 |
+
'exif_imagetype',
|
312 |
+
'exif_read_data',
|
313 |
+
'exif_thumbnail',
|
314 |
+
'read_exif_data',
|
315 |
+
// From http://www.php.net/manual/en/ref.hash.php
|
316 |
+
'hash_file',
|
317 |
+
'hash_hmac_file',
|
318 |
+
'hash_update_file',
|
319 |
+
// From http://www.php.net/manual/en/ref.misc.php
|
320 |
+
'highlight_file',
|
321 |
+
'php_check_syntax',
|
322 |
+
'php_strip_whitespace',
|
323 |
+
'show_source',
|
324 |
+
// Various functions that open/read files
|
325 |
+
'get_meta_tags',
|
326 |
+
'hash_file',
|
327 |
+
'hash_hmac_file',
|
328 |
+
'hash_update_file',
|
329 |
+
'md5_file',
|
330 |
+
'sha1_file',
|
331 |
+
'bzopen',
|
332 |
+
//Curl Functions
|
333 |
+
'curl_exec',
|
334 |
+
'curl_multi_exec',
|
335 |
+
);
|
336 |
+
}
|
337 |
+
|
338 |
+
//Borrow from https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/Utils.php
|
339 |
+
public static function getSystemexecFunctions() {
|
340 |
+
return array(
|
341 |
+
'exec',
|
342 |
+
'passthru',
|
343 |
+
'proc_open',
|
344 |
+
'popen',
|
345 |
+
'shell_exec',
|
346 |
+
'system',
|
347 |
+
'pcntl_exec'
|
348 |
+
);
|
349 |
+
}
|
350 |
+
|
351 |
+
public static function getInclutions() {
|
352 |
+
return array( 'include', 'include_once', 'require', 'require_once' );
|
353 |
+
}
|
354 |
+
|
355 |
//Borrow from https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/Utils.php
|
356 |
//Point to RIPs and SO https://stackoverflow.com/questions/3115559/exploitable-php-functions
|
357 |
public static function getCallbackFunctions() {
|
359 |
'ob_start',
|
360 |
'array_diff_uassoc',
|
361 |
'array_diff_ukey',
|
362 |
+
//'array_filter',
|
363 |
'array_intersect_uassoc',
|
364 |
'array_intersect_ukey',
|
365 |
+
//'array_map',
|
366 |
'array_reduce',
|
367 |
'array_udiff_assoc',
|
368 |
'array_udiff_uassoc',
|
373 |
'array_walk_recursive',
|
374 |
'array_walk',
|
375 |
'assert_options',
|
|
|
|
|
|
|
376 |
'preg_replace_callback',
|
377 |
'spl_autoload_register',
|
378 |
'iterator_apply',
|
406 |
* @return array
|
407 |
*/
|
408 |
public static function getsuspiciousFunctions() {
|
409 |
+
return array_merge( self::getDangeriousFunction(), self::getFilesystemFunctions() );
|
410 |
+
}
|
411 |
+
|
412 |
+
public static function getDangeriousFunction() {
|
413 |
+
return array(
|
414 |
'assert',
|
415 |
'eval',
|
416 |
'gzinflate'
|
417 |
+
);
|
418 |
}
|
419 |
|
420 |
/**
|
574 |
'crc32',
|
575 |
);
|
576 |
}
|
577 |
+
|
578 |
+
/**
|
579 |
+
* @return array
|
580 |
+
*/
|
581 |
+
public static function getSanitizeFunctions() {
|
582 |
+
return array(
|
583 |
+
'sanitize_email',
|
584 |
+
'sanitize_file_name',
|
585 |
+
'sanitize_html_class',
|
586 |
+
'sanitize_key',
|
587 |
+
'sanitize_meta',
|
588 |
+
'sanitize_mime_type',
|
589 |
+
'sanitize_option',
|
590 |
+
'sanitize_sql_orderby',
|
591 |
+
'sanitize_text_field',
|
592 |
+
'sanitize_textarea_field',
|
593 |
+
'sanitize_title',
|
594 |
+
'sanitize_title_for_query',
|
595 |
+
'sanitize_title_with_dashes',
|
596 |
+
'sanitize_user',
|
597 |
+
'intval',
|
598 |
+
'floatval'
|
599 |
+
);
|
600 |
+
}
|
601 |
+
|
602 |
+
public static function getOutputFunctions() {
|
603 |
+
return array(
|
604 |
+
'echo',
|
605 |
+
'print'
|
606 |
+
);
|
607 |
+
}
|
608 |
+
|
609 |
+
public static function getEscapeFunction() {
|
610 |
+
return array(
|
611 |
+
'esc_html',
|
612 |
+
'esc_html_',
|
613 |
+
'esc_html_e',
|
614 |
+
'esc_html_x',
|
615 |
+
'esc_url',
|
616 |
+
'esc_js',
|
617 |
+
'esc_attr',
|
618 |
+
'esc_attr_',
|
619 |
+
'esc_attr_e',
|
620 |
+
'esc_attr_x',
|
621 |
+
'esc_textarea'
|
622 |
+
);
|
623 |
+
}
|
624 |
}
|
app/module/scan/controller/main.php
CHANGED
@@ -491,7 +491,7 @@ class Main extends \WP_Defender\Controller {
|
|
491 |
//from dashboard
|
492 |
$data['url'] = network_admin_url( 'admin.php?page=wp-defender' );
|
493 |
}
|
494 |
-
$this->sendEmailReport(
|
495 |
$this->submitStatsToDev();
|
496 |
wp_send_json_success( $data );
|
497 |
} else {
|
@@ -559,10 +559,10 @@ class Main extends \WP_Defender\Controller {
|
|
559 |
wp_enqueue_style( 'wpmudev-sui' );
|
560 |
|
561 |
wp_enqueue_script( 'defender' );
|
562 |
-
wp_enqueue_script( '
|
563 |
-
wp_enqueue_script( 'highlight-linenumbers.js', wp_defender()->getPluginUrl() . 'app/module/scan/js/highlightjs-line-numbers.js' );
|
564 |
wp_enqueue_style( 'defender' );
|
565 |
wp_enqueue_script( 'scan', wp_defender()->getPluginUrl() . 'app/module/scan/js/script.js' );
|
|
|
566 |
wp_localize_script( 'scan', 'scan', $data );
|
567 |
} else {
|
568 |
wp_enqueue_script( 'scan', wp_defender()->getPluginUrl() . 'app/module/scan/js/script.js' );
|
@@ -770,26 +770,38 @@ class Main extends \WP_Defender\Controller {
|
|
770 |
|
771 |
public function sendEmailReport( $force = false ) {
|
772 |
$settings = Settings::instance();
|
773 |
-
if ( $settings->notification == false && $force != true ) {
|
774 |
-
return false;
|
775 |
-
}
|
776 |
|
777 |
$model = Scan_Api::getLastScan();
|
778 |
if ( ! is_object( $model ) ) {
|
779 |
return;
|
780 |
}
|
|
|
|
|
|
|
|
|
|
|
781 |
$count = $model->countAll( Result_Item::STATUS_ISSUE );
|
782 |
|
783 |
//Check one instead of validating both conditions
|
784 |
if ( $model->logs == 'report' ) {
|
|
|
|
|
|
|
|
|
785 |
if ( $settings->always_send == false && $count == 0 ) {
|
786 |
return;
|
787 |
}
|
|
|
788 |
$recipients = $settings->receipts;
|
789 |
} else {
|
|
|
|
|
|
|
|
|
790 |
if ( $settings->alwaysSendNotification == false && $count == 0 ) {
|
791 |
return;
|
792 |
}
|
|
|
793 |
$recipients = $settings->receiptsNotification;
|
794 |
}
|
795 |
|
491 |
//from dashboard
|
492 |
$data['url'] = network_admin_url( 'admin.php?page=wp-defender' );
|
493 |
}
|
494 |
+
$this->sendEmailReport();
|
495 |
$this->submitStatsToDev();
|
496 |
wp_send_json_success( $data );
|
497 |
} else {
|
559 |
wp_enqueue_style( 'wpmudev-sui' );
|
560 |
|
561 |
wp_enqueue_script( 'defender' );
|
562 |
+
wp_enqueue_script( 'prism', wp_defender()->getPluginUrl() . 'app/module/scan/js/prism.js' );
|
|
|
563 |
wp_enqueue_style( 'defender' );
|
564 |
wp_enqueue_script( 'scan', wp_defender()->getPluginUrl() . 'app/module/scan/js/script.js' );
|
565 |
+
wp_enqueue_style( 'prism', wp_defender()->getPluginUrl() . 'app/module/scan/js/prism.css' );
|
566 |
wp_localize_script( 'scan', 'scan', $data );
|
567 |
} else {
|
568 |
wp_enqueue_script( 'scan', wp_defender()->getPluginUrl() . 'app/module/scan/js/script.js' );
|
770 |
|
771 |
public function sendEmailReport( $force = false ) {
|
772 |
$settings = Settings::instance();
|
|
|
|
|
|
|
773 |
|
774 |
$model = Scan_Api::getLastScan();
|
775 |
if ( ! is_object( $model ) ) {
|
776 |
return;
|
777 |
}
|
778 |
+
|
779 |
+
if ( $settings->notification == false && $force != true ) {
|
780 |
+
return false;
|
781 |
+
}
|
782 |
+
|
783 |
$count = $model->countAll( Result_Item::STATUS_ISSUE );
|
784 |
|
785 |
//Check one instead of validating both conditions
|
786 |
if ( $model->logs == 'report' ) {
|
787 |
+
if ( $settings->report == false ) {
|
788 |
+
return;
|
789 |
+
}
|
790 |
+
|
791 |
if ( $settings->always_send == false && $count == 0 ) {
|
792 |
return;
|
793 |
}
|
794 |
+
|
795 |
$recipients = $settings->receipts;
|
796 |
} else {
|
797 |
+
if ( $settings->notification == false ) {
|
798 |
+
return;
|
799 |
+
}
|
800 |
+
|
801 |
if ( $settings->alwaysSendNotification == false && $count == 0 ) {
|
802 |
return;
|
803 |
}
|
804 |
+
|
805 |
$recipients = $settings->receiptsNotification;
|
806 |
}
|
807 |
|
app/module/scan/js/prism.css
ADDED
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* PrismJS 1.16.0
|
2 |
+
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+markup-templating+php&plugins=line-numbers+keep-markup */
|
3 |
+
/**
|
4 |
+
* prism.js default theme for JavaScript, CSS and HTML
|
5 |
+
* Based on dabblet (http://dabblet.com)
|
6 |
+
* @author Lea Verou
|
7 |
+
*/
|
8 |
+
|
9 |
+
code[class*="language-"],
|
10 |
+
pre[class*="language-"] {
|
11 |
+
color: black;
|
12 |
+
background: none;
|
13 |
+
text-shadow: 0 1px white;
|
14 |
+
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
15 |
+
font-size: 1em;
|
16 |
+
text-align: left;
|
17 |
+
white-space: pre;
|
18 |
+
word-spacing: normal;
|
19 |
+
word-break: normal;
|
20 |
+
word-wrap: normal;
|
21 |
+
line-height: 1.5;
|
22 |
+
|
23 |
+
-moz-tab-size: 4;
|
24 |
+
-o-tab-size: 4;
|
25 |
+
tab-size: 4;
|
26 |
+
|
27 |
+
-webkit-hyphens: none;
|
28 |
+
-moz-hyphens: none;
|
29 |
+
-ms-hyphens: none;
|
30 |
+
hyphens: none;
|
31 |
+
}
|
32 |
+
|
33 |
+
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
34 |
+
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
35 |
+
text-shadow: none;
|
36 |
+
background: #b3d4fc;
|
37 |
+
}
|
38 |
+
|
39 |
+
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
40 |
+
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
41 |
+
text-shadow: none;
|
42 |
+
background: #b3d4fc;
|
43 |
+
}
|
44 |
+
|
45 |
+
@media print {
|
46 |
+
code[class*="language-"],
|
47 |
+
pre[class*="language-"] {
|
48 |
+
text-shadow: none;
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
/* Code blocks */
|
53 |
+
pre[class*="language-"] {
|
54 |
+
padding: 1em;
|
55 |
+
margin: .5em 0;
|
56 |
+
overflow: auto;
|
57 |
+
}
|
58 |
+
|
59 |
+
:not(pre) > code[class*="language-"],
|
60 |
+
pre[class*="language-"] {
|
61 |
+
background: #f5f2f0;
|
62 |
+
}
|
63 |
+
|
64 |
+
/* Inline code */
|
65 |
+
:not(pre) > code[class*="language-"] {
|
66 |
+
padding: .1em;
|
67 |
+
border-radius: .3em;
|
68 |
+
white-space: normal;
|
69 |
+
}
|
70 |
+
|
71 |
+
.token.comment,
|
72 |
+
.token.prolog,
|
73 |
+
.token.doctype,
|
74 |
+
.token.cdata {
|
75 |
+
color: slategray;
|
76 |
+
}
|
77 |
+
|
78 |
+
.token.punctuation {
|
79 |
+
color: #999;
|
80 |
+
}
|
81 |
+
|
82 |
+
.namespace {
|
83 |
+
opacity: .7;
|
84 |
+
}
|
85 |
+
|
86 |
+
.token.property,
|
87 |
+
.token.tag,
|
88 |
+
.token.boolean,
|
89 |
+
.token.number,
|
90 |
+
.token.constant,
|
91 |
+
.token.symbol,
|
92 |
+
.token.deleted {
|
93 |
+
color: #905;
|
94 |
+
}
|
95 |
+
|
96 |
+
.token.selector,
|
97 |
+
.token.attr-name,
|
98 |
+
.token.string,
|
99 |
+
.token.char,
|
100 |
+
.token.builtin,
|
101 |
+
.token.inserted {
|
102 |
+
color: #690;
|
103 |
+
}
|
104 |
+
|
105 |
+
.token.operator,
|
106 |
+
.token.entity,
|
107 |
+
.token.url,
|
108 |
+
.language-css .token.string,
|
109 |
+
.style .token.string {
|
110 |
+
color: #9a6e3a;
|
111 |
+
background: hsla(0, 0%, 100%, .5);
|
112 |
+
}
|
113 |
+
|
114 |
+
.token.atrule,
|
115 |
+
.token.attr-value,
|
116 |
+
.token.keyword {
|
117 |
+
color: #07a;
|
118 |
+
}
|
119 |
+
|
120 |
+
.token.function,
|
121 |
+
.token.class-name {
|
122 |
+
color: #DD4A68;
|
123 |
+
}
|
124 |
+
|
125 |
+
.token.regex,
|
126 |
+
.token.important,
|
127 |
+
.token.variable {
|
128 |
+
color: #e90;
|
129 |
+
}
|
130 |
+
|
131 |
+
.token.important,
|
132 |
+
.token.bold {
|
133 |
+
font-weight: bold;
|
134 |
+
}
|
135 |
+
.token.italic {
|
136 |
+
font-style: italic;
|
137 |
+
}
|
138 |
+
|
139 |
+
.token.entity {
|
140 |
+
cursor: help;
|
141 |
+
}
|
142 |
+
|
143 |
+
pre[class*="language-"].line-numbers {
|
144 |
+
position: relative;
|
145 |
+
padding-left: 3.8em !important;
|
146 |
+
counter-reset: linenumber;
|
147 |
+
}
|
148 |
+
|
149 |
+
pre[class*="language-"].line-numbers > code {
|
150 |
+
position: relative;
|
151 |
+
white-space: inherit;
|
152 |
+
}
|
153 |
+
|
154 |
+
.line-numbers .line-numbers-rows {
|
155 |
+
position: absolute;
|
156 |
+
pointer-events: none;
|
157 |
+
top: 0;
|
158 |
+
font-size: 100%;
|
159 |
+
left: -3.8em;
|
160 |
+
width: 3em; /* works for line-numbers below 1000 lines */
|
161 |
+
letter-spacing: -1px;
|
162 |
+
border-right: 1px solid #999;
|
163 |
+
|
164 |
+
-webkit-user-select: none;
|
165 |
+
-moz-user-select: none;
|
166 |
+
-ms-user-select: none;
|
167 |
+
user-select: none;
|
168 |
+
|
169 |
+
}
|
170 |
+
|
171 |
+
.line-numbers-rows > span {
|
172 |
+
pointer-events: none;
|
173 |
+
display: block;
|
174 |
+
counter-increment: linenumber;
|
175 |
+
}
|
176 |
+
|
177 |
+
.line-numbers-rows > span:before {
|
178 |
+
content: counter(linenumber);
|
179 |
+
color: #999;
|
180 |
+
display: block;
|
181 |
+
padding-right: 0.8em;
|
182 |
+
text-align: right;
|
183 |
+
}
|
app/module/scan/js/prism.js
ADDED
@@ -0,0 +1,1350 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* PrismJS 1.16.0
|
2 |
+
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+markup-templating+php&plugins=line-numbers+keep-markup */
|
3 |
+
var _self = (typeof window !== 'undefined')
|
4 |
+
? window // if in browser
|
5 |
+
: (
|
6 |
+
(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
|
7 |
+
? self // if in worker
|
8 |
+
: {} // if in node js
|
9 |
+
);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Prism: Lightweight, robust, elegant syntax highlighting
|
13 |
+
* MIT license http://www.opensource.org/licenses/mit-license.php/
|
14 |
+
* @author Lea Verou http://lea.verou.me
|
15 |
+
*/
|
16 |
+
|
17 |
+
var Prism = (function (_self){
|
18 |
+
|
19 |
+
// Private helper vars
|
20 |
+
var lang = /\blang(?:uage)?-([\w-]+)\b/i;
|
21 |
+
var uniqueId = 0;
|
22 |
+
|
23 |
+
var _ = {
|
24 |
+
manual: _self.Prism && _self.Prism.manual,
|
25 |
+
disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
|
26 |
+
util: {
|
27 |
+
encode: function (tokens) {
|
28 |
+
if (tokens instanceof Token) {
|
29 |
+
return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
|
30 |
+
} else if (Array.isArray(tokens)) {
|
31 |
+
return tokens.map(_.util.encode);
|
32 |
+
} else {
|
33 |
+
return tokens.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');
|
34 |
+
}
|
35 |
+
},
|
36 |
+
|
37 |
+
type: function (o) {
|
38 |
+
return Object.prototype.toString.call(o).slice(8, -1);
|
39 |
+
},
|
40 |
+
|
41 |
+
objId: function (obj) {
|
42 |
+
if (!obj['__id']) {
|
43 |
+
Object.defineProperty(obj, '__id', { value: ++uniqueId });
|
44 |
+
}
|
45 |
+
return obj['__id'];
|
46 |
+
},
|
47 |
+
|
48 |
+
// Deep clone a language definition (e.g. to extend it)
|
49 |
+
clone: function deepClone(o, visited) {
|
50 |
+
var clone, id, type = _.util.type(o);
|
51 |
+
visited = visited || {};
|
52 |
+
|
53 |
+
switch (type) {
|
54 |
+
case 'Object':
|
55 |
+
id = _.util.objId(o);
|
56 |
+
if (visited[id]) {
|
57 |
+
return visited[id];
|
58 |
+
}
|
59 |
+
clone = {};
|
60 |
+
visited[id] = clone;
|
61 |
+
|
62 |
+
for (var key in o) {
|
63 |
+
if (o.hasOwnProperty(key)) {
|
64 |
+
clone[key] = deepClone(o[key], visited);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
return clone;
|
69 |
+
|
70 |
+
case 'Array':
|
71 |
+
id = _.util.objId(o);
|
72 |
+
if (visited[id]) {
|
73 |
+
return visited[id];
|
74 |
+
}
|
75 |
+
clone = [];
|
76 |
+
visited[id] = clone;
|
77 |
+
|
78 |
+
o.forEach(function (v, i) {
|
79 |
+
clone[i] = deepClone(v, visited);
|
80 |
+
});
|
81 |
+
|
82 |
+
return clone;
|
83 |
+
|
84 |
+
default:
|
85 |
+
return o;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
},
|
89 |
+
|
90 |
+
languages: {
|
91 |
+
extend: function (id, redef) {
|
92 |
+
var lang = _.util.clone(_.languages[id]);
|
93 |
+
|
94 |
+
for (var key in redef) {
|
95 |
+
lang[key] = redef[key];
|
96 |
+
}
|
97 |
+
|
98 |
+
return lang;
|
99 |
+
},
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Insert a token before another token in a language literal
|
103 |
+
* As this needs to recreate the object (we cannot actually insert before keys in object literals),
|
104 |
+
* we cannot just provide an object, we need an object and a key.
|
105 |
+
* @param inside The key (or language id) of the parent
|
106 |
+
* @param before The key to insert before.
|
107 |
+
* @param insert Object with the key/value pairs to insert
|
108 |
+
* @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
|
109 |
+
*/
|
110 |
+
insertBefore: function (inside, before, insert, root) {
|
111 |
+
root = root || _.languages;
|
112 |
+
var grammar = root[inside];
|
113 |
+
var ret = {};
|
114 |
+
|
115 |
+
for (var token in grammar) {
|
116 |
+
if (grammar.hasOwnProperty(token)) {
|
117 |
+
|
118 |
+
if (token == before) {
|
119 |
+
for (var newToken in insert) {
|
120 |
+
if (insert.hasOwnProperty(newToken)) {
|
121 |
+
ret[newToken] = insert[newToken];
|
122 |
+
}
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
// Do not insert token which also occur in insert. See #1525
|
127 |
+
if (!insert.hasOwnProperty(token)) {
|
128 |
+
ret[token] = grammar[token];
|
129 |
+
}
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
var old = root[inside];
|
134 |
+
root[inside] = ret;
|
135 |
+
|
136 |
+
// Update references in other language definitions
|
137 |
+
_.languages.DFS(_.languages, function(key, value) {
|
138 |
+
if (value === old && key != inside) {
|
139 |
+
this[key] = ret;
|
140 |
+
}
|
141 |
+
});
|
142 |
+
|
143 |
+
return ret;
|
144 |
+
},
|
145 |
+
|
146 |
+
// Traverse a language definition with Depth First Search
|
147 |
+
DFS: function DFS(o, callback, type, visited) {
|
148 |
+
visited = visited || {};
|
149 |
+
|
150 |
+
var objId = _.util.objId;
|
151 |
+
|
152 |
+
for (var i in o) {
|
153 |
+
if (o.hasOwnProperty(i)) {
|
154 |
+
callback.call(o, i, o[i], type || i);
|
155 |
+
|
156 |
+
var property = o[i],
|
157 |
+
propertyType = _.util.type(property);
|
158 |
+
|
159 |
+
if (propertyType === 'Object' && !visited[objId(property)]) {
|
160 |
+
visited[objId(property)] = true;
|
161 |
+
DFS(property, callback, null, visited);
|
162 |
+
}
|
163 |
+
else if (propertyType === 'Array' && !visited[objId(property)]) {
|
164 |
+
visited[objId(property)] = true;
|
165 |
+
DFS(property, callback, i, visited);
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
169 |
+
}
|
170 |
+
},
|
171 |
+
plugins: {},
|
172 |
+
|
173 |
+
highlightAll: function(async, callback) {
|
174 |
+
_.highlightAllUnder(document, async, callback);
|
175 |
+
},
|
176 |
+
|
177 |
+
highlightAllUnder: function(container, async, callback) {
|
178 |
+
var env = {
|
179 |
+
callback: callback,
|
180 |
+
selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
|
181 |
+
};
|
182 |
+
|
183 |
+
_.hooks.run("before-highlightall", env);
|
184 |
+
|
185 |
+
var elements = env.elements || container.querySelectorAll(env.selector);
|
186 |
+
|
187 |
+
for (var i=0, element; element = elements[i++];) {
|
188 |
+
_.highlightElement(element, async === true, env.callback);
|
189 |
+
}
|
190 |
+
},
|
191 |
+
|
192 |
+
highlightElement: function(element, async, callback) {
|
193 |
+
// Find language
|
194 |
+
var language, grammar, parent = element;
|
195 |
+
|
196 |
+
while (parent && !lang.test(parent.className)) {
|
197 |
+
parent = parent.parentNode;
|
198 |
+
}
|
199 |
+
|
200 |
+
if (parent) {
|
201 |
+
language = (parent.className.match(lang) || [,''])[1].toLowerCase();
|
202 |
+
grammar = _.languages[language];
|
203 |
+
}
|
204 |
+
|
205 |
+
// Set language on the element, if not present
|
206 |
+
element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
|
207 |
+
|
208 |
+
if (element.parentNode) {
|
209 |
+
// Set language on the parent, for styling
|
210 |
+
parent = element.parentNode;
|
211 |
+
|
212 |
+
if (/pre/i.test(parent.nodeName)) {
|
213 |
+
parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
var code = element.textContent;
|
218 |
+
|
219 |
+
var env = {
|
220 |
+
element: element,
|
221 |
+
language: language,
|
222 |
+
grammar: grammar,
|
223 |
+
code: code
|
224 |
+
};
|
225 |
+
|
226 |
+
var insertHighlightedCode = function (highlightedCode) {
|
227 |
+
env.highlightedCode = highlightedCode;
|
228 |
+
|
229 |
+
_.hooks.run('before-insert', env);
|
230 |
+
|
231 |
+
env.element.innerHTML = env.highlightedCode;
|
232 |
+
|
233 |
+
_.hooks.run('after-highlight', env);
|
234 |
+
_.hooks.run('complete', env);
|
235 |
+
callback && callback.call(env.element);
|
236 |
+
}
|
237 |
+
|
238 |
+
_.hooks.run('before-sanity-check', env);
|
239 |
+
|
240 |
+
if (!env.code) {
|
241 |
+
_.hooks.run('complete', env);
|
242 |
+
return;
|
243 |
+
}
|
244 |
+
|
245 |
+
_.hooks.run('before-highlight', env);
|
246 |
+
|
247 |
+
if (!env.grammar) {
|
248 |
+
insertHighlightedCode(_.util.encode(env.code));
|
249 |
+
return;
|
250 |
+
}
|
251 |
+
|
252 |
+
if (async && _self.Worker) {
|
253 |
+
var worker = new Worker(_.filename);
|
254 |
+
|
255 |
+
worker.onmessage = function(evt) {
|
256 |
+
insertHighlightedCode(evt.data);
|
257 |
+
};
|
258 |
+
|
259 |
+
worker.postMessage(JSON.stringify({
|
260 |
+
language: env.language,
|
261 |
+
code: env.code,
|
262 |
+
immediateClose: true
|
263 |
+
}));
|
264 |
+
}
|
265 |
+
else {
|
266 |
+
insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
|
267 |
+
}
|
268 |
+
},
|
269 |
+
|
270 |
+
highlight: function (text, grammar, language) {
|
271 |
+
var env = {
|
272 |
+
code: text,
|
273 |
+
grammar: grammar,
|
274 |
+
language: language
|
275 |
+
};
|
276 |
+
_.hooks.run('before-tokenize', env);
|
277 |
+
env.tokens = _.tokenize(env.code, env.grammar);
|
278 |
+
_.hooks.run('after-tokenize', env);
|
279 |
+
return Token.stringify(_.util.encode(env.tokens), env.language);
|
280 |
+
},
|
281 |
+
|
282 |
+
matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) {
|
283 |
+
for (var token in grammar) {
|
284 |
+
if(!grammar.hasOwnProperty(token) || !grammar[token]) {
|
285 |
+
continue;
|
286 |
+
}
|
287 |
+
|
288 |
+
if (token == target) {
|
289 |
+
return;
|
290 |
+
}
|
291 |
+
|
292 |
+
var patterns = grammar[token];
|
293 |
+
patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
|
294 |
+
|
295 |
+
for (var j = 0; j < patterns.length; ++j) {
|
296 |
+
var pattern = patterns[j],
|
297 |
+
inside = pattern.inside,
|
298 |
+
lookbehind = !!pattern.lookbehind,
|
299 |
+
greedy = !!pattern.greedy,
|
300 |
+
lookbehindLength = 0,
|
301 |
+
alias = pattern.alias;
|
302 |
+
|
303 |
+
if (greedy && !pattern.pattern.global) {
|
304 |
+
// Without the global flag, lastIndex won't work
|
305 |
+
var flags = pattern.pattern.toString().match(/[imuy]*$/)[0];
|
306 |
+
pattern.pattern = RegExp(pattern.pattern.source, flags + "g");
|
307 |
+
}
|
308 |
+
|
309 |
+
pattern = pattern.pattern || pattern;
|
310 |
+
|
311 |
+
// Don’t cache length as it changes during the loop
|
312 |
+
for (var i = index, pos = startPos; i < strarr.length; pos += strarr[i].length, ++i) {
|
313 |
+
|
314 |
+
var str = strarr[i];
|
315 |
+
|
316 |
+
if (strarr.length > text.length) {
|
317 |
+
// Something went terribly wrong, ABORT, ABORT!
|
318 |
+
return;
|
319 |
+
}
|
320 |
+
|
321 |
+
if (str instanceof Token) {
|
322 |
+
continue;
|
323 |
+
}
|
324 |
+
|
325 |
+
if (greedy && i != strarr.length - 1) {
|
326 |
+
pattern.lastIndex = pos;
|
327 |
+
var match = pattern.exec(text);
|
328 |
+
if (!match) {
|
329 |
+
break;
|
330 |
+
}
|
331 |
+
|
332 |
+
var from = match.index + (lookbehind ? match[1].length : 0),
|
333 |
+
to = match.index + match[0].length,
|
334 |
+
k = i,
|
335 |
+
p = pos;
|
336 |
+
|
337 |
+
for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) {
|
338 |
+
p += strarr[k].length;
|
339 |
+
// Move the index i to the element in strarr that is closest to from
|
340 |
+
if (from >= p) {
|
341 |
+
++i;
|
342 |
+
pos = p;
|
343 |
+
}
|
344 |
+
}
|
345 |
+
|
346 |
+
// If strarr[i] is a Token, then the match starts inside another Token, which is invalid
|
347 |
+
if (strarr[i] instanceof Token) {
|
348 |
+
continue;
|
349 |
+
}
|
350 |
+
|
351 |
+
// Number of tokens to delete and replace with the new match
|
352 |
+
delNum = k - i;
|
353 |
+
str = text.slice(pos, p);
|
354 |
+
match.index -= pos;
|
355 |
+
} else {
|
356 |
+
pattern.lastIndex = 0;
|
357 |
+
|
358 |
+
var match = pattern.exec(str),
|
359 |
+
delNum = 1;
|
360 |
+
}
|
361 |
+
|
362 |
+
if (!match) {
|
363 |
+
if (oneshot) {
|
364 |
+
break;
|
365 |
+
}
|
366 |
+
|
367 |
+
continue;
|
368 |
+
}
|
369 |
+
|
370 |
+
if(lookbehind) {
|
371 |
+
lookbehindLength = match[1] ? match[1].length : 0;
|
372 |
+
}
|
373 |
+
|
374 |
+
var from = match.index + lookbehindLength,
|
375 |
+
match = match[0].slice(lookbehindLength),
|
376 |
+
to = from + match.length,
|
377 |
+
before = str.slice(0, from),
|
378 |
+
after = str.slice(to);
|
379 |
+
|
380 |
+
var args = [i, delNum];
|
381 |
+
|
382 |
+
if (before) {
|
383 |
+
++i;
|
384 |
+
pos += before.length;
|
385 |
+
args.push(before);
|
386 |
+
}
|
387 |
+
|
388 |
+
var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy);
|
389 |
+
|
390 |
+
args.push(wrapped);
|
391 |
+
|
392 |
+
if (after) {
|
393 |
+
args.push(after);
|
394 |
+
}
|
395 |
+
|
396 |
+
Array.prototype.splice.apply(strarr, args);
|
397 |
+
|
398 |
+
if (delNum != 1)
|
399 |
+
_.matchGrammar(text, strarr, grammar, i, pos, true, token);
|
400 |
+
|
401 |
+
if (oneshot)
|
402 |
+
break;
|
403 |
+
}
|
404 |
+
}
|
405 |
+
}
|
406 |
+
},
|
407 |
+
|
408 |
+
tokenize: function(text, grammar) {
|
409 |
+
var strarr = [text];
|
410 |
+
|
411 |
+
var rest = grammar.rest;
|
412 |
+
|
413 |
+
if (rest) {
|
414 |
+
for (var token in rest) {
|
415 |
+
grammar[token] = rest[token];
|
416 |
+
}
|
417 |
+
|
418 |
+
delete grammar.rest;
|
419 |
+
}
|
420 |
+
|
421 |
+
_.matchGrammar(text, strarr, grammar, 0, 0, false);
|
422 |
+
|
423 |
+
return strarr;
|
424 |
+
},
|
425 |
+
|
426 |
+
hooks: {
|
427 |
+
all: {},
|
428 |
+
|
429 |
+
add: function (name, callback) {
|
430 |
+
var hooks = _.hooks.all;
|
431 |
+
|
432 |
+
hooks[name] = hooks[name] || [];
|
433 |
+
|
434 |
+
hooks[name].push(callback);
|
435 |
+
},
|
436 |
+
|
437 |
+
run: function (name, env) {
|
438 |
+
var callbacks = _.hooks.all[name];
|
439 |
+
|
440 |
+
if (!callbacks || !callbacks.length) {
|
441 |
+
return;
|
442 |
+
}
|
443 |
+
|
444 |
+
for (var i=0, callback; callback = callbacks[i++];) {
|
445 |
+
callback(env);
|
446 |
+
}
|
447 |
+
}
|
448 |
+
},
|
449 |
+
|
450 |
+
Token: Token
|
451 |
+
};
|
452 |
+
|
453 |
+
_self.Prism = _;
|
454 |
+
|
455 |
+
function Token(type, content, alias, matchedStr, greedy) {
|
456 |
+
this.type = type;
|
457 |
+
this.content = content;
|
458 |
+
this.alias = alias;
|
459 |
+
// Copy of the full string this token was created from
|
460 |
+
this.length = (matchedStr || "").length|0;
|
461 |
+
this.greedy = !!greedy;
|
462 |
+
}
|
463 |
+
|
464 |
+
Token.stringify = function(o, language) {
|
465 |
+
if (typeof o == 'string') {
|
466 |
+
return o;
|
467 |
+
}
|
468 |
+
|
469 |
+
if (Array.isArray(o)) {
|
470 |
+
return o.map(function(element) {
|
471 |
+
return Token.stringify(element, language);
|
472 |
+
}).join('');
|
473 |
+
}
|
474 |
+
|
475 |
+
var env = {
|
476 |
+
type: o.type,
|
477 |
+
content: Token.stringify(o.content, language),
|
478 |
+
tag: 'span',
|
479 |
+
classes: ['token', o.type],
|
480 |
+
attributes: {},
|
481 |
+
language: language
|
482 |
+
};
|
483 |
+
|
484 |
+
if (o.alias) {
|
485 |
+
var aliases = Array.isArray(o.alias) ? o.alias : [o.alias];
|
486 |
+
Array.prototype.push.apply(env.classes, aliases);
|
487 |
+
}
|
488 |
+
|
489 |
+
_.hooks.run('wrap', env);
|
490 |
+
|
491 |
+
var attributes = Object.keys(env.attributes).map(function(name) {
|
492 |
+
return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"';
|
493 |
+
}).join(' ');
|
494 |
+
|
495 |
+
return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + '</' + env.tag + '>';
|
496 |
+
};
|
497 |
+
|
498 |
+
if (!_self.document) {
|
499 |
+
if (!_self.addEventListener) {
|
500 |
+
// in Node.js
|
501 |
+
return _;
|
502 |
+
}
|
503 |
+
|
504 |
+
if (!_.disableWorkerMessageHandler) {
|
505 |
+
// In worker
|
506 |
+
_self.addEventListener('message', function (evt) {
|
507 |
+
var message = JSON.parse(evt.data),
|
508 |
+
lang = message.language,
|
509 |
+
code = message.code,
|
510 |
+
immediateClose = message.immediateClose;
|
511 |
+
|
512 |
+
_self.postMessage(_.highlight(code, _.languages[lang], lang));
|
513 |
+
if (immediateClose) {
|
514 |
+
_self.close();
|
515 |
+
}
|
516 |
+
}, false);
|
517 |
+
}
|
518 |
+
|
519 |
+
return _;
|
520 |
+
}
|
521 |
+
|
522 |
+
//Get current script and highlight
|
523 |
+
var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop();
|
524 |
+
|
525 |
+
if (script) {
|
526 |
+
_.filename = script.src;
|
527 |
+
|
528 |
+
if (!_.manual && !script.hasAttribute('data-manual')) {
|
529 |
+
if(document.readyState !== "loading") {
|
530 |
+
if (window.requestAnimationFrame) {
|
531 |
+
window.requestAnimationFrame(_.highlightAll);
|
532 |
+
} else {
|
533 |
+
window.setTimeout(_.highlightAll, 16);
|
534 |
+
}
|
535 |
+
}
|
536 |
+
else {
|
537 |
+
document.addEventListener('DOMContentLoaded', _.highlightAll);
|
538 |
+
}
|
539 |
+
}
|
540 |
+
}
|
541 |
+
|
542 |
+
return _;
|
543 |
+
|
544 |
+
})(_self);
|
545 |
+
|
546 |
+
if (typeof module !== 'undefined' && module.exports) {
|
547 |
+
module.exports = Prism;
|
548 |
+
}
|
549 |
+
|
550 |
+
// hack for components to work correctly in node.js
|
551 |
+
if (typeof global !== 'undefined') {
|
552 |
+
global.Prism = Prism;
|
553 |
+
}
|
554 |
+
;
|
555 |
+
Prism.languages.markup = {
|
556 |
+
'comment': /<!--[\s\S]*?-->/,
|
557 |
+
'prolog': /<\?[\s\S]+?\?>/,
|
558 |
+
'doctype': /<!DOCTYPE[\s\S]+?>/i,
|
559 |
+
'cdata': /<!\[CDATA\[[\s\S]*?]]>/i,
|
560 |
+
'tag': {
|
561 |
+
pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i,
|
562 |
+
greedy: true,
|
563 |
+
inside: {
|
564 |
+
'tag': {
|
565 |
+
pattern: /^<\/?[^\s>\/]+/i,
|
566 |
+
inside: {
|
567 |
+
'punctuation': /^<\/?/,
|
568 |
+
'namespace': /^[^\s>\/:]+:/
|
569 |
+
}
|
570 |
+
},
|
571 |
+
'attr-value': {
|
572 |
+
pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i,
|
573 |
+
inside: {
|
574 |
+
'punctuation': [
|
575 |
+
/^=/,
|
576 |
+
{
|
577 |
+
pattern: /^(\s*)["']|["']$/,
|
578 |
+
lookbehind: true
|
579 |
+
}
|
580 |
+
]
|
581 |
+
}
|
582 |
+
},
|
583 |
+
'punctuation': /\/?>/,
|
584 |
+
'attr-name': {
|
585 |
+
pattern: /[^\s>\/]+/,
|
586 |
+
inside: {
|
587 |
+
'namespace': /^[^\s>\/:]+:/
|
588 |
+
}
|
589 |
+
}
|
590 |
+
|
591 |
+
}
|
592 |
+
},
|
593 |
+
'entity': /&#?[\da-z]{1,8};/i
|
594 |
+
};
|
595 |
+
|
596 |
+
Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
|
597 |
+
Prism.languages.markup['entity'];
|
598 |
+
|
599 |
+
// Plugin to make entity title show the real entity, idea by Roman Komarov
|
600 |
+
Prism.hooks.add('wrap', function(env) {
|
601 |
+
|
602 |
+
if (env.type === 'entity') {
|
603 |
+
env.attributes['title'] = env.content.replace(/&/, '&');
|
604 |
+
}
|
605 |
+
});
|
606 |
+
|
607 |
+
Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
|
608 |
+
/**
|
609 |
+
* Adds an inlined language to markup.
|
610 |
+
*
|
611 |
+
* An example of an inlined language is CSS with `<style>` tags.
|
612 |
+
*
|
613 |
+
* @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
|
614 |
+
* case insensitive.
|
615 |
+
* @param {string} lang The language key.
|
616 |
+
* @example
|
617 |
+
* addInlined('style', 'css');
|
618 |
+
*/
|
619 |
+
value: function addInlined(tagName, lang) {
|
620 |
+
var includedCdataInside = {};
|
621 |
+
includedCdataInside['language-' + lang] = {
|
622 |
+
pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
|
623 |
+
lookbehind: true,
|
624 |
+
inside: Prism.languages[lang]
|
625 |
+
};
|
626 |
+
includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
|
627 |
+
|
628 |
+
var inside = {
|
629 |
+
'included-cdata': {
|
630 |
+
pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
|
631 |
+
inside: includedCdataInside
|
632 |
+
}
|
633 |
+
};
|
634 |
+
inside['language-' + lang] = {
|
635 |
+
pattern: /[\s\S]+/,
|
636 |
+
inside: Prism.languages[lang]
|
637 |
+
};
|
638 |
+
|
639 |
+
var def = {};
|
640 |
+
def[tagName] = {
|
641 |
+
pattern: RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[[\s\S]*?\]\]>\s*|[\s\S])*?(?=<\/__>)/.source.replace(/__/g, tagName), 'i'),
|
642 |
+
lookbehind: true,
|
643 |
+
greedy: true,
|
644 |
+
inside: inside
|
645 |
+
};
|
646 |
+
|
647 |
+
Prism.languages.insertBefore('markup', 'cdata', def);
|
648 |
+
}
|
649 |
+
});
|
650 |
+
|
651 |
+
Prism.languages.xml = Prism.languages.extend('markup', {});
|
652 |
+
Prism.languages.html = Prism.languages.markup;
|
653 |
+
Prism.languages.mathml = Prism.languages.markup;
|
654 |
+
Prism.languages.svg = Prism.languages.markup;
|
655 |
+
|
656 |
+
(function (Prism) {
|
657 |
+
|
658 |
+
var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;
|
659 |
+
|
660 |
+
Prism.languages.css = {
|
661 |
+
'comment': /\/\*[\s\S]*?\*\//,
|
662 |
+
'atrule': {
|
663 |
+
pattern: /@[\w-]+?[\s\S]*?(?:;|(?=\s*\{))/i,
|
664 |
+
inside: {
|
665 |
+
'rule': /@[\w-]+/
|
666 |
+
// See rest below
|
667 |
+
}
|
668 |
+
},
|
669 |
+
'url': RegExp('url\\((?:' + string.source + '|.*?)\\)', 'i'),
|
670 |
+
'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + ')*?(?=\\s*\\{)'),
|
671 |
+
'string': {
|
672 |
+
pattern: string,
|
673 |
+
greedy: true
|
674 |
+
},
|
675 |
+
'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
|
676 |
+
'important': /!important\b/i,
|
677 |
+
'function': /[-a-z0-9]+(?=\()/i,
|
678 |
+
'punctuation': /[(){};:,]/
|
679 |
+
};
|
680 |
+
|
681 |
+
Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
|
682 |
+
|
683 |
+
var markup = Prism.languages.markup;
|
684 |
+
if (markup) {
|
685 |
+
markup.tag.addInlined('style', 'css');
|
686 |
+
|
687 |
+
Prism.languages.insertBefore('inside', 'attr-value', {
|
688 |
+
'style-attr': {
|
689 |
+
pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
|
690 |
+
inside: {
|
691 |
+
'attr-name': {
|
692 |
+
pattern: /^\s*style/i,
|
693 |
+
inside: markup.tag.inside
|
694 |
+
},
|
695 |
+
'punctuation': /^\s*=\s*['"]|['"]\s*$/,
|
696 |
+
'attr-value': {
|
697 |
+
pattern: /.+/i,
|
698 |
+
inside: Prism.languages.css
|
699 |
+
}
|
700 |
+
},
|
701 |
+
alias: 'language-css'
|
702 |
+
}
|
703 |
+
}, markup.tag);
|
704 |
+
}
|
705 |
+
|
706 |
+
}(Prism));
|
707 |
+
|
708 |
+
Prism.languages.clike = {
|
709 |
+
'comment': [
|
710 |
+
{
|
711 |
+
pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
|
712 |
+
lookbehind: true
|
713 |
+
},
|
714 |
+
{
|
715 |
+
pattern: /(^|[^\\:])\/\/.*/,
|
716 |
+
lookbehind: true,
|
717 |
+
greedy: true
|
718 |
+
}
|
719 |
+
],
|
720 |
+
'string': {
|
721 |
+
pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
|
722 |
+
greedy: true
|
723 |
+
},
|
724 |
+
'class-name': {
|
725 |
+
pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,
|
726 |
+
lookbehind: true,
|
727 |
+
inside: {
|
728 |
+
punctuation: /[.\\]/
|
729 |
+
}
|
730 |
+
},
|
731 |
+
'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
|
732 |
+
'boolean': /\b(?:true|false)\b/,
|
733 |
+
'function': /\w+(?=\()/,
|
734 |
+
'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
|
735 |
+
'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
|
736 |
+
'punctuation': /[{}[\];(),.:]/
|
737 |
+
};
|
738 |
+
|
739 |
+
Prism.languages.javascript = Prism.languages.extend('clike', {
|
740 |
+
'class-name': [
|
741 |
+
Prism.languages.clike['class-name'],
|
742 |
+
{
|
743 |
+
pattern: /(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,
|
744 |
+
lookbehind: true
|
745 |
+
}
|
746 |
+
],
|
747 |
+
'keyword': [
|
748 |
+
{
|
749 |
+
pattern: /((?:^|})\s*)(?:catch|finally)\b/,
|
750 |
+
lookbehind: true
|
751 |
+
},
|
752 |
+
{
|
753 |
+
pattern: /(^|[^.])\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
|
754 |
+
lookbehind: true
|
755 |
+
},
|
756 |
+
],
|
757 |
+
'number': /\b(?:(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+)n?|\d+n|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,
|
758 |
+
// Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
|
759 |
+
'function': /[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
|
760 |
+
'operator': /-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/
|
761 |
+
});
|
762 |
+
|
763 |
+
Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/;
|
764 |
+
|
765 |
+
Prism.languages.insertBefore('javascript', 'keyword', {
|
766 |
+
'regex': {
|
767 |
+
pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,
|
768 |
+
lookbehind: true,
|
769 |
+
greedy: true
|
770 |
+
},
|
771 |
+
// This must be declared before keyword because we use "function" inside the look-forward
|
772 |
+
'function-variable': {
|
773 |
+
pattern: /[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,
|
774 |
+
alias: 'function'
|
775 |
+
},
|
776 |
+
'parameter': [
|
777 |
+
{
|
778 |
+
pattern: /(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,
|
779 |
+
lookbehind: true,
|
780 |
+
inside: Prism.languages.javascript
|
781 |
+
},
|
782 |
+
{
|
783 |
+
pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,
|
784 |
+
inside: Prism.languages.javascript
|
785 |
+
},
|
786 |
+
{
|
787 |
+
pattern: /(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,
|
788 |
+
lookbehind: true,
|
789 |
+
inside: Prism.languages.javascript
|
790 |
+
},
|
791 |
+
{
|
792 |
+
pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,
|
793 |
+
lookbehind: true,
|
794 |
+
inside: Prism.languages.javascript
|
795 |
+
}
|
796 |
+
],
|
797 |
+
'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
|
798 |
+
});
|
799 |
+
|
800 |
+
Prism.languages.insertBefore('javascript', 'string', {
|
801 |
+
'template-string': {
|
802 |
+
pattern: /`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,
|
803 |
+
greedy: true,
|
804 |
+
inside: {
|
805 |
+
'interpolation': {
|
806 |
+
pattern: /\${[^}]+}/,
|
807 |
+
inside: {
|
808 |
+
'interpolation-punctuation': {
|
809 |
+
pattern: /^\${|}$/,
|
810 |
+
alias: 'punctuation'
|
811 |
+
},
|
812 |
+
rest: Prism.languages.javascript
|
813 |
+
}
|
814 |
+
},
|
815 |
+
'string': /[\s\S]+/
|
816 |
+
}
|
817 |
+
}
|
818 |
+
});
|
819 |
+
|
820 |
+
if (Prism.languages.markup) {
|
821 |
+
Prism.languages.markup.tag.addInlined('script', 'javascript');
|
822 |
+
}
|
823 |
+
|
824 |
+
Prism.languages.js = Prism.languages.javascript;
|
825 |
+
|
826 |
+
(function (Prism) {
|
827 |
+
|
828 |
+
/**
|
829 |
+
* Returns the placeholder for the given language id and index.
|
830 |
+
*
|
831 |
+
* @param {string} language
|
832 |
+
* @param {string|number} index
|
833 |
+
* @returns {string}
|
834 |
+
*/
|
835 |
+
function getPlaceholder(language, index) {
|
836 |
+
return '___' + language.toUpperCase() + index + '___';
|
837 |
+
}
|
838 |
+
|
839 |
+
Object.defineProperties(Prism.languages['markup-templating'] = {}, {
|
840 |
+
buildPlaceholders: {
|
841 |
+
/**
|
842 |
+
* Tokenize all inline templating expressions matching `placeholderPattern`.
|
843 |
+
*
|
844 |
+
* If `replaceFilter` is provided, only matches of `placeholderPattern` for which `replaceFilter` returns
|
845 |
+
* `true` will be replaced.
|
846 |
+
*
|
847 |
+
* @param {object} env The environment of the `before-tokenize` hook.
|
848 |
+
* @param {string} language The language id.
|
849 |
+
* @param {RegExp} placeholderPattern The matches of this pattern will be replaced by placeholders.
|
850 |
+
* @param {(match: string) => boolean} [replaceFilter]
|
851 |
+
*/
|
852 |
+
value: function (env, language, placeholderPattern, replaceFilter) {
|
853 |
+
if (env.language !== language) {
|
854 |
+
return;
|
855 |
+
}
|
856 |
+
|
857 |
+
var tokenStack = env.tokenStack = [];
|
858 |
+
|
859 |
+
env.code = env.code.replace(placeholderPattern, function (match) {
|
860 |
+
if (typeof replaceFilter === 'function' && !replaceFilter(match)) {
|
861 |
+
return match;
|
862 |
+
}
|
863 |
+
var i = tokenStack.length;
|
864 |
+
var placeholder;
|
865 |
+
|
866 |
+
// Check for existing strings
|
867 |
+
while (env.code.indexOf(placeholder = getPlaceholder(language, i)) !== -1)
|
868 |
+
++i;
|
869 |
+
|
870 |
+
// Create a sparse array
|
871 |
+
tokenStack[i] = match;
|
872 |
+
|
873 |
+
return placeholder;
|
874 |
+
});
|
875 |
+
|
876 |
+
// Switch the grammar to markup
|
877 |
+
env.grammar = Prism.languages.markup;
|
878 |
+
}
|
879 |
+
},
|
880 |
+
tokenizePlaceholders: {
|
881 |
+
/**
|
882 |
+
* Replace placeholders with proper tokens after tokenizing.
|
883 |
+
*
|
884 |
+
* @param {object} env The environment of the `after-tokenize` hook.
|
885 |
+
* @param {string} language The language id.
|
886 |
+
*/
|
887 |
+
value: function (env, language) {
|
888 |
+
if (env.language !== language || !env.tokenStack) {
|
889 |
+
return;
|
890 |
+
}
|
891 |
+
|
892 |
+
// Switch the grammar back
|
893 |
+
env.grammar = Prism.languages[language];
|
894 |
+
|
895 |
+
var j = 0;
|
896 |
+
var keys = Object.keys(env.tokenStack);
|
897 |
+
|
898 |
+
function walkTokens(tokens) {
|
899 |
+
for (var i = 0; i < tokens.length; i++) {
|
900 |
+
// all placeholders are replaced already
|
901 |
+
if (j >= keys.length) {
|
902 |
+
break;
|
903 |
+
}
|
904 |
+
|
905 |
+
var token = tokens[i];
|
906 |
+
if (typeof token === 'string' || (token.content && typeof token.content === 'string')) {
|
907 |
+
var k = keys[j];
|
908 |
+
var t = env.tokenStack[k];
|
909 |
+
var s = typeof token === 'string' ? token : token.content;
|
910 |
+
var placeholder = getPlaceholder(language, k);
|
911 |
+
|
912 |
+
var index = s.indexOf(placeholder);
|
913 |
+
if (index > -1) {
|
914 |
+
++j;
|
915 |
+
|
916 |
+
var before = s.substring(0, index);
|
917 |
+
var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar), 'language-' + language, t);
|
918 |
+
var after = s.substring(index + placeholder.length);
|
919 |
+
|
920 |
+
var replacement = [];
|
921 |
+
if (before) {
|
922 |
+
replacement.push.apply(replacement, walkTokens([before]));
|
923 |
+
}
|
924 |
+
replacement.push(middle);
|
925 |
+
if (after) {
|
926 |
+
replacement.push.apply(replacement, walkTokens([after]));
|
927 |
+
}
|
928 |
+
|
929 |
+
if (typeof token === 'string') {
|
930 |
+
tokens.splice.apply(tokens, [i, 1].concat(replacement));
|
931 |
+
} else {
|
932 |
+
token.content = replacement;
|
933 |
+
}
|
934 |
+
}
|
935 |
+
} else if (token.content /* && typeof token.content !== 'string' */) {
|
936 |
+
walkTokens(token.content);
|
937 |
+
}
|
938 |
+
}
|
939 |
+
|
940 |
+
return tokens;
|
941 |
+
}
|
942 |
+
|
943 |
+
walkTokens(env.tokens);
|
944 |
+
}
|
945 |
+
}
|
946 |
+
});
|
947 |
+
|
948 |
+
}(Prism));
|
949 |
+
|
950 |
+
/**
|
951 |
+
* Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/
|
952 |
+
* Modified by Miles Johnson: http://milesj.me
|
953 |
+
*
|
954 |
+
* Supports the following:
|
955 |
+
* - Extends clike syntax
|
956 |
+
* - Support for PHP 5.3+ (namespaces, traits, generators, etc)
|
957 |
+
* - Smarter constant and function matching
|
958 |
+
*
|
959 |
+
* Adds the following new token classes:
|
960 |
+
* constant, delimiter, variable, function, package
|
961 |
+
*/
|
962 |
+
(function (Prism) {
|
963 |
+
Prism.languages.php = Prism.languages.extend('clike', {
|
964 |
+
'keyword': /\b(?:__halt_compiler|abstract|and|array|as|break|callable|case|catch|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exit|extends|final|finally|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|namespace|new|or|parent|print|private|protected|public|require|require_once|return|static|switch|throw|trait|try|unset|use|var|while|xor|yield)\b/i,
|
965 |
+
'boolean': {
|
966 |
+
pattern: /\b(?:false|true)\b/i,
|
967 |
+
alias: 'constant'
|
968 |
+
},
|
969 |
+
'constant': [
|
970 |
+
/\b[A-Z_][A-Z0-9_]*\b/,
|
971 |
+
/\b(?:null)\b/i,
|
972 |
+
],
|
973 |
+
'comment': {
|
974 |
+
pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
|
975 |
+
lookbehind: true
|
976 |
+
}
|
977 |
+
});
|
978 |
+
|
979 |
+
Prism.languages.insertBefore('php', 'string', {
|
980 |
+
'shell-comment': {
|
981 |
+
pattern: /(^|[^\\])#.*/,
|
982 |
+
lookbehind: true,
|
983 |
+
alias: 'comment'
|
984 |
+
}
|
985 |
+
});
|
986 |
+
|
987 |
+
Prism.languages.insertBefore('php', 'comment', {
|
988 |
+
'delimiter': {
|
989 |
+
pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i,
|
990 |
+
alias: 'important'
|
991 |
+
}
|
992 |
+
});
|
993 |
+
|
994 |
+
Prism.languages.insertBefore('php', 'keyword', {
|
995 |
+
'variable': /\$+(?:\w+\b|(?={))/i,
|
996 |
+
'package': {
|
997 |
+
pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
|
998 |
+
lookbehind: true,
|
999 |
+
inside: {
|
1000 |
+
punctuation: /\\/
|
1001 |
+
}
|
1002 |
+
}
|
1003 |
+
});
|
1004 |
+
|
1005 |
+
// Must be defined after the function pattern
|
1006 |
+
Prism.languages.insertBefore('php', 'operator', {
|
1007 |
+
'property': {
|
1008 |
+
pattern: /(->)[\w]+/,
|
1009 |
+
lookbehind: true
|
1010 |
+
}
|
1011 |
+
});
|
1012 |
+
|
1013 |
+
var string_interpolation = {
|
1014 |
+
pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/,
|
1015 |
+
lookbehind: true,
|
1016 |
+
inside: {
|
1017 |
+
rest: Prism.languages.php
|
1018 |
+
}
|
1019 |
+
};
|
1020 |
+
|
1021 |
+
Prism.languages.insertBefore('php', 'string', {
|
1022 |
+
'nowdoc-string': {
|
1023 |
+
pattern: /<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/,
|
1024 |
+
greedy: true,
|
1025 |
+
alias: 'string',
|
1026 |
+
inside: {
|
1027 |
+
'delimiter': {
|
1028 |
+
pattern: /^<<<'[^']+'|[a-z_]\w*;$/i,
|
1029 |
+
alias: 'symbol',
|
1030 |
+
inside: {
|
1031 |
+
'punctuation': /^<<<'?|[';]$/
|
1032 |
+
}
|
1033 |
+
}
|
1034 |
+
}
|
1035 |
+
},
|
1036 |
+
'heredoc-string': {
|
1037 |
+
pattern: /<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i,
|
1038 |
+
greedy: true,
|
1039 |
+
alias: 'string',
|
1040 |
+
inside: {
|
1041 |
+
'delimiter': {
|
1042 |
+
pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,
|
1043 |
+
alias: 'symbol',
|
1044 |
+
inside: {
|
1045 |
+
'punctuation': /^<<<"?|[";]$/
|
1046 |
+
}
|
1047 |
+
},
|
1048 |
+
'interpolation': string_interpolation // See below
|
1049 |
+
}
|
1050 |
+
},
|
1051 |
+
'single-quoted-string': {
|
1052 |
+
pattern: /'(?:\\[\s\S]|[^\\'])*'/,
|
1053 |
+
greedy: true,
|
1054 |
+
alias: 'string'
|
1055 |
+
},
|
1056 |
+
'double-quoted-string': {
|
1057 |
+
pattern: /"(?:\\[\s\S]|[^\\"])*"/,
|
1058 |
+
greedy: true,
|
1059 |
+
alias: 'string',
|
1060 |
+
inside: {
|
1061 |
+
'interpolation': string_interpolation // See below
|
1062 |
+
}
|
1063 |
+
}
|
1064 |
+
});
|
1065 |
+
// The different types of PHP strings "replace" the C-like standard string
|
1066 |
+
delete Prism.languages.php['string'];
|
1067 |
+
|
1068 |
+
Prism.hooks.add('before-tokenize', function(env) {
|
1069 |
+
if (!/<\?/.test(env.code)) {
|
1070 |
+
return;
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#)(?:[^?\n\r]|\?(?!>))*|\/\*[\s\S]*?(?:\*\/|$))*?(?:\?>|$)/ig;
|
1074 |
+
Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern);
|
1075 |
+
});
|
1076 |
+
|
1077 |
+
Prism.hooks.add('after-tokenize', function(env) {
|
1078 |
+
Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php');
|
1079 |
+
});
|
1080 |
+
|
1081 |
+
}(Prism));
|
1082 |
+
|
1083 |
+
(function () {
|
1084 |
+
|
1085 |
+
if (typeof self === 'undefined' || !self.Prism || !self.document) {
|
1086 |
+
return;
|
1087 |
+
}
|
1088 |
+
|
1089 |
+
/**
|
1090 |
+
* Plugin name which is used as a class name for <pre> which is activating the plugin
|
1091 |
+
* @type {String}
|
1092 |
+
*/
|
1093 |
+
var PLUGIN_NAME = 'line-numbers';
|
1094 |
+
|
1095 |
+
/**
|
1096 |
+
* Regular expression used for determining line breaks
|
1097 |
+
* @type {RegExp}
|
1098 |
+
*/
|
1099 |
+
var NEW_LINE_EXP = /\n(?!$)/g;
|
1100 |
+
|
1101 |
+
/**
|
1102 |
+
* Resizes line numbers spans according to height of line of code
|
1103 |
+
* @param {Element} element <pre> element
|
1104 |
+
*/
|
1105 |
+
var _resizeElement = function (element) {
|
1106 |
+
var codeStyles = getStyles(element);
|
1107 |
+
var whiteSpace = codeStyles['white-space'];
|
1108 |
+
|
1109 |
+
if (whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line') {
|
1110 |
+
var codeElement = element.querySelector('code');
|
1111 |
+
var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
|
1112 |
+
var lineNumberSizer = element.querySelector('.line-numbers-sizer');
|
1113 |
+
var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
|
1114 |
+
|
1115 |
+
if (!lineNumberSizer) {
|
1116 |
+
lineNumberSizer = document.createElement('span');
|
1117 |
+
lineNumberSizer.className = 'line-numbers-sizer';
|
1118 |
+
|
1119 |
+
codeElement.appendChild(lineNumberSizer);
|
1120 |
+
}
|
1121 |
+
|
1122 |
+
lineNumberSizer.style.display = 'block';
|
1123 |
+
|
1124 |
+
codeLines.forEach(function (line, lineNumber) {
|
1125 |
+
lineNumberSizer.textContent = line || '\n';
|
1126 |
+
var lineSize = lineNumberSizer.getBoundingClientRect().height;
|
1127 |
+
lineNumbersWrapper.children[lineNumber].style.height = lineSize + 'px';
|
1128 |
+
});
|
1129 |
+
|
1130 |
+
lineNumberSizer.textContent = '';
|
1131 |
+
lineNumberSizer.style.display = 'none';
|
1132 |
+
}
|
1133 |
+
};
|
1134 |
+
|
1135 |
+
/**
|
1136 |
+
* Returns style declarations for the element
|
1137 |
+
* @param {Element} element
|
1138 |
+
*/
|
1139 |
+
var getStyles = function (element) {
|
1140 |
+
if (!element) {
|
1141 |
+
return null;
|
1142 |
+
}
|
1143 |
+
|
1144 |
+
return window.getComputedStyle ? getComputedStyle(element) : (element.currentStyle || null);
|
1145 |
+
};
|
1146 |
+
|
1147 |
+
window.addEventListener('resize', function () {
|
1148 |
+
Array.prototype.forEach.call(document.querySelectorAll('pre.' + PLUGIN_NAME), _resizeElement);
|
1149 |
+
});
|
1150 |
+
|
1151 |
+
Prism.hooks.add('complete', function (env) {
|
1152 |
+
if (!env.code) {
|
1153 |
+
return;
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
var code = env.element;
|
1157 |
+
var pre = code.parentNode;
|
1158 |
+
|
1159 |
+
// works only for <code> wrapped inside <pre> (not inline)
|
1160 |
+
if (!pre || !/pre/i.test(pre.nodeName)) {
|
1161 |
+
return;
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
// Abort if line numbers already exists
|
1165 |
+
if (code.querySelector('.line-numbers-rows')) {
|
1166 |
+
return;
|
1167 |
+
}
|
1168 |
+
|
1169 |
+
var addLineNumbers = false;
|
1170 |
+
var lineNumbersRegex = /(?:^|\s)line-numbers(?:\s|$)/;
|
1171 |
+
|
1172 |
+
for (var element = code; element; element = element.parentNode) {
|
1173 |
+
if (lineNumbersRegex.test(element.className)) {
|
1174 |
+
addLineNumbers = true;
|
1175 |
+
break;
|
1176 |
+
}
|
1177 |
+
}
|
1178 |
+
|
1179 |
+
// only add line numbers if <code> or one of its ancestors has the `line-numbers` class
|
1180 |
+
if (!addLineNumbers) {
|
1181 |
+
return;
|
1182 |
+
}
|
1183 |
+
|
1184 |
+
// Remove the class 'line-numbers' from the <code>
|
1185 |
+
code.className = code.className.replace(lineNumbersRegex, ' ');
|
1186 |
+
// Add the class 'line-numbers' to the <pre>
|
1187 |
+
if (!lineNumbersRegex.test(pre.className)) {
|
1188 |
+
pre.className += ' line-numbers';
|
1189 |
+
}
|
1190 |
+
|
1191 |
+
var match = env.code.match(NEW_LINE_EXP);
|
1192 |
+
var linesNum = match ? match.length + 1 : 1;
|
1193 |
+
var lineNumbersWrapper;
|
1194 |
+
|
1195 |
+
var lines = new Array(linesNum + 1).join('<span></span>');
|
1196 |
+
|
1197 |
+
lineNumbersWrapper = document.createElement('span');
|
1198 |
+
lineNumbersWrapper.setAttribute('aria-hidden', 'true');
|
1199 |
+
lineNumbersWrapper.className = 'line-numbers-rows';
|
1200 |
+
lineNumbersWrapper.innerHTML = lines;
|
1201 |
+
|
1202 |
+
if (pre.hasAttribute('data-start')) {
|
1203 |
+
pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
|
1204 |
+
}
|
1205 |
+
|
1206 |
+
env.element.appendChild(lineNumbersWrapper);
|
1207 |
+
|
1208 |
+
_resizeElement(pre);
|
1209 |
+
|
1210 |
+
Prism.hooks.run('line-numbers', env);
|
1211 |
+
});
|
1212 |
+
|
1213 |
+
Prism.hooks.add('line-numbers', function (env) {
|
1214 |
+
env.plugins = env.plugins || {};
|
1215 |
+
env.plugins.lineNumbers = true;
|
1216 |
+
});
|
1217 |
+
|
1218 |
+
/**
|
1219 |
+
* Global exports
|
1220 |
+
*/
|
1221 |
+
Prism.plugins.lineNumbers = {
|
1222 |
+
/**
|
1223 |
+
* Get node for provided line number
|
1224 |
+
* @param {Element} element pre element
|
1225 |
+
* @param {Number} number line number
|
1226 |
+
* @return {Element|undefined}
|
1227 |
+
*/
|
1228 |
+
getLine: function (element, number) {
|
1229 |
+
if (element.tagName !== 'PRE' || !element.classList.contains(PLUGIN_NAME)) {
|
1230 |
+
return;
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
var lineNumberRows = element.querySelector('.line-numbers-rows');
|
1234 |
+
var lineNumberStart = parseInt(element.getAttribute('data-start'), 10) || 1;
|
1235 |
+
var lineNumberEnd = lineNumberStart + (lineNumberRows.children.length - 1);
|
1236 |
+
|
1237 |
+
if (number < lineNumberStart) {
|
1238 |
+
number = lineNumberStart;
|
1239 |
+
}
|
1240 |
+
if (number > lineNumberEnd) {
|
1241 |
+
number = lineNumberEnd;
|
1242 |
+
}
|
1243 |
+
|
1244 |
+
var lineIndex = number - lineNumberStart;
|
1245 |
+
|
1246 |
+
return lineNumberRows.children[lineIndex];
|
1247 |
+
}
|
1248 |
+
};
|
1249 |
+
|
1250 |
+
}());
|
1251 |
+
|
1252 |
+
(function (self, document) {
|
1253 |
+
|
1254 |
+
if (typeof self === 'undefined' || !self.Prism || !self.document || !document.createRange) {
|
1255 |
+
return;
|
1256 |
+
}
|
1257 |
+
|
1258 |
+
Prism.plugins.KeepMarkup = true;
|
1259 |
+
|
1260 |
+
Prism.hooks.add('before-highlight', function (env) {
|
1261 |
+
if (!env.element.children.length) {
|
1262 |
+
return;
|
1263 |
+
}
|
1264 |
+
|
1265 |
+
var pos = 0;
|
1266 |
+
var data = [];
|
1267 |
+
var f = function (elt, baseNode) {
|
1268 |
+
var o = {};
|
1269 |
+
if (!baseNode) {
|
1270 |
+
// Clone the original tag to keep all attributes
|
1271 |
+
o.clone = elt.cloneNode(false);
|
1272 |
+
o.posOpen = pos;
|
1273 |
+
data.push(o);
|
1274 |
+
}
|
1275 |
+
for (var i = 0, l = elt.childNodes.length; i < l; i++) {
|
1276 |
+
var child = elt.childNodes[i];
|
1277 |
+
if (child.nodeType === 1) { // element
|
1278 |
+
f(child);
|
1279 |
+
} else if(child.nodeType === 3) { // text
|
1280 |
+
pos += child.data.length;
|
1281 |
+
}
|
1282 |
+
}
|
1283 |
+
if (!baseNode) {
|
1284 |
+
o.posClose = pos;
|
1285 |
+
}
|
1286 |
+
};
|
1287 |
+
f(env.element, true);
|
1288 |
+
|
1289 |
+
if (data && data.length) {
|
1290 |
+
// data is an array of all existing tags
|
1291 |
+
env.keepMarkup = data;
|
1292 |
+
}
|
1293 |
+
});
|
1294 |
+
|
1295 |
+
Prism.hooks.add('after-highlight', function (env) {
|
1296 |
+
if(env.keepMarkup && env.keepMarkup.length) {
|
1297 |
+
|
1298 |
+
var walk = function (elt, nodeState) {
|
1299 |
+
for (var i = 0, l = elt.childNodes.length; i < l; i++) {
|
1300 |
+
|
1301 |
+
var child = elt.childNodes[i];
|
1302 |
+
|
1303 |
+
if (child.nodeType === 1) { // element
|
1304 |
+
if (!walk(child, nodeState)) {
|
1305 |
+
return false;
|
1306 |
+
}
|
1307 |
+
|
1308 |
+
} else if (child.nodeType === 3) { // text
|
1309 |
+
if(!nodeState.nodeStart && nodeState.pos + child.data.length > nodeState.node.posOpen) {
|
1310 |
+
// We found the start position
|
1311 |
+
nodeState.nodeStart = child;
|
1312 |
+
nodeState.nodeStartPos = nodeState.node.posOpen - nodeState.pos;
|
1313 |
+
}
|
1314 |
+
if(nodeState.nodeStart && nodeState.pos + child.data.length >= nodeState.node.posClose) {
|
1315 |
+
// We found the end position
|
1316 |
+
nodeState.nodeEnd = child;
|
1317 |
+
nodeState.nodeEndPos = nodeState.node.posClose - nodeState.pos;
|
1318 |
+
}
|
1319 |
+
|
1320 |
+
nodeState.pos += child.data.length;
|
1321 |
+
}
|
1322 |
+
|
1323 |
+
if (nodeState.nodeStart && nodeState.nodeEnd) {
|
1324 |
+
// Select the range and wrap it with the clone
|
1325 |
+
var range = document.createRange();
|
1326 |
+
range.setStart(nodeState.nodeStart, nodeState.nodeStartPos);
|
1327 |
+
range.setEnd(nodeState.nodeEnd, nodeState.nodeEndPos);
|
1328 |
+
nodeState.node.clone.appendChild(range.extractContents());
|
1329 |
+
range.insertNode(nodeState.node.clone);
|
1330 |
+
range.detach();
|
1331 |
+
|
1332 |
+
// Process is over
|
1333 |
+
return false;
|
1334 |
+
}
|
1335 |
+
}
|
1336 |
+
return true;
|
1337 |
+
};
|
1338 |
+
|
1339 |
+
// For each tag, we walk the DOM to reinsert it
|
1340 |
+
env.keepMarkup.forEach(function (node) {
|
1341 |
+
walk(env.element, {
|
1342 |
+
node: node,
|
1343 |
+
pos: 0
|
1344 |
+
});
|
1345 |
+
});
|
1346 |
+
// Store new highlightedCode for later hooks calls
|
1347 |
+
env.highlightedCode = env.element.innerHTML;
|
1348 |
+
}
|
1349 |
+
});
|
1350 |
+
}(self, document));
|
app/module/scan/js/script.js
CHANGED
@@ -135,11 +135,8 @@ jQuery(function ($) {
|
|
135 |
current_issue = null;
|
136 |
var parent = form.closest('.source-code');
|
137 |
parent.html(data.data.html);
|
138 |
-
|
139 |
-
// hljs.highlightBlock(parent.find('pre code'));
|
140 |
parent.find('pre code').each(function (i, block) {
|
141 |
-
|
142 |
-
hljs.lineNumbersBlock(block);
|
143 |
});
|
144 |
} else {
|
145 |
Defender.showNotification('error', data.data.message);
|
@@ -190,7 +187,7 @@ jQuery(function ($) {
|
|
190 |
}).change();
|
191 |
|
192 |
//bulk
|
193 |
-
$('
|
194 |
$('.scan-chk').prop('checked', $(this).prop('checked'));
|
195 |
});
|
196 |
$('select[name="bulk"]').change(function () {
|
@@ -261,10 +258,10 @@ WDScan.formHandler = function () {
|
|
261 |
}
|
262 |
|
263 |
WDScan.formatCode = function () {
|
264 |
-
jQuery('pre code').each(function (i, block) {
|
265 |
-
|
266 |
-
|
267 |
-
});
|
268 |
}
|
269 |
|
270 |
//Refresh file issues counts
|
@@ -292,22 +289,14 @@ WDScan.initAppear = function () {
|
|
292 |
}
|
293 |
|
294 |
WDScan.showNextIssue = function () {
|
295 |
-
jQuery('body').on('click', '
|
|
|
|
|
296 |
var parent = jQuery(this).closest('.sui-box').find('.inner-sourcecode').first();
|
297 |
-
var
|
298 |
-
|
299 |
-
|
300 |
-
}
|
301 |
-
if (current_issue === null) {
|
302 |
-
current_issue = 0;
|
303 |
-
} else {
|
304 |
-
current_issue = current_issue + 1;
|
305 |
-
if (issues[current_issue] === undefined) {
|
306 |
-
current_issue = 0;
|
307 |
-
}
|
308 |
-
}
|
309 |
-
var pos = jQuery(issues[current_issue]).position();
|
310 |
-
parent.scrollTop(pos.top);
|
311 |
})
|
312 |
}
|
313 |
|
135 |
current_issue = null;
|
136 |
var parent = form.closest('.source-code');
|
137 |
parent.html(data.data.html);
|
|
|
|
|
138 |
parent.find('pre code').each(function (i, block) {
|
139 |
+
Prism.highlightElement(block);
|
|
|
140 |
});
|
141 |
} else {
|
142 |
Defender.showNotification('error', data.data.message);
|
187 |
}).change();
|
188 |
|
189 |
//bulk
|
190 |
+
$('.apply-all').click(function () {
|
191 |
$('.scan-chk').prop('checked', $(this).prop('checked'));
|
192 |
});
|
193 |
$('select[name="bulk"]').change(function () {
|
258 |
}
|
259 |
|
260 |
WDScan.formatCode = function () {
|
261 |
+
// jQuery('pre code').each(function (i, block) {
|
262 |
+
// hljs.highlightBlock(block);
|
263 |
+
// hljs.lineNumbersBlock(block);
|
264 |
+
// });
|
265 |
}
|
266 |
|
267 |
//Refresh file issues counts
|
289 |
}
|
290 |
|
291 |
WDScan.showNextIssue = function () {
|
292 |
+
jQuery('body').on('click', '.nav-issue', function (e) {
|
293 |
+
e.preventDefault();
|
294 |
+
var line = jQuery(this).data('line');
|
295 |
var parent = jQuery(this).closest('.sui-box').find('.inner-sourcecode').first();
|
296 |
+
var curr = jQuery(Prism.plugins.lineNumbers.getLine(parent.get(0), line));
|
297 |
+
curr.get(0).scrollIntoView({
|
298 |
+
block: 'center'
|
299 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
})
|
301 |
}
|
302 |
|
app/module/scan/model/settings.php
CHANGED
@@ -11,6 +11,7 @@ use Hammer\Queue\Queue;
|
|
11 |
use WP_Defender\Behavior\Utils;
|
12 |
use WP_Defender\Module\Scan\Behavior\Core_Scan;
|
13 |
use WP_Defender\Module\Scan\Behavior\Pro\Content_Scan;
|
|
|
14 |
use WP_Defender\Module\Scan\Behavior\Pro\MD5_Scan;
|
15 |
use WP_Defender\Module\Scan\Behavior\Pro\Vuln_Scan;
|
16 |
use WP_Defender\Module\Scan\Component\Scan_Api;
|
@@ -141,7 +142,7 @@ Stay safe,
|
|
141 |
WP Defender
|
142 |
Official WPMU DEV Superhero', "defender-security" );
|
143 |
//call parent to load stored
|
144 |
-
if ( is_admin() || is_network_admin() && current_user_can( 'manage_options' ) ) {
|
145 |
$user = wp_get_current_user();
|
146 |
if ( is_object( $user ) ) {
|
147 |
$this->receipts[] = array(
|
11 |
use WP_Defender\Behavior\Utils;
|
12 |
use WP_Defender\Module\Scan\Behavior\Core_Scan;
|
13 |
use WP_Defender\Module\Scan\Behavior\Pro\Content_Scan;
|
14 |
+
use WP_Defender\Module\Scan\Behavior\Pro\Content_Scan2;
|
15 |
use WP_Defender\Module\Scan\Behavior\Pro\MD5_Scan;
|
16 |
use WP_Defender\Module\Scan\Behavior\Pro\Vuln_Scan;
|
17 |
use WP_Defender\Module\Scan\Component\Scan_Api;
|
142 |
WP Defender
|
143 |
Official WPMU DEV Superhero', "defender-security" );
|
144 |
//call parent to load stored
|
145 |
+
if ( ( is_admin() || is_network_admin() ) && current_user_can( 'manage_options' ) ) {
|
146 |
$user = wp_get_current_user();
|
147 |
if ( is_object( $user ) ) {
|
148 |
$this->receipts[] = array(
|
app/module/scan/view/automation.php
CHANGED
@@ -30,8 +30,8 @@
|
|
30 |
<p class="sui-p-small">
|
31 |
<?php _e( "By default, we will only notify the recipients below when there is an issue from your file scan. Enable this option to send emails even when no issues are detected. ", "defender-security" ) ?>
|
32 |
</p>
|
|
|
33 |
<label class="sui-toggle">
|
34 |
-
<input type="hidden" name="always_send" value="0"/>
|
35 |
<input role="presentation" type="checkbox" name="always_send"
|
36 |
class="toggle-checkbox"
|
37 |
id="always_send" value="1"
|
30 |
<p class="sui-p-small">
|
31 |
<?php _e( "By default, we will only notify the recipients below when there is an issue from your file scan. Enable this option to send emails even when no issues are detected. ", "defender-security" ) ?>
|
32 |
</p>
|
33 |
+
<input type="hidden" name="always_send" value="0"/>
|
34 |
<label class="sui-toggle">
|
|
|
35 |
<input role="presentation" type="checkbox" name="always_send"
|
36 |
class="toggle-checkbox"
|
37 |
id="always_send" value="1"
|
app/module/scan/view/ignored.php
CHANGED
@@ -17,7 +17,7 @@
|
|
17 |
} else {
|
18 |
?>
|
19 |
<div class="sui-notice sui-notice-info">
|
20 |
-
<p> <?php _e( "You haven't
|
21 |
</div>
|
22 |
<?php
|
23 |
}
|
17 |
} else {
|
18 |
?>
|
19 |
<div class="sui-notice sui-notice-info">
|
20 |
+
<p> <?php _e( "You haven't chosen to ignore any suspicious files yet. Ignored files appear here and can be restored at any time", "defender-security" ) ?> </p>
|
21 |
</div>
|
22 |
<?php
|
23 |
}
|
app/module/scan/view/issues.php
CHANGED
@@ -26,8 +26,8 @@ $table->prepare_items();
|
|
26 |
<?php selected( 'vuln', \Hammer\Helper\HTTP_Helper::retrieve_get( 'type' ) ) ?>
|
27 |
value="vuln"><?php _e( "Plugins/Themes Vulnerability", "defender-security" ) ?></option>
|
28 |
<option
|
29 |
-
<?php selected( '
|
30 |
-
value="
|
31 |
</select>
|
32 |
</div>
|
33 |
</div>
|
26 |
<?php selected( 'vuln', \Hammer\Helper\HTTP_Helper::retrieve_get( 'type' ) ) ?>
|
27 |
value="vuln"><?php _e( "Plugins/Themes Vulnerability", "defender-security" ) ?></option>
|
28 |
<option
|
29 |
+
<?php selected( 'content', \Hammer\Helper\HTTP_Helper::retrieve_get( 'type' ) ) ?>
|
30 |
+
value="content"><?php _e( "Suspicious code", "defender-security" ) ?></option>
|
31 |
</select>
|
32 |
</div>
|
33 |
</div>
|
app/module/scan/view/layouts/layout.php
CHANGED
@@ -2,6 +2,12 @@
|
|
2 |
$core = $model->getCount( 'core' );
|
3 |
$vuln = $model->getCount( 'vuln' );
|
4 |
$content = $model->getCount( 'content' );
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
?>
|
6 |
<div class="sui-wrap <?php echo \WP_Defender\Behavior\Utils::instance()->maybeHighContrast() ?>">
|
7 |
<div id="wp-defender" class="wp-defender">
|
@@ -21,25 +27,32 @@ $content = $model->getCount( 'content' );
|
|
21 |
</button>
|
22 |
</form>
|
23 |
</div>
|
24 |
-
|
25 |
<div class="sui-actions-right">
|
26 |
<div class="sui-actions-right">
|
27 |
-
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender
|
|
|
28 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
29 |
</a>
|
30 |
</div>
|
31 |
</div>
|
32 |
-
|
33 |
</div>
|
34 |
-
<div class="sui-box sui-summary <?php echo \WP_Defender\Behavior\Utils::instance()->getSummaryClass()?>">
|
35 |
<div class="sui-summary-image-space" aria-hidden="true"></div>
|
36 |
<div class="sui-summary-segment">
|
37 |
<div class="sui-summary-details">
|
38 |
<span class="sui-summary-large issues"><?php echo $countAll ?></span>
|
39 |
<?php if ( $countAll > 0 ): ?>
|
40 |
-
<
|
|
|
|
|
|
|
41 |
<?php else: ?>
|
|
|
|
|
42 |
<i class="sui-icon-check-tick sui-success" aria-hidden="true"></i>
|
|
|
43 |
<?php endif; ?>
|
44 |
<span class="sui-summary-sub"><?php _e( "File scanning issues", "defender-security" ) ?></span>
|
45 |
|
@@ -110,7 +123,7 @@ $content = $model->getCount( 'content' );
|
|
110 |
<?php echo $contents ?>
|
111 |
</div>
|
112 |
</div>
|
113 |
-
<?php if ( wp_defender()->changeFooter
|
114 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
115 |
<?php else: ?>
|
116 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
2 |
$core = $model->getCount( 'core' );
|
3 |
$vuln = $model->getCount( 'vuln' );
|
4 |
$content = $model->getCount( 'content' );
|
5 |
+
$tooltips = __( "You don't have any outstanding security issues, nice work!", "defender-security" );
|
6 |
+
if ( $countAll == 1 ) {
|
7 |
+
$tooltips = __( "We've detected a potential security risk in your file system. We recommend you take a look and action a fix, or ignore the file if it's harmless.", "defender-security" );
|
8 |
+
} elseif ( $countAll > 1 ) {
|
9 |
+
$tooltips = sprintf( __( "You have %s potential security risks in your file system. We recommend you take a look and action fixes, or ignore the issues if they are harmless." ), $countAll );
|
10 |
+
}
|
11 |
?>
|
12 |
<div class="sui-wrap <?php echo \WP_Defender\Behavior\Utils::instance()->maybeHighContrast() ?>">
|
13 |
<div id="wp-defender" class="wp-defender">
|
27 |
</button>
|
28 |
</form>
|
29 |
</div>
|
30 |
+
<?php if ( wp_defender()->hideDocLinks === false ): ?>
|
31 |
<div class="sui-actions-right">
|
32 |
<div class="sui-actions-right">
|
33 |
+
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/#security-scans" target="_blank"
|
34 |
+
class="sui-button sui-button-ghost">
|
35 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
36 |
</a>
|
37 |
</div>
|
38 |
</div>
|
39 |
+
<?php endif; ?>
|
40 |
</div>
|
41 |
+
<div class="sui-box sui-summary <?php echo \WP_Defender\Behavior\Utils::instance()->getSummaryClass() ?>">
|
42 |
<div class="sui-summary-image-space" aria-hidden="true"></div>
|
43 |
<div class="sui-summary-segment">
|
44 |
<div class="sui-summary-details">
|
45 |
<span class="sui-summary-large issues"><?php echo $countAll ?></span>
|
46 |
<?php if ( $countAll > 0 ): ?>
|
47 |
+
<span class="sui-tooltip sui-tooltip-top-left sui-tooltip-constrained"
|
48 |
+
data-tooltip="<?php echo $tooltips ?>">
|
49 |
+
<i aria-hidden="true" class="sui-icon-info sui-warning"></i>
|
50 |
+
</span>
|
51 |
<?php else: ?>
|
52 |
+
<span class="sui-tooltip sui-tooltip-top-left sui-tooltip-constrained"
|
53 |
+
data-tooltip="<?php echo $tooltips ?>">
|
54 |
<i class="sui-icon-check-tick sui-success" aria-hidden="true"></i>
|
55 |
+
</span>
|
56 |
<?php endif; ?>
|
57 |
<span class="sui-summary-sub"><?php _e( "File scanning issues", "defender-security" ) ?></span>
|
58 |
|
123 |
<?php echo $contents ?>
|
124 |
</div>
|
125 |
</div>
|
126 |
+
<?php if ( wp_defender()->changeFooter ): ?>
|
127 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
128 |
<?php else: ?>
|
129 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
app/module/scan/view/notification.php
CHANGED
@@ -32,8 +32,8 @@
|
|
32 |
<p class="sui-p-small">
|
33 |
<?php _e( "By default, we will only notify the recipients below when there is an issue from your file scan. Enable this option to send emails even when no issues are detected. ", "defender-security" ) ?>
|
34 |
</p>
|
|
|
35 |
<label class="sui-toggle">
|
36 |
-
<input type="hidden" name="always_send" value="0"/>
|
37 |
<input role="presentation" type="checkbox" name="alwaysSendNotification"
|
38 |
class="toggle-checkbox"
|
39 |
id="alwaysSendNotification" value="1"
|
@@ -118,6 +118,19 @@
|
|
118 |
<div class="sui-row">
|
119 |
<div class="sui-col">
|
120 |
<div class="sui-form-field">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
<textarea rows="12" class="sui-form-control"
|
122 |
name="email_all_ok"><?php echo $setting->email_all_ok ?></textarea>
|
123 |
</div>
|
@@ -178,6 +191,19 @@
|
|
178 |
<div class="sui-row">
|
179 |
<div class="sui-col">
|
180 |
<div class="sui-form-field">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
<textarea rows="12" class="sui-form-control"
|
182 |
name="email_has_issue"><?php echo $setting->email_has_issue ?></textarea>
|
183 |
</div>
|
32 |
<p class="sui-p-small">
|
33 |
<?php _e( "By default, we will only notify the recipients below when there is an issue from your file scan. Enable this option to send emails even when no issues are detected. ", "defender-security" ) ?>
|
34 |
</p>
|
35 |
+
<input type="hidden" name="always_send" value="0"/>
|
36 |
<label class="sui-toggle">
|
|
|
37 |
<input role="presentation" type="checkbox" name="alwaysSendNotification"
|
38 |
class="toggle-checkbox"
|
39 |
id="alwaysSendNotification" value="1"
|
118 |
<div class="sui-row">
|
119 |
<div class="sui-col">
|
120 |
<div class="sui-form-field">
|
121 |
+
<label class="sui-label">
|
122 |
+
<?php _e( "Subject", "defender-security" ) ?>
|
123 |
+
</label>
|
124 |
+
<input type="text" class="sui-form-control" name="email_subject" value="<?php echo $setting->email_subject ?>">
|
125 |
+
</div>
|
126 |
+
</div>
|
127 |
+
</div>
|
128 |
+
<div class="sui-row">
|
129 |
+
<div class="sui-col">
|
130 |
+
<div class="sui-form-field">
|
131 |
+
<label class="sui-label">
|
132 |
+
<?php _e( "Body", "defender-security" ) ?>
|
133 |
+
</label>
|
134 |
<textarea rows="12" class="sui-form-control"
|
135 |
name="email_all_ok"><?php echo $setting->email_all_ok ?></textarea>
|
136 |
</div>
|
191 |
<div class="sui-row">
|
192 |
<div class="sui-col">
|
193 |
<div class="sui-form-field">
|
194 |
+
<label class="sui-label">
|
195 |
+
<?php _e( "Subject", "defender-security" ) ?>
|
196 |
+
</label>
|
197 |
+
<input type="text" class="sui-form-control" name="email_subject" value="<?php echo $setting->email_subject ?>">
|
198 |
+
</div>
|
199 |
+
</div>
|
200 |
+
</div>
|
201 |
+
<div class="sui-row">
|
202 |
+
<div class="sui-col">
|
203 |
+
<div class="sui-form-field">
|
204 |
+
<label class="sui-label">
|
205 |
+
<?php _e( "Subject", "defender-security" ) ?>
|
206 |
+
</label>
|
207 |
<textarea rows="12" class="sui-form-control"
|
208 |
name="email_has_issue"><?php echo $setting->email_has_issue ?></textarea>
|
209 |
</div>
|
app/module/scan/view/setting-free.php
CHANGED
@@ -16,8 +16,8 @@
|
|
16 |
|
17 |
<div class="sui-box-settings-col-2">
|
18 |
<div class="sui-form-field">
|
|
|
19 |
<label class="sui-toggle">
|
20 |
-
<input type="hidden" name="scan_core" value="0"/>
|
21 |
<input role="presentation" type="checkbox" name="scan_core" class="toggle-checkbox"
|
22 |
id="core-scan" value="1"
|
23 |
<?php checked( true, $setting->scan_core ) ?>/>
|
16 |
|
17 |
<div class="sui-box-settings-col-2">
|
18 |
<div class="sui-form-field">
|
19 |
+
<input type="hidden" name="scan_core" value="0"/>
|
20 |
<label class="sui-toggle">
|
|
|
21 |
<input role="presentation" type="checkbox" name="scan_core" class="toggle-checkbox"
|
22 |
id="core-scan" value="1"
|
23 |
<?php checked( true, $setting->scan_core ) ?>/>
|
app/module/scan/view/setting.php
CHANGED
@@ -16,9 +16,9 @@
|
|
16 |
|
17 |
<div class="sui-box-settings-col-2">
|
18 |
<div class="sui-form-field">
|
|
|
19 |
<label class="sui-toggle">
|
20 |
-
<input type="
|
21 |
-
<input role="presentation" type="checkbox" name="scan_core" class="toggle-checkbox"
|
22 |
id="core-scan" value="1"
|
23 |
<?php checked( true, $setting->scan_core ) ?>/>
|
24 |
<span class="sui-toggle-slider"></span>
|
@@ -31,11 +31,11 @@
|
|
31 |
</p>
|
32 |
</div>
|
33 |
<div class="sui-form-field">
|
|
|
34 |
<label class="sui-toggle">
|
35 |
-
<input type="
|
36 |
-
<input role="presentation" type="checkbox" class="toggle-checkbox" name="scan_vuln"
|
37 |
value="1"
|
38 |
-
id="
|
39 |
<span class="sui-toggle-slider"></span>
|
40 |
</label>
|
41 |
<label for="scan_vuln" class="sui-toggle-label">
|
@@ -46,11 +46,11 @@
|
|
46 |
</p>
|
47 |
</div>
|
48 |
<div class="sui-form-field">
|
|
|
49 |
<label class="sui-toggle">
|
50 |
-
<input type="hidden" name="scan_content" value="0"/>
|
51 |
<input role="presentation" type="checkbox" class="toggle-checkbox" name="scan_content"
|
52 |
value="1"
|
53 |
-
id="
|
54 |
<span class="sui-toggle-slider"></span>
|
55 |
</label>
|
56 |
<label for="scan_content" class="sui-toggle-label">
|
16 |
|
17 |
<div class="sui-box-settings-col-2">
|
18 |
<div class="sui-form-field">
|
19 |
+
<input type="hidden" name="scan_core" value="0"/>
|
20 |
<label class="sui-toggle">
|
21 |
+
<input type="checkbox" name="scan_core" class="toggle-checkbox"
|
|
|
22 |
id="core-scan" value="1"
|
23 |
<?php checked( true, $setting->scan_core ) ?>/>
|
24 |
<span class="sui-toggle-slider"></span>
|
31 |
</p>
|
32 |
</div>
|
33 |
<div class="sui-form-field">
|
34 |
+
<input type="hidden" name="scan_vuln" value="0"/>
|
35 |
<label class="sui-toggle">
|
36 |
+
<input type="checkbox" class="toggle-checkbox" name="scan_vuln"
|
|
|
37 |
value="1"
|
38 |
+
id="scan_vuln" <?php checked( true, $setting->scan_vuln ) ?>/>
|
39 |
<span class="sui-toggle-slider"></span>
|
40 |
</label>
|
41 |
<label for="scan_vuln" class="sui-toggle-label">
|
46 |
</p>
|
47 |
</div>
|
48 |
<div class="sui-form-field">
|
49 |
+
<input type="hidden" name="scan_content" value="0"/>
|
50 |
<label class="sui-toggle">
|
|
|
51 |
<input role="presentation" type="checkbox" class="toggle-checkbox" name="scan_content"
|
52 |
value="1"
|
53 |
+
id="scan_content" <?php checked( true, $setting->scan_content ) ?>/>
|
54 |
<span class="sui-toggle-slider"></span>
|
55 |
</label>
|
56 |
<label for="scan_content" class="sui-toggle-label">
|
app/module/setting/view/accessibility.php
CHANGED
@@ -19,9 +19,9 @@
|
|
19 |
</span>
|
20 |
</div>
|
21 |
<div class="sui-box-settings-col-2">
|
|
|
22 |
<div class="sui-form-field">
|
23 |
<label class="sui-toggle">
|
24 |
-
<input type="hidden" name="high_contrast_mode" value="0"/>
|
25 |
<input role="presentation" type="checkbox" name="high_contrast_mode" class="toggle-checkbox"
|
26 |
id="high_contrast_mode" <?php checked( 1, $settings->high_contrast_mode ) ?> value="1"
|
27 |
/>
|
19 |
</span>
|
20 |
</div>
|
21 |
<div class="sui-box-settings-col-2">
|
22 |
+
<input type="hidden" name="high_contrast_mode" value="0"/>
|
23 |
<div class="sui-form-field">
|
24 |
<label class="sui-toggle">
|
|
|
25 |
<input role="presentation" type="checkbox" name="high_contrast_mode" class="toggle-checkbox"
|
26 |
id="high_contrast_mode" <?php checked( 1, $settings->high_contrast_mode ) ?> value="1"
|
27 |
/>
|
app/module/setting/view/general.php
CHANGED
@@ -43,8 +43,8 @@
|
|
43 |
|
44 |
<div class="sui-box-settings-col-2">
|
45 |
<div class="sui-form-field">
|
|
|
46 |
<label class="sui-toggle">
|
47 |
-
<input type="hidden" name="usage_tracking" value="0"/>
|
48 |
<input role="presentation" type="checkbox" name="usage_tracking" class="toggle-checkbox"
|
49 |
id="usage_tracking" <?php checked( 1, $settings->usage_tracking ) ?> value="1"
|
50 |
/>
|
43 |
|
44 |
<div class="sui-box-settings-col-2">
|
45 |
<div class="sui-form-field">
|
46 |
+
<input type="hidden" name="usage_tracking" value="0"/>
|
47 |
<label class="sui-toggle">
|
|
|
48 |
<input role="presentation" type="checkbox" name="usage_tracking" class="toggle-checkbox"
|
49 |
id="usage_tracking" <?php checked( 1, $settings->usage_tracking ) ?> value="1"
|
50 |
/>
|
app/module/setting/view/layouts/layout.php
CHANGED
@@ -5,15 +5,16 @@
|
|
5 |
<h1 class="sui-header-title">
|
6 |
<?php _e( "Settings", "defender-security" ) ?>
|
7 |
</h1>
|
8 |
-
|
9 |
<div class="sui-actions-right">
|
10 |
<div class="sui-actions-right">
|
11 |
-
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/" target="_blank"
|
|
|
12 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
13 |
</a>
|
14 |
</div>
|
15 |
</div>
|
16 |
-
|
17 |
</div>
|
18 |
<div class="sui-row-with-sidenav">
|
19 |
<div class="sui-sidenav">
|
@@ -37,7 +38,13 @@
|
|
37 |
<div class="sui-sidenav-hide-lg">
|
38 |
<select class="sui-mobile-nav" style="display: none;">
|
39 |
<option <?php selected( '', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
|
40 |
-
value="<?php echo network_admin_url( 'admin.php?page=wdf-
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
<?php _e( "Accessibility", "defender-security" ) ?></option>
|
42 |
</select>
|
43 |
</div>
|
@@ -90,13 +97,13 @@
|
|
90 |
</div>
|
91 |
|
92 |
</div>
|
93 |
-
|
94 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
95 |
-
|
96 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
<ul class="sui-footer-nav">
|
101 |
<li><a href="https://profiles.wordpress.org/wpmudev#content-plugins" target="_blank">Free
|
102 |
Plugins</a>
|
@@ -110,7 +117,7 @@
|
|
110 |
</li>
|
111 |
<li><a href="https://incsub.com/privacy-policy/" target="_blank">Privacy Policy</a></li>
|
112 |
</ul>
|
113 |
-
|
114 |
<ul class="sui-footer-nav">
|
115 |
<li><a href="https://premium.wpmudev.org/hub/" target="_blank">The Hub</a></li>
|
116 |
<li><a href="https://premium.wpmudev.org/projects/category/plugins/" target="_blank">Plugins</a>
|
@@ -123,7 +130,7 @@
|
|
123 |
</li>
|
124 |
<li><a href="https://incsub.com/privacy-policy/" target="_blank">Privacy Policy</a></li>
|
125 |
</ul>
|
126 |
-
|
127 |
<ul class="sui-footer-social">
|
128 |
<li><a href="https://www.facebook.com/wpmudev" target="_blank">
|
129 |
<i class="sui-icon-social-facebook" aria-hidden="true"></i>
|
@@ -138,6 +145,6 @@
|
|
138 |
<span class="sui-screen-reader-text">Instagram</span>
|
139 |
</a></li>
|
140 |
</ul>
|
141 |
-
|
142 |
</div>
|
143 |
</div>
|
5 |
<h1 class="sui-header-title">
|
6 |
<?php _e( "Settings", "defender-security" ) ?>
|
7 |
</h1>
|
8 |
+
<?php if ( wp_defender()->hideDocLinks === false ): ?>
|
9 |
<div class="sui-actions-right">
|
10 |
<div class="sui-actions-right">
|
11 |
+
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/" target="_blank"
|
12 |
+
class="sui-button sui-button-ghost">
|
13 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
14 |
</a>
|
15 |
</div>
|
16 |
</div>
|
17 |
+
<?php endif; ?>
|
18 |
</div>
|
19 |
<div class="sui-row-with-sidenav">
|
20 |
<div class="sui-sidenav">
|
38 |
<div class="sui-sidenav-hide-lg">
|
39 |
<select class="sui-mobile-nav" style="display: none;">
|
40 |
<option <?php selected( '', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
|
41 |
+
value="<?php echo network_admin_url( 'admin.php?page=wdf-setting' ) ?>">
|
42 |
+
<?php _e( "General", "defender-security" ) ?></option>
|
43 |
+
<option <?php selected( 'data', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
|
44 |
+
value="<?php echo network_admin_url( 'admin.php?page=wdf-setting&view=data' ) ?>">
|
45 |
+
<?php _e( "Data & Settings", "defender-security" ) ?></option>
|
46 |
+
<option <?php selected( 'accessibility', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
|
47 |
+
value="<?php echo network_admin_url( 'admin.php?page=wdf-setting&view=accessibility' ) ?>">
|
48 |
<?php _e( "Accessibility", "defender-security" ) ?></option>
|
49 |
</select>
|
50 |
</div>
|
97 |
</div>
|
98 |
|
99 |
</div>
|
100 |
+
<?php if ( wp_defender()->changeFooter ): ?>
|
101 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
102 |
+
<?php else: ?>
|
103 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
104 |
+
<?php endif; ?>
|
105 |
+
<?php if ( wp_defender()->hideDocLinks == false ): ?>
|
106 |
+
<?php if ( wp_defender()->isFree ): ?>
|
107 |
<ul class="sui-footer-nav">
|
108 |
<li><a href="https://profiles.wordpress.org/wpmudev#content-plugins" target="_blank">Free
|
109 |
Plugins</a>
|
117 |
</li>
|
118 |
<li><a href="https://incsub.com/privacy-policy/" target="_blank">Privacy Policy</a></li>
|
119 |
</ul>
|
120 |
+
<?php else: ?>
|
121 |
<ul class="sui-footer-nav">
|
122 |
<li><a href="https://premium.wpmudev.org/hub/" target="_blank">The Hub</a></li>
|
123 |
<li><a href="https://premium.wpmudev.org/projects/category/plugins/" target="_blank">Plugins</a>
|
130 |
</li>
|
131 |
<li><a href="https://incsub.com/privacy-policy/" target="_blank">Privacy Policy</a></li>
|
132 |
</ul>
|
133 |
+
<?php endif; ?>
|
134 |
<ul class="sui-footer-social">
|
135 |
<li><a href="https://www.facebook.com/wpmudev" target="_blank">
|
136 |
<i class="sui-icon-social-facebook" aria-hidden="true"></i>
|
145 |
<span class="sui-screen-reader-text">Instagram</span>
|
146 |
</a></li>
|
147 |
</ul>
|
148 |
+
<?php endif; ?>
|
149 |
</div>
|
150 |
</div>
|
app/view/activator.php
CHANGED
@@ -132,8 +132,10 @@
|
|
132 |
</div>
|
133 |
</div>
|
134 |
</form>
|
135 |
-
|
136 |
-
|
|
|
|
|
137 |
</div>
|
138 |
<div class="sui-box activate-progress wd-hide">
|
139 |
<div class="sui-box-body">
|
132 |
</div>
|
133 |
</div>
|
134 |
</form>
|
135 |
+
<?php if ( strlen( wp_defender()->heroImage ) == 0 ): ?>
|
136 |
+
<img src="<?php echo wp_defender()->getPluginUrl() . '/assets/img/defender-activator.svg' ?>"
|
137 |
+
class="sui-image sui-image-center"/>
|
138 |
+
<?php endif; ?>
|
139 |
</div>
|
140 |
<div class="sui-box activate-progress wd-hide">
|
141 |
<div class="sui-box-body">
|
app/view/dashboard.php
CHANGED
@@ -9,15 +9,16 @@ $countAll = $hCount + $sCount;
|
|
9 |
<h1 class="sui-header-title">
|
10 |
<?php _e( "Dashboard", "defender-security" ) ?>
|
11 |
</h1>
|
12 |
-
|
13 |
<div class="sui-actions-right">
|
14 |
<div class="sui-actions-right">
|
15 |
-
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/" target="_blank"
|
|
|
16 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
17 |
</a>
|
18 |
</div>
|
19 |
</div>
|
20 |
-
|
21 |
</div>
|
22 |
<div class="sui-box sui-summary <?php echo \WP_Defender\Behavior\Utils::instance()->getSummaryClass() ?>">
|
23 |
<div class="sui-summary-image-space" aria-hidden="true"></div>
|
@@ -25,9 +26,35 @@ $countAll = $hCount + $sCount;
|
|
25 |
<div class="sui-summary-details">
|
26 |
<span class="sui-summary-large"><?php echo $countAll ?></span>
|
27 |
<?php if ( $countAll > 0 ): ?>
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
<?php else: ?>
|
|
|
|
|
30 |
<i class="sui-icon-check-tick sui-success" aria-hidden="true"></i>
|
|
|
31 |
<?php endif; ?>
|
32 |
<span class="sui-summary-sub"><?php _e( "Security issues", "defender-security" ) ?></span>
|
33 |
</div>
|
@@ -174,7 +201,7 @@ $countAll = $hCount + $sCount;
|
|
174 |
|
175 |
</div>
|
176 |
<?php endif; ?>
|
177 |
-
<?php if ( wp_defender()->changeFooter
|
178 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
179 |
<?php else: ?>
|
180 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
9 |
<h1 class="sui-header-title">
|
10 |
<?php _e( "Dashboard", "defender-security" ) ?>
|
11 |
</h1>
|
12 |
+
<?php if ( wp_defender()->hideDocLinks === false ): ?>
|
13 |
<div class="sui-actions-right">
|
14 |
<div class="sui-actions-right">
|
15 |
+
<a href="https://premium.wpmudev.org/docs/wpmu-dev-plugins/defender/" target="_blank"
|
16 |
+
class="sui-button sui-button-ghost">
|
17 |
<i class="sui-icon-academy"></i> <?php _e( "View Documentation", "defender-security" ) ?>
|
18 |
</a>
|
19 |
</div>
|
20 |
</div>
|
21 |
+
<?php endif; ?>
|
22 |
</div>
|
23 |
<div class="sui-box sui-summary <?php echo \WP_Defender\Behavior\Utils::instance()->getSummaryClass() ?>">
|
24 |
<div class="sui-summary-image-space" aria-hidden="true"></div>
|
26 |
<div class="sui-summary-details">
|
27 |
<span class="sui-summary-large"><?php echo $countAll ?></span>
|
28 |
<?php if ( $countAll > 0 ): ?>
|
29 |
+
<?php
|
30 |
+
$tooltips = "";
|
31 |
+
if ( $hCount == 1 && $sCount == 0 ) {
|
32 |
+
$tooltips = __( "You have one security tweak left to do. We recommend you action it, or ignore it if it's irrelevant.", "defender-security" );
|
33 |
+
} elseif ( $hCount == 0 && $sCount == 1 ) {
|
34 |
+
$tooltips = __( "We've detected a potential security risk in your file system. We recommend you take a look and action a fix, or ignore the file if it's harmless.", "defender-security" );
|
35 |
+
} elseif ( $hCount == 1 && $sCount == 1 ) {
|
36 |
+
$tooltips = __( "You have one security tweak left to do, and one potential security risk in your file system. We recommend you take a look and action fixes, or ignore the issues if they are harmless.", "defender-security" );
|
37 |
+
} elseif ( $hCount == 1 && $sCount > 1 ) {
|
38 |
+
$tooltips = sprintf( __( "You have one security tweak left to do, and %s potential security risks in your file system. We recommend you take a look and action fixes, or ignore the issues if they are harmless", "defender-security" ), $sCount );
|
39 |
+
} elseif ( $hCount > 1 && $sCount == 1 ) {
|
40 |
+
$tooltips = sprintf( __( "You have %s security tweaks left to do, and one potential security risk in your file system. We recommend you take a look and action fixes, or ignore the issues if they are harmless.", "defender-security" ), $hCount );
|
41 |
+
} elseif ( $hCount > 1 && $sCount > 1 ) {
|
42 |
+
$tooltips = sprintf( __( "You have %s security tweaks left to do, and %s potential security risks in your file system. We recommend you take a look and action fixes, or ignore the issues if they are harmless.", "defender-security" ), $hCount, $sCount );
|
43 |
+
} elseif ( $hCount > 1 && $sCount == 0 ) {
|
44 |
+
$tooltips = sprintf( __( "You have %d security tweaks left to do. We recommend you action it, or ignore it if it's irrelevant.", "defender-security" ), $hCount );
|
45 |
+
} elseif ( $hCount == 0 && $sCount > 1 ) {
|
46 |
+
$tooltips = sprintf( __( "We've detected %d potential security risks in your file system. We recommend you take a look and action a fix, or ignore the file if it's harmless.", "defender-security" ), $sCount );
|
47 |
+
}
|
48 |
+
?>
|
49 |
+
<span class="sui-tooltip sui-tooltip-top-left sui-tooltip-constrained"
|
50 |
+
data-tooltip="<?php echo $tooltips ?>">
|
51 |
+
<i aria-hidden="true" class="sui-icon-info sui-warning"></i>
|
52 |
+
</span>
|
53 |
<?php else: ?>
|
54 |
+
<span class="sui-tooltip sui-tooltip-top-left sui-tooltip-constrained"
|
55 |
+
data-tooltip="<?php esc_attr_e( "You don't have any outstanding security issues, nice work!", "defender-security" ) ?>">
|
56 |
<i class="sui-icon-check-tick sui-success" aria-hidden="true"></i>
|
57 |
+
</span>
|
58 |
<?php endif; ?>
|
59 |
<span class="sui-summary-sub"><?php _e( "Security issues", "defender-security" ) ?></span>
|
60 |
</div>
|
201 |
|
202 |
</div>
|
203 |
<?php endif; ?>
|
204 |
+
<?php if ( wp_defender()->changeFooter ): ?>
|
205 |
<div class="sui-footer"><?php echo wp_defender()->footerText ?></div>
|
206 |
<?php else: ?>
|
207 |
<div class="sui-footer">Made with <i class="sui-icon-heart"></i> by WPMU DEV</div>
|
assets/css/styles.css
CHANGED
@@ -230,9 +230,18 @@
|
|
230 |
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-image-space {
|
231 |
display: block;
|
232 |
}
|
|
|
|
|
|
|
233 |
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details {
|
234 |
padding-left: 30px !important;
|
235 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-list i {
|
237 |
font-size: 16px;
|
238 |
}
|
@@ -275,9 +284,18 @@
|
|
275 |
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-image-space {
|
276 |
display: block;
|
277 |
}
|
|
|
|
|
|
|
278 |
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details {
|
279 |
padding-left: 30px !important;
|
280 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-list i {
|
282 |
font-size: 16px;
|
283 |
}
|
@@ -301,79 +319,6 @@
|
|
301 |
.wp-defender .wdf-scanning .issue-content .sui-box-body div {
|
302 |
margin-bottom: 30px;
|
303 |
}
|
304 |
-
.wp-defender .wdf-scanning .issue-content .hljs {
|
305 |
-
display: block;
|
306 |
-
overflow-x: auto;
|
307 |
-
padding: 0.5em;
|
308 |
-
color: black;
|
309 |
-
background-color: #FAFAFA;
|
310 |
-
}
|
311 |
-
.wp-defender .wdf-scanning .issue-content .hljs del {
|
312 |
-
background: #FFA5A8;
|
313 |
-
}
|
314 |
-
.wp-defender .wdf-scanning .issue-content .hljs ins {
|
315 |
-
background: #D1F1EA;
|
316 |
-
text-decoration: none;
|
317 |
-
}
|
318 |
-
.wp-defender .wdf-scanning .issue-content .hljs-comment,
|
319 |
-
.wp-defender .wdf-scanning .issue-content .hljs-quote,
|
320 |
-
.wp-defender .wdf-scanning .issue-content .hljs-variable {
|
321 |
-
color: #008000;
|
322 |
-
}
|
323 |
-
.wp-defender .wdf-scanning .issue-content .hljs-keyword,
|
324 |
-
.wp-defender .wdf-scanning .issue-content .hljs-selector-tag,
|
325 |
-
.wp-defender .wdf-scanning .issue-content .hljs-built_in,
|
326 |
-
.wp-defender .wdf-scanning .issue-content .hljs-name,
|
327 |
-
.wp-defender .wdf-scanning .issue-content .hljs-tag {
|
328 |
-
color: #00f;
|
329 |
-
}
|
330 |
-
.wp-defender .wdf-scanning .issue-content .hljs-string,
|
331 |
-
.wp-defender .wdf-scanning .issue-content .hljs-title,
|
332 |
-
.wp-defender .wdf-scanning .issue-content .hljs-section,
|
333 |
-
.wp-defender .wdf-scanning .issue-content .hljs-attribute,
|
334 |
-
.wp-defender .wdf-scanning .issue-content .hljs-literal,
|
335 |
-
.wp-defender .wdf-scanning .issue-content .hljs-template-tag,
|
336 |
-
.wp-defender .wdf-scanning .issue-content .hljs-template-variable,
|
337 |
-
.wp-defender .wdf-scanning .issue-content .hljs-type,
|
338 |
-
.wp-defender .wdf-scanning .issue-content .hljs-addition {
|
339 |
-
color: #a31515;
|
340 |
-
}
|
341 |
-
.wp-defender .wdf-scanning .issue-content .hljs-deletion,
|
342 |
-
.wp-defender .wdf-scanning .issue-content .hljs-selector-attr,
|
343 |
-
.wp-defender .wdf-scanning .issue-content .hljs-selector-pseudo,
|
344 |
-
.wp-defender .wdf-scanning .issue-content .hljs-meta {
|
345 |
-
color: #2b91af;
|
346 |
-
}
|
347 |
-
.wp-defender .wdf-scanning .issue-content .hljs-doctag {
|
348 |
-
color: #808080;
|
349 |
-
}
|
350 |
-
.wp-defender .wdf-scanning .issue-content .hljs-attr {
|
351 |
-
color: #f00;
|
352 |
-
}
|
353 |
-
.wp-defender .wdf-scanning .issue-content .hljs-symbol,
|
354 |
-
.wp-defender .wdf-scanning .issue-content .hljs-bullet,
|
355 |
-
.wp-defender .wdf-scanning .issue-content .hljs-link {
|
356 |
-
color: #00b0e8;
|
357 |
-
}
|
358 |
-
.wp-defender .wdf-scanning .issue-content .hljs-emphasis {
|
359 |
-
font-style: italic;
|
360 |
-
}
|
361 |
-
.wp-defender .wdf-scanning .issue-content .hljs-strong {
|
362 |
-
font-weight: bold;
|
363 |
-
}
|
364 |
-
.wp-defender .wdf-scanning .issue-content .hljs-line-numbers {
|
365 |
-
border-right: 1px solid #ccc;
|
366 |
-
color: #999;
|
367 |
-
-webkit-touch-callout: none;
|
368 |
-
-webkit-user-select: none;
|
369 |
-
-khtml-user-select: none;
|
370 |
-
-moz-user-select: none;
|
371 |
-
-ms-user-select: none;
|
372 |
-
user-select: none;
|
373 |
-
background-color: #F2F2F2;
|
374 |
-
width: 40px;
|
375 |
-
text-align: center;
|
376 |
-
}
|
377 |
.wp-defender .wdf-scanning .issue-content pre {
|
378 |
border: 1px solid #E6E6E6;
|
379 |
padding: 0;
|
@@ -384,6 +329,7 @@
|
|
384 |
.wp-defender .wdf-scanning .issue-content pre code {
|
385 |
border: none;
|
386 |
border-radius: 0;
|
|
|
387 |
}
|
388 |
.wp-defender .wdf-scanning .sui-box-settings-row.sui-upsell-row {
|
389 |
border-bottom: 1px solid #E6E6E6 !important;
|
@@ -532,9 +478,18 @@
|
|
532 |
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-image-space {
|
533 |
display: block;
|
534 |
}
|
|
|
|
|
|
|
535 |
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details {
|
536 |
padding-left: 30px !important;
|
537 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
538 |
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-list i {
|
539 |
font-size: 16px;
|
540 |
}
|
@@ -640,3 +595,8 @@
|
|
640 |
.wd-calendar .applyBtn, .wd-calendar .cancelBtn {
|
641 |
display: none;
|
642 |
}
|
|
|
|
|
|
|
|
|
|
230 |
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-image-space {
|
231 |
display: block;
|
232 |
}
|
233 |
+
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-segment {
|
234 |
+
overflow: visible;
|
235 |
+
}
|
236 |
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details {
|
237 |
padding-left: 30px !important;
|
238 |
}
|
239 |
+
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-segment span.sui-tooltip {
|
240 |
+
top: -22px;
|
241 |
+
}
|
242 |
+
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-segment span.sui-tooltip i {
|
243 |
+
top: 0;
|
244 |
+
}
|
245 |
.wp-defender .hardener .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-list i {
|
246 |
font-size: 16px;
|
247 |
}
|
284 |
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-image-space {
|
285 |
display: block;
|
286 |
}
|
287 |
+
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-segment {
|
288 |
+
overflow: visible;
|
289 |
+
}
|
290 |
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details {
|
291 |
padding-left: 30px !important;
|
292 |
}
|
293 |
+
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details span.sui-tooltip {
|
294 |
+
top: -22px;
|
295 |
+
}
|
296 |
+
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details span.sui-tooltip i {
|
297 |
+
top: 0;
|
298 |
+
}
|
299 |
.wp-defender .wdf-scanning .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-list i {
|
300 |
font-size: 16px;
|
301 |
}
|
319 |
.wp-defender .wdf-scanning .issue-content .sui-box-body div {
|
320 |
margin-bottom: 30px;
|
321 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
.wp-defender .wdf-scanning .issue-content pre {
|
323 |
border: 1px solid #E6E6E6;
|
324 |
padding: 0;
|
329 |
.wp-defender .wdf-scanning .issue-content pre code {
|
330 |
border: none;
|
331 |
border-radius: 0;
|
332 |
+
overflow: visible;
|
333 |
}
|
334 |
.wp-defender .wdf-scanning .sui-box-settings-row.sui-upsell-row {
|
335 |
border-bottom: 1px solid #E6E6E6 !important;
|
478 |
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-image-space {
|
479 |
display: block;
|
480 |
}
|
481 |
+
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-segment {
|
482 |
+
overflow: visible;
|
483 |
+
}
|
484 |
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details {
|
485 |
padding-left: 30px !important;
|
486 |
}
|
487 |
+
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details span.sui-tooltip {
|
488 |
+
top: -22px;
|
489 |
+
}
|
490 |
+
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-summary-details span.sui-tooltip i {
|
491 |
+
top: 0;
|
492 |
+
}
|
493 |
.wp-defender .def-dashboard .sui-summary:not(.sui-unbranded) .sui-summary-segment .sui-list i {
|
494 |
font-size: 16px;
|
495 |
}
|
595 |
.wd-calendar .applyBtn, .wd-calendar .cancelBtn {
|
596 |
display: none;
|
597 |
}
|
598 |
+
|
599 |
+
.sui-color-accessible .wp-defender .iplockout #iplockout-table tbody tr td .badge {
|
600 |
+
color: white;
|
601 |
+
background: black;
|
602 |
+
}
|
assets/css/styles.css.map
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"version": 3,
|
3 |
-
"mappings": ";;IA4HI,SAAS,EAAE,YAAY;;IAEvB,SAAS,EAAE,cAAc;AC9H7B,wBAAkB;EAChB,OAAO,EAAE,IAAI;EACb,SAAS,EAAE,IAAI;AAGjB,6CAAuC;EACrC,aAAa,EAAE,IAAI;AAGrB,iDAA2C;EACzC,YAAY,EAAE,CAAC;AAGjB,kDAA4C;EAC1C,aAAa,EAAE,CAAC;AAIhB,uBAAQ;EACN,UAAU,EAAE,UAAU;AAI1B,kCAA4B;EAAE,yBAAyB;EACrD,KAAK,EAAE,OAAO;AAGhB,wBAAkB;EAAE,6BAA6B;EAC/C,KAAK,EAAE,OAAO;EACd,OAAO,EAAE,CAAC;AAGZ,yBAAmB;EACjB,KAAK,EAAE,OAAO;EACd,OAAO,EAAE,CAAC;AAGZ,6BAAuB;EAAE,6BAA6B;EACpD,KAAK,EAAE,OAAO;AAGhB,sGAA2E;EACzE,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,iBAAiB;EACzB,KAAK,ECxCG,IAAI;EDyCZ,WAAW,EAAE,GAAG;EAChB,cAAc,EAAE,QAAQ;AAG1B,wBAAkB;EAChB,UAAU,EAAE,OAAO;EAEnB,yCAAiB;IACf,UAAU,EAAE,IAAI;EAGhB,2DAAY;IACV,KAAK,ECrDD,IAAI;IDsDR,WAAW,EAAE,GAAG;EAGhB,qDAAG;IACD,KAAK,EC1DH,IAAI;ID2DN,WAAW,EAAE,GAAG;AAMxB,qEAAwD;EACtD,MAAM,EAAE,iBAAiB;EACzB,6FAAY;IACV,KAAK,ECpEC,IAAI;IDqEV,WAAW,EAAE,GAAG;AAIpB,+DAAkD;EAShD,UAAU,EAAE,OAAO;EARnB,uFAAY;IACV,KAAK,EC3EC,IAAI;ID4EV,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,OAAO;EAErB,iGAAiB;IACf,UAAU,EAAE,IAAI;AAKpB,yFAAqE;EACnE,MAAM,EAAE,iBAAiB;AAG3B,yFAAqE;EACnE,MAAM,EAAE,iBAAiB;EACzB,UAAU,EAAE,OAAO;AAGrB,0KAAsJ;EACpJ,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,CAAC;AAGZ,+IAA2H;EACzH,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,IAAI;EAChB,OAAO,EAAE,CAAC;AAGZ,2JAAuI;EACrI,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,IAAI;EAChB,OAAO,EAAE,CAAC;AAGZ,8HAAwH;EACtH,gBAAgB,EC1GL,OAAO;ED2GlB,KAAK,EC1GO,IAAI;AD6GlB,wBAAkB;EAChB,KAAK,EC5GO,OAAO;ED6GnB,UAAU,EAAE,uBAA4B;AAG1C;oIAC8H;EAC5H,gBAAgB,EAAE,OAAO;AAG3B,8DAAiD;EAC/C,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,kBAAuB;AAGrC,yHAA8F;EAC5F,UAAU,ECnHE,OAAO;EDoHnB,KAAK,EAAE,OAAO;EACd,MAAM,EAAE,WAAW;EACnB,WAAW,EAAE,IAAI;AAGnB,2BAAqB;EACnB,IAAI,EAAE,gCAAgC;EACtC,OAAO,EAAE,QAAQ;AAGnB,yBAAmB;EACjB,KAAK,ECrIK,OAAO;EDsIjB,gBAAgB,EAAE,IAAI;EACtB,UAAU,EAAE,uBAAyB;EACrC,WAAW,EAAE,GAAG;EAChB,qBAAqB,EAAE,IAAI;EAC3B,kBAAkB,EAAE,IAAI;EACxB,aAAa,EAAE,IAAI;AAGrB,kGAA8E;EAC5E,UAAU,EAAE,kBAAoB;EAChC,KAAK,EAAE,IAAI;AAGb,gBAAU;EACR,UAAU,EAAE,CAAC;EACb,aAAa,EAAE,IAAI;EAEjB,kCAAa;IACX,OAAO,EAAE,MAAM;IACf,sCAAI;MACF,YAAY,EAAE,GAAG;MACjB,OAAO,EAAE,YAAY;MACrB,cAAc,EAAE,MAAM;EAG1B,iCAAY;IACV,OAAO,EAAE,MAAM;AAKrB,qBAAe;EACb,WAAW,ECnLK,8BAA8B;EDoL9C,iCAAY;IACV,WAAW,EAAE,IAAI;IACjB,KAAK,ECpLC,IAAI;IDqLV,SAAS,EAAE,IAAI;IACf,WAAW,ECzLF,kBAAkB;ID0L3B,cAAc,EAAE,UAAU;EAE5B,kCAAa;IACX,KAAK,ECzLM,IAAI;ID0Lf,SAAS,EAAE,IAAI;IACf,oCAAE;MACA,cAAc,EAAE,GAAG;AAKzB,eAAS;EACP,QAAQ,EAAE,QAAQ;EAClB,0BAAW;IACT,QAAQ,EAAE,QAAQ;IAClB,6BAAG;MACD,KAAK,ECvMD,IAAI;MDwMR,OAAO,EAAE,YAAY;MACrB,SAAS,EAAE,IAAI;MACf,QAAQ,EAAE,OAAO;IAEnB,qCAAW;MACT,YAAY,EAAE,IAAI;MAClB,cAAc,EAAE,MAAM;IAExB,mCAAS;MACP,WAAW,EAAE,IAAI;MACjB,QAAQ,EAAE,QAAQ;MAClB,GAAG,EAAE,IAAI;IAEX,kCAAQ;MACN,UAAU,EAAE,GAAG;IAGjB,kCAAQ;MACN,WAAW,EAAE,GAAG;MAChB,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;MACjB,UAAU,EAAE,IAAI;IAElB,gCAAM;MAMJ,KAAK,EAAE,KAAK;MALZ,uCAAO;QACL,WAAW,EAAE,IAAI;QACjB,KAAK,EAAE,IAAI;QACX,YAAY,EAAE,IAAI;MAGpB,kDAAkB;QAChB,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,YAAY;QACrB,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,KAAK;QAChB,UAAU,EAAE,GAAG;IAGnB,mCAAQ;MACN,YAAY,EAAE,IAAI;EAGtB,4BAAa;IACX,KAAK,ECjPG,IAAI;IDkPZ,mCAAO;MACL,KAAK,ECrPD,IAAI;AD0Pd,cAAQ;EACN,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,4BAAc;IACZ,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;EAEd,kCAAoB;IAClB,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,IAAI;EAElB,6DAA+C;IAC7C,WAAW,EAAE,IAAI;EAEnB,8DAAgD;IAC9C,IAAI,EAAE,IAAI;EAEZ,uDAAyC;IACvC,UAAU,EAAE,OAAO;EAErB,mCAAqB;IACnB,UAAU,EAAE,OAAO;AAKrB,6BAAW;EACT,KAAK,EAAE,IAAI;AAKb,qBAAK;EACH,gBAAgB,EAAE,8BAA8B;EAChD,iBAAiB,EAAE,SAAS;EAC5B,mBAAmB,EAAE,QAAQ;EAC7B,cAAc,EAAE,gBAAgB;AAKlC,yBAAK;EACH,gBAAgB,EAAE,8BAA8B;EAChD,iBAAiB,EAAE,SAAS;EAC5B,mBAAmB,EAAE,QAAQ;EAC7B,cAAc,EAAE,gBAAgB;EAChC,qEAAsE;IALxE,yBAAK;MAMF,gBAAgB,EAAC,8BAClB;AAIJ,mBAAa;EACX,gBAAgB,EAAE,KAAK;EACvB,UAAU,EAAE,IAAI;EAChB,OAAO,EAAE,IAAI;EACb,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,iBAAsB;EAC9B,yCAAsB;IACpB,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,8BAA8B;IAC3C,6DAAoB;MAClB,QAAQ,EAAE,QAAQ;MAClB,GAAG,EAAE,IAAI;MACT,IAAI,EAAE,IAAI;MACV,MAAM,EAAE,OAAO;IAEjB,6DAAoB;MAClB,QAAQ,EAAE,QAAQ;MAClB,GAAG,EAAE,IAAI;MACT,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,OAAO;IAEjB,8DAAqB;MACnB,UAAU,EAAE,MAAM;EAGtB,2CAAwB;IACtB,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,cAAc;IAC1B,WAAW,EAAE,IAAI;IACjB,8FAAO;MACL,OAAO,EAAE,GAAG;MACZ,kGAAE;QACA,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;IAGhB,8CAAG;MACD,UAAU,EAAE,MAAM;EAGtB,wCAAqB;IACnB,UAAU,EAAE,OAAO;IACnB,0CAAE;MACA,KAAK,EAAE,IAAI;EAIf,8CAA2B;IACzB,UAAU,EAAE,OAAO;IACnB,gDAAE;MACA,KAAK,EAAE,IAAI;EAIf,6DAAsB;IACpB,OAAO,EAAE,IAAI;AAIjB,QAAE;EACA,KAAK,EAAE,OAAO;AAGhB,8BAAiB;EACf,KAAK,EAAE,OAAO;AAId,yBAAM;EACJ,UAAU,EAAE,sBAAqB;AAEnC,wBAAK;EAYH,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,SAAS;EACjB,KAAK,EAAE,IAAI;EACX,IAAI,EAAE,CAAC;EACP,SAAS,EAAE,KAAK;EAChB,OAAO,EAAE,IAAI;EAhBb,+BAAO;IAIL,MAAM,EAAE,sBAAsB;IAC9B,OAAO,EAAE,MAAM;IAJf,sCAAO;MACL,OAAO,EAAE,MAAM;IAIjB,kCAAG;MACD,KAAK,ECjYH,IAAI;MDkYN,SAAS,EAAE,IAAI;AAUrB,+BAAY;EACV,OAAO,EAAE,IAAI;AAKf,8BAAK;EACH,MAAM,EAAE,SAAS;ADpNnB,2DAAsE;ECyNtE,mBAAa;IACX,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;ADnOZ,oCAA4C;ECwO5C,mBAAa;IACX,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,CAAC;IACP,+BAAY;MACV,OAAO,EAAE,IAAI;AAKnB,6BAAuB;EACrB,cAAc,EAAE,eAAe;EAC/B,WAAW,EAAE,MAAM;AAGrB,sBAAgB;EACd,cAAc,EAAE,IAAI;EACpB,IAAI,EAAE,gCAAgC;AEnbxC,sBAAgB;EACd,gBAAgB,EAAE,6BAA6B;EAC/C,iBAAiB,EAAE,SAAS;EAC5B,mBAAmB,EAAE,SAAS;AAGhC,mBAAa;EACX,gBAAgB,EAAE,mCAAmC;EACrD,iBAAiB,EAAE,SAAS;EAC5B,mBAAmB,EAAE,SAAS;EAC9B,cAAc,EAAE,KAAK;EACrB,QAAQ,EAAE,MAAM;EAChB,wBAAK;IACH,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,mBAAmB;IAC3B,OAAO,EAAE,MAAM;EAEjB,iCAAc;IACZ,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;EAEb,yBAAM;IACJ,UAAU,EAAE,IAAI;AAIpB,mCAA6B;EAC3B,gBAAgB,EAAE,+BAA+B;EAE/C,qDAAI;IACF,KAAK,EAAE,GAAG;AAKhB,wBAAkB;EAChB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,KAAK;EACX,OAAO,EAAE,GAAG;EACZ,OAAO,EAAE,GAAG;EACZ,UAAU,EAAE,OAAO;AAGrB,iBAAU;EACR,UAAU,EAAE,eAAe;AAG7B,oBAAc;EACZ,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC;EACP,OAAO,EAAE,GAAG;EACZ,OAAO,EAAE,GAAG;EACZ,UAAU,EAAE,OAAO;AAGrB,kCAA4B;EAC1B,gBAAgB,EAAE,0BAA0B;EAC5C,iBAAiB,EAAE,SAAS;EAC5B,mBAAmB,EAAE,QAAQ;EAC7B,cAAc,EAAE,GAAG;AAGrB,iCAA2B;EACzB,cAAc,EAAE,KAAK;EACrB,gBAAgB,EAAE,8BAA8B;EAChD,eAAe,EAAE,GAAG;EACpB,iBAAiB,EAAE,SAAS;EAC5B,mBAAmB,EAAE,QAAQ;AAI7B,mCAAK;EACH,gBAAgB,EAAE,mCAAmC;EACrD,iBAAiB,EAAE,SAAS;EAC5B,mBAAmB,EAAE,OAAO;EAC5B,cAAc,EAAE,gBAAgB;EAChC,iDAAc;IACZ,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IHqGf,oCAA4C;MGxG1C,iDAAc;QAKV,MAAM,EAAE,CAAC;AAMjB,2BAAqB;EAcnB,QAAQ,EAAE,QAAQ;EAblB,oEAAa;IACX,OAAO,EAAE,CAAC;EAEZ,+BAAI;IACF,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,CAAC;IACV,UAAU,EAAE,KAAK;IACjB,OAAO,EAAE,GAAG;EAGd,uCAAY;IACV,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,IAAI;IACT,KAAK,EAAE,CAAC;AAIZ,oBAAc;EACZ,QAAQ,EAAE,MAAM;EAChB,WAAW,EAAE,EAAE;EACf,wBAAI;IACF,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAAE,GAAG;IACV,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,SAAS;IAClB,aAAa,EAAE,GAAG;IAClB,gBAAgB,EDtFV,OAAO;ICuFb,SAAS,EAAE,IAAI;IACf,KAAK,ED7HC,IAAI;IC8HV,WAAW,EAAE,IAAI;IHyDnB,oCAA4C;MGlE5C,wBAAI;QAWA,KAAK,EAAE,GAAG;EAGd,+BAAW;IACT,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,YAAY;IACrB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,sBAAsB;IAC9B,cAAc,EAAE,MAAM;EAExB,+BAAW;IACT,kBAAkB,EDvGZ,OAAO;ICwGb,QAAQ,EAAE,QAAQ;IAClB,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,GAAG;EAEV,sBAAE;IACA,KAAK,EDlJC,IAAI;ICmJV,eAAe,EAAE,SAAS;IAC1B,MAAM,EAAE,OAAO;IACf,WAAW,EAAE,GAAG;;ACjJpB,UASC;EARC,WAAW,EAAE,eAAe;EAC5B,GAAG,EAAE,yBAAyB;EAC9B,GAAG,EAAE,uMAG2C;EAChD,WAAW,EAAE,MAAM;EACnB,UAAU,EAAE,MAAM;AAGpB,YAAa;EACX,cAAc,EAAE,QAAQ;EACxB,WAAW,EFpBA,kBAAkB;EEqB7B,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;EAChB,WAAW,EAAE,IAAI;EACjB,MAAM,EAAE,eAAe;EACvB,sBAAsB,EAAE,sBAAsB;ECmChD;;;;IAIE;EDrCA,kBAAM;IACJ,eAAe,EAAE,QAAQ;EC5B7B,kBAAM;IACJ,cAAc,EAAE,IAAI;EAGtB,mBAAO;IACL,aAAa,EAAE,IAAI;EAGrB,wBAAY;IACV,MAAM,EAAE,YAAY;EAGtB,iBAAK;IACH,aAAa,EAAE,iBAAsB;EAGvC,kBAAM;IACJ,SAAS,EAAE,IAAI;IACf,KAAK,EHZI,IAAI;IGab,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,IAAI;EAGnB,mBAAO;IACL,KAAK,EAAE,IAAI;EAGb,yBAAa;IACX,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,MAAM;EAGpB,qBAAS;IACP,OAAO,EAAE,eAAe;EAG1B,wBAAY;IACV,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,gBAAgB,EAAE,IAAI;IACtB,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,GAAG;IACZ,0BAAE;MACA,SAAS,EAAE,IAAI;MACf,QAAQ,EAAE,QAAQ;MAClB,GAAG,EAAE,GAAG;MACR,IAAI,EAAE,GAAG;MACT,UAAU,EAAE,KAAK;MACjB,WAAW,EAAE,KAAK;EAStB,kBAAM;IACJ,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,KAAK;IACjB,KAAK,EAAE,KAAK;IACZ,sBAAI;MACF,UAAU,EAAE,OAAO;IAErB,sBAAI;MACF,UAAU,EAAE,OAAO;MACnB,eAAe,EAAE,IAAI;EAIzB;;6BAEe;IACb,KAAK,EAAE,OAAO;EAGhB;;;;wBAIU;IACR,KAAK,EAAE,IAAI;EAGb;;;;;;;;6BAQe;IACb,KAAK,EAAE,OAAO;EAGhB;;;yBAGW;IACT,KAAK,EAAE,OAAO;EAGhB,yBAAa;IACX,KAAK,EAAE,OAAO;EAGhB,uBAAW;IACT,KAAK,EAAE,IAAI;EAGb;;yBAEW;IACT,KAAK,EAAE,OAAO;EAGhB,2BAAe;IACb,UAAU,EAAE,MAAM;EAGpB,yBAAa;IACX,WAAW,EAAE,IAAI;EAGnB,+BAAmB;IACjB,UAAU,EAAE,KAAK;IACjB,YAAY,EAAE,cAAc;IAC5B,KAAK,EAAE,IAAI;IACX,qBAAqB,EAAE,IAAI;IAC3B,mBAAmB,EAAE,IAAI;IACzB,kBAAkB,EAAE,IAAI;IACxB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,IAAI;EAGnB,gBAAI;IACF,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,CAAC;IACV,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,MAAM;;;IL5BhB,SAAS,EAAE,YAAY;;IAEvB,SAAS,EAAE,cAAc;EMzH3B,sBAAe;IACb,OAAO,EAAE,KAAW;ENqLtB,oCAA4C;IMpL5C,6BAAsB;MAElB,OAAO,EAAE,gBAAsB;ENsLnC,oCAAsC;IMrLtC,6BAAsB;MAElB,OAAO,EAAE,gBAAsB;ENuLnC,2DAAsE;IMtLtE,kCAA2B;MAEvB,OAAO,EAAE,gBAAsB;ENwLnC,oCAA6C;IMvL7C,4BAAqB;MAEjB,OAAO,EAAE,gBAAsB;ENyLnC,oCAAuC;IMxLvC,8BAAuB;MAEnB,OAAO,EAAE,gBAAsB;EN0LnC,4DAA0E;IMzL1E,mCAA4B;MAExB,OAAO,EAAE,gBAAsB;EN2LnC,qCAA0C;IM1L1C,iCAA0B;MAEtB,OAAO,EAAE,gBAAsB;EAtBnC,qBAAe;IACb,OAAO,EAAE,IAAW;ENqLtB,oCAA4C;IMpL5C,4BAAsB;MAElB,OAAO,EAAE,eAAsB;ENsLnC,oCAAsC;IMrLtC,4BAAsB;MAElB,OAAO,EAAE,eAAsB;ENuLnC,2DAAsE;IMtLtE,iCAA2B;MAEvB,OAAO,EAAE,eAAsB;ENwLnC,oCAA6C;IMvL7C,2BAAqB;MAEjB,OAAO,EAAE,eAAsB;ENyLnC,oCAAuC;IMxLvC,6BAAuB;MAEnB,OAAO,EAAE,eAAsB;EN0LnC,4DAA0E;IMzL1E,kCAA4B;MAExB,OAAO,EAAE,eAAsB;EN2LnC,qCAA0C;IM1L1C,gCAA0B;MAEtB,OAAO,EAAE,eAAsB;EAtBnC,uBAAe;IACb,OAAO,EAAE,MAAW;ENqLtB,oCAA4C;IMpL5C,8BAAsB;MAElB,OAAO,EAAE,iBAAsB;ENsLnC,oCAAsC;IMrLtC,8BAAsB;MAElB,OAAO,EAAE,iBAAsB;ENuLnC,2DAAsE;IMtLtE,mCAA2B;MAEvB,OAAO,EAAE,iBAAsB;ENwLnC,oCAA6C;IMvL7C,6BAAqB;MAEjB,OAAO,EAAE,iBAAsB;ENyLnC,oCAAuC;IMxLvC,+BAAuB;MAEnB,OAAO,EAAE,iBAAsB;EN0LnC,4DAA0E;IMzL1E,oCAA4B;MAExB,OAAO,EAAE,iBAAsB;EN2LnC,qCAA0C;IM1L1C,kCAA0B;MAEtB,OAAO,EAAE,iBAAsB;EAtBnC,6BAAe;IACb,OAAO,EAAE,YAAW;ENqLtB,oCAA4C;IMpL5C,oCAAsB;MAElB,OAAO,EAAE,uBAAsB;ENsLnC,oCAAsC;IMrLtC,oCAAsB;MAElB,OAAO,EAAE,uBAAsB;ENuLnC,2DAAsE;IMtLtE,yCAA2B;MAEvB,OAAO,EAAE,uBAAsB;ENwLnC,oCAA6C;IMvL7C,mCAAqB;MAEjB,OAAO,EAAE,uBAAsB;ENyLnC,oCAAuC;IMxLvC,qCAAuB;MAEnB,OAAO,EAAE,uBAAsB;EN0LnC,4DAA0E;IMzL1E,0CAA4B;MAExB,OAAO,EAAE,uBAAsB;EN2LnC,qCAA0C;IM1L1C,wCAA0B;MAEtB,OAAO,EAAE,uBAAsB;EAtBnC,4BAAe;IACb,OAAO,EAAE,WAAW;ENqLtB,oCAA4C;IMpL5C,mCAAsB;MAElB,OAAO,EAAE,sBAAsB;ENsLnC,oCAAsC;IMrLtC,mCAAsB;MAElB,OAAO,EAAE,sBAAsB;ENuLnC,2DAAsE;IMtLtE,wCAA2B;MAEvB,OAAO,EAAE,sBAAsB;ENwLnC,oCAA6C;IMvL7C,kCAAqB;MAEjB,OAAO,EAAE,sBAAsB;ENyLnC,oCAAuC;IMxLvC,oCAAuB;MAEnB,OAAO,EAAE,sBAAsB;EN0LnC,4DAA0E;IMzL1E,yCAA4B;MAExB,OAAO,EAAE,sBAAsB;EN2LnC,qCAA0C;IM1L1C,uCAA0B;MAEtB,OAAO,EAAE,sBAAsB;ENTnC,+BAAO;IACL,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,KAAK;EMalB,4BAAe;IACb,KAAK,EAAE,IAAI;EAEb,6BAAgB;IACd,KAAK,EAAE,KAAK;EAId,wBAAW;IACT,QAAQ,EAAE,iBAAiB;EAI7B,wBAAW;IN8FT,MAAM,EADU,CAAC;IAEjB,IAAI,EAFY,CAAC;IAGjB,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAJW,CAAC;IAKjB,GAAG,EALa,CAAC;EMxFnB,+BAAkB;IAChB,UAAU,EAAE,MAAM;EAEpB,2BAAc;IACZ,UAAU,EAAE,IAAI;EAElB,4BAAe;IACb,UAAU,EAAE,KAAK;EAInB,uBAAU;IACR,OAAO,EAAE,eAAe;EN2HxB,oCAA4C;IMzH9C,8BAAiB;MAEb,OAAO,EAAE,eAAe;EN2H1B,oCAAsC;IMzHxC,8BAAiB;MAEb,OAAO,EAAE,eAAe;EN2H1B,2DAAsE;IMzHxE,mCAAsB;MAElB,OAAO,EAAE,eAAe;EN2H1B,oCAA6C;IMzH/C,6BAAgB;MAEZ,OAAO,EAAE,eAAe;EN2H1B,oCAAuC;IMzHzC,+BAAkB;MAEd,OAAO,EAAE,eAAe;EN2H1B,4DAA0E;IMzH5E,oCAAuB;MAEnB,OAAO,EAAE,eAAe;EN2H1B,qCAA0C;IMzH5C,kCAAqB;MAEjB,OAAO,EAAE,eAAe;EAI5B,yBAAY;IACV,cAAc,EAAE,IAAI;EAEtB,2BAAc;IACZ,MAAM,EAAE,YAAY;EAEtB,4BAAe;IACb,OAAO,EAAE,YAAY;EAEvB,6BAAgB;IN6Dd,qBAAqB,EAAE,IAAI;IAC3B,mBAAmB,EAAE,IAAI;IACzB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,IAAI;EO1KnB,oBAAO;IACL,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC;IACZ,WAAW,EAAE,CAAC;IACd,OAAO,EAAE,IAAI;IACb,mDAAgC;MAC9B,IAAI,EAAE,IAAI;IACZ,iDAA8B;MAC5B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,IAAI;IACb,2DAAwC;MACtC,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,GAAG;IACZ,uDAAoC;MAClC,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,QAAQ;IACjB,iDAA8B;MAC5B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,GAAG;IACZ,sDAAmC;MACjC,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,QAAQ;IACjB,wDAAqC;MACnC,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,GAAG;IACZ,kEAA+C;MAC7C,WAAW,EAAE,GAAG;IAClB,8DAA2C;MACzC,WAAW,EAAE,QAAQ;IACvB,wDAAqC;MACnC,WAAW,EAAE,GAAG;IAClB,6DAA0C;MACxC,WAAW,EAAE,QAAQ;IACvB,+DAA4C;MAC1C,WAAW,EAAE,GAAG;IAEhB,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,aAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,aAAgB;IAJ/B,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,cAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,cAAgB;IAJ/B,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,GAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,GAAgB;IAJ/B,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,cAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,cAAgB;IAJ/B,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,cAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,cAAgB;IAJ/B,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,GAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,GAAgB;IAJ/B,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,cAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,cAAgB;IAJ/B,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,cAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,cAAgB;IAJ/B,8CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,GAAgB;IACzB,qDAAsC;MACpC,WAAW,EAAE,GAAgB;IAJ/B,+CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,cAAgB;IACzB,sDAAsC;MACpC,WAAW,EAAE,cAAgB;IAJ/B,+CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,cAAgB;IACzB,sDAAsC;MACpC,WAAW,EAAE,cAAgB;IAJ/B,+CAA+B;MAC7B,IAAI,EAAE,IAAI;MACV,KAAK,EAAE,IAAgB;IACzB,sDAAsC;MACpC,WAAW,EAAE,IAAgB;IPkJjC,oCAA4C;MOhJ1C,qCAAkB;QAChB,IAAI,EAAE,IAAI;MACZ,mCAAgB;QACd,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;MACb,6CAA0B;QACxB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,yCAAsB;QACpB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,QAAQ;MACjB,mCAAgB;QACd,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,wCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,QAAQ;MACjB,0CAAuB;QACrB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,oDAAiC;QAC/B,WAAW,EAAE,GAAG;MAClB,gDAA6B;QAC3B,WAAW,EAAE,QAAQ;MACvB,0CAAuB;QACrB,WAAW,EAAE,GAAG;MAClB,+CAA4B;QAC1B,WAAW,EAAE,QAAQ;MACvB,iDAA8B;QAC5B,WAAW,EAAE,GAAG;MAEhB,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,aAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,aAAgB;MAJ/B,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,cAAgB;MAJ/B,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,GAAgB;MAJ/B,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,cAAgB;MAJ/B,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,cAAgB;MAJ/B,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,GAAgB;MAJ/B,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,cAAgB;MAJ/B,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,cAAgB;MAJ/B,gCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,uCAAwB;QACtB,WAAW,EAAE,GAAgB;MAJ/B,iCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,wCAAwB;QACtB,WAAW,EAAE,cAAgB;MAJ/B,iCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,wCAAwB;QACtB,WAAW,EAAE,cAAgB;MAJ/B,iCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAgB;MACzB,wCAAwB;QACtB,WAAW,EAAE,IAAgB;IPiHnC,oCAAsC;MO/GpC,qEAAY;QAEV,IAAI,EAAE,IAAI;MACZ,iEAAU;QAER,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;MACb,qFAAoB;QAElB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,6EAAgB;QAEd,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,QAAQ;MACjB,iEAAU;QAER,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,2EAAe;QAEb,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,QAAQ;MACjB,+EAAiB;QAEf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,mGAA2B;QAEzB,WAAW,EAAE,GAAG;MAClB,2FAAuB;QAErB,WAAW,EAAE,QAAQ;MACvB,+EAAiB;QAEf,WAAW,EAAE,GAAG;MAClB,yFAAsB;QAEpB,WAAW,EAAE,QAAQ;MACvB,6FAAwB;QAEtB,WAAW,EAAE,GAAG;MAEhB,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,aAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,aAAgB;MAN/B,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,cAAgB;MAN/B,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,GAAgB;MAN/B,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,cAAgB;MAN/B,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,cAAgB;MAN/B,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,GAAgB;MAN/B,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,cAAgB;MAN/B,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,cAAgB;MAN/B,2DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,yEAAkB;QAEhB,WAAW,EAAE,GAAgB;MAN/B,6DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,2EAAkB;QAEhB,WAAW,EAAE,cAAgB;MAN/B,6DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,2EAAkB;QAEhB,WAAW,EAAE,cAAgB;MAN/B,6DAAW;QAET,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAgB;MACzB,2EAAkB;QAEhB,WAAW,EAAE,IAAgB;IP0EnC,oCAAuC;MOxErC,sCAAmB;QACjB,IAAI,EAAE,IAAI;MACZ,oCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;MACb,8CAA2B;QACzB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,0CAAuB;QACrB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,QAAQ;MACjB,oCAAiB;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,yCAAsB;QACpB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,QAAQ;MACjB,2CAAwB;QACtB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,qDAAkC;QAChC,WAAW,EAAE,GAAG;MAClB,iDAA8B;QAC5B,WAAW,EAAE,QAAQ;MACvB,2CAAwB;QACtB,WAAW,EAAE,GAAG;MAClB,gDAA6B;QAC3B,WAAW,EAAE,QAAQ;MACvB,kDAA+B;QAC7B,WAAW,EAAE,GAAG;MAEhB,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,aAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,aAAgB;MAJ/B,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,cAAgB;MAJ/B,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,GAAgB;MAJ/B,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,cAAgB;MAJ/B,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,cAAgB;MAJ/B,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,GAAgB;MAJ/B,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,cAAgB;MAJ/B,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,cAAgB;MAJ/B,iCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,wCAAyB;QACvB,WAAW,EAAE,GAAgB;MAJ/B,kCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,yCAAyB;QACvB,WAAW,EAAE,cAAgB;MAJ/B,kCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,yCAAyB;QACvB,WAAW,EAAE,cAAgB;MAJ/B,kCAAkB;QAChB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAgB;MACzB,yCAAyB;QACvB,WAAW,EAAE,IAAgB;IP6CnC,qCAA0C;MO3CxC,yCAAsB;QACpB,IAAI,EAAE,IAAI;MACZ,uCAAoB;QAClB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;MACb,iDAA8B;QAC5B,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,6CAA0B;QACxB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,QAAQ;MACjB,uCAAoB;QAClB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,4CAAyB;QACvB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,QAAQ;MACjB,8CAA2B;QACzB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAG;MACZ,wDAAqC;QACnC,WAAW,EAAE,GAAG;MAClB,oDAAiC;QAC/B,WAAW,EAAE,QAAQ;MACvB,8CAA2B;QACzB,WAAW,EAAE,GAAG;MAClB,mDAAgC;QAC9B,WAAW,EAAE,QAAQ;MACvB,qDAAkC;QAChC,WAAW,EAAE,GAAG;MAEhB,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,aAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,aAAgB;MAJ/B,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,cAAgB;MAJ/B,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,GAAgB;MAJ/B,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,cAAgB;MAJ/B,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,cAAgB;MAJ/B,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,GAAgB;MAJ/B,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,cAAgB;MAJ/B,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,cAAgB;MAJ/B,oCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,GAAgB;MACzB,2CAA4B;QAC1B,WAAW,EAAE,GAAgB;MAJ/B,qCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,4CAA4B;QAC1B,WAAW,EAAE,cAAgB;MAJ/B,qCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,cAAgB;MACzB,4CAA4B;QAC1B,WAAW,EAAE,cAAgB;MAJ/B,qCAAqB;QACnB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAgB;MACzB,4CAA4B;QAC1B,WAAW,EAAE,IAAgB;EAErC,qBAAQ;IACN,WAAW,EAAE,KAAK;IAClB,YAAY,EAAE,KAAK;IACnB,UAAU,EAAE,KAAK;IACjB,gCAAY;MACV,aAAa,EAAE,KAAK;IACtB,sCAAkB;MAChB,aAAa,EAAE,IAAI;IAErB,iCAAa;MACX,eAAe,EAAE,MAAM;IACzB,gCAAY;MACV,WAAW,EAAE,CAAC;MACd,YAAY,EAAE,CAAC;MACf,UAAU,EAAE,CAAC;MACb,2CAAY;QACV,aAAa,EAAE,CAAC;MAClB,iDAAkB;QAChB,aAAa,EAAE,IAAI;MACrB,0CAAW;QACT,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;IPnCd,oCAAsC;MOoCtC,6BAAS;QAGL,SAAS,EAAE,IAAI;QACf,uCAAW;UACT,SAAS,EAAE,QAAQ;UACnB,OAAO,EAAE,IAAI;UACb,KAAK,EAAE,QAAQ;UACf,iDAAW;YACT,WAAW,EAAE,CAAC;IACtB,+BAAW;MACT,OAAO,EAAE,IAAI;IACf,kCAAc;MACZ,SAAS,EAAE,IAAI;IACjB,kCAAc;MACZ,WAAW,EAAE,MAAM;IPnDrB,oCAAsC;MOsDpC,sCAAkB;QAChB,OAAO,EAAE,IAAI;IP3CjB,oCAAuC;MO8CrC,gCAAY;QACV,OAAO,EAAE,IAAI;EC1PnB,cAAE;IACA,aAAa,EAAE,CAAC;EAGlB,8BAAkB;IAChB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,WAAW,ENLK,8BAA8B;IMM9C,UAAU,EAAE,IAAI;IAChB,KAAK,ENLG,IAAI;IMMZ,cAAc,EAAE,SAAS;IACzB,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,mCAAK;MACH,KAAK,ENVG,IAAI;MMWZ,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,GAAG;MAChB,WAAW,ENlBF,kBAAkB;MMmB3B,KAAK,EAAE,KAAK;MACZ,cAAc,EAAE,IAAI;MACpB,2CAAQ;QACN,WAAW,EAAE,IAAI;MAEnB,wCAAK;QACH,OAAO,EAAE,MAAM;EAKrB,yBAAa;IACX,gBAAgB,EAAE,0BAA0B;IAC5C,iBAAiB,EAAE,SAAS;IAC5B,mBAAmB,EAAE,OAAO;IAC5B,uCAAc;MACZ,cAAc,EAAE,MAAM;MACtB,QAAQ,EAAE,QAAQ;MAClB,6CAAM;QACJ,QAAQ,EAAE,QAAQ;QAClB,GAAG,EAAE,GAAG;QACR,SAAS,EAAE,gBAAgB;QAC3B,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,IAAI;QAChB,gDAAG;UACD,UAAU,EAAE,IAAI;UAChB,OAAO,EAAE,YAAY;UACrB,KAAK,EAAE,IAAI;UACX,SAAS,EAAE,IAAI;UACf,KAAK,EN/CH,IAAI;UMgDN,MAAM,EAAE,CAAC;UACT,KAAK,EAAE,IAAI;UACX,QAAQ,EAAE,QAAQ;UAClB,cAAc,EAAE,GAAG;QAErB,gDAAG;UACD,KAAK,ENtDH,IAAI;UMuDN,SAAS,EAAE,IAAI;UACf,UAAU,EAAE,IAAI;UAChB,WAAW,EAAE,IAAI;UACjB,OAAO,EAAE,YAAY;QAEvB,+CAAE;UACA,SAAS,EAAE,IAAI;UACf,GAAG,EAAE,GAAG;UACR,WAAW,EAAE,CAAC;QAEhB,2EAA8B;UAC5B,IAAI,EAAE,IAAI;UACV,YAAY,EAAE,IAAI;UAClB,UAAU,EAAE,qDAAqD;QAEnE,oDAAO;UACL,OAAO,EAAE,KAAK;MAGlB,4CAAK;QACH,SAAS,EAAE,IAAI;QACf,KAAK,ENzEA,IAAI;QM0ET,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,KAAK;IAGlB,mCAAU;MACR,MAAM,EAAE,gBAAgB;MAEtB,+HAA0B;QACxB,WAAW,EAAE,CAAC;MAIhB,6HAA0B;QACxB,cAAc,EAAE,CAAC;EAMzB,qBAAS;IACP,qBAAqB,EAAE,IAAI;IAC3B,kBAAkB,EAAE,IAAI;IACxB,aAAa,EAAE,IAAI;IACnB,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,IAAI;IACX,cAAc,EAAE,SAAS;EAG3B,iCAAqB;IACnB,UAAU,ENhFE,OAAO;IMiFnB,KAAK,EN5GG,IAAI;EM+Gd,gCAAoB;IAClB,gBAAgB,ENxFN,OAAO;IMyFjB,KAAK,ENjHG,IAAI;EMoHd,kCAAsB;IACpB,UAAU,EN1FE,OAAO;IM2FnB,KAAK,ENlHG,OAAO;EMqHjB,gCAAoB;IAClB,UAAU,ENtGF,OAAO;IMuGf,KAAK,ENjGI,OAAO;EMoGlB,iCAAqB;IACnB,UAAU,EAAE,OAAO;IACnB,KAAK,EAAE,IAAI;EAGb,+BAAmB;IACjB,UAAU,EN3GH,OAAO;IM4Gd,KAAK,EAAE,IAAI;EAGb,yBAAa;IACX,KAAK,ENjHK,OAAO;EMoHnB,yBAAa;IACX,KAAK,ENnHI,OAAO;EMsHlB,uBAAW;IACT,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,YAAY;EAGvB,qCAAyB;IACvB,UAAU,EAAE,4CAA4C;IACxD,KAAK,EAAE,IAAI;IACX,eAAe,EAAE,OAAO;EAG1B,iCAAqB;IACnB,UAAU,EAAE,2CAA2C;IACvD,eAAe,EAAE,OAAO;EAG1B,sCAA0B;IACxB,UAAU,EAAE,4CAA4C;IACxD,eAAe,EAAE,OAAO;EAG1B,oCAAwB;IACtB,UAAU,EAAE,6CAA6C;IACzD,eAAe,EAAE,OAAO;EAG1B,kCAAsB;IACpB,UAAU,EAAE,wCAAwC;IACpD,eAAe,EAAE,OAAO;EAG1B,mCAAuB;IACrB,UAAU,EAAE,4CAA4C;IACxD,eAAe,EAAE,OAAO;EAG1B,2BAAe;IACb,gBAAgB,ENxJP,OAAO;IMyJhB,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,MAAM;IACf,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,MAAM;IAClB,qBAAqB,EAAE,GAAG;IAC1B,kBAAkB,EAAE,GAAG;IACvB,aAAa,EAAE,GAAG;IAClB,aAAa,EAAE,IAAI;IACnB,kCAAO;MACL,OAAO,EAAE,KAAK;MACd,WAAW,ENnMG,8BAA8B;MMoM5C,WAAW,EAAE,IAAI;MACjB,UAAU,EAAE,IAAI;MAChB,SAAS,EAAE,IAAI;MACf,cAAc,EAAE,SAAS;IAE3B,+BAAI;MACF,KAAK,ENtMG,IAAI;MMuMZ,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;IAEd,mCAAQ;MACN,QAAQ,EAAE,QAAQ;MAClB,GAAG,EAAE,CAAC;MACN,KAAK,EAAE,CAAC;MACR,KAAK,ENrMG,OAAO;MMsMf,WAAW,EAAE,IAAI;MACjB,WAAW,ENpNG,8BAA8B;MMqN5C,aAAa,EAAE,GAAG;MAClB,WAAW,EAAE,GAAG;MAChB,cAAc,EAAE,SAAS;MACzB,SAAS,EAAE,IAAI;IAEjB,sCAAW;MACT,cAAc,EAAE,GAAG;MACnB,YAAY,EAAE,GAAG;IAEnB,6CAAkB;MAChB,SAAS,EAAE,IAAI;IAEjB,6BAAE;MACA,OAAO,EAAE,YAAY;MACrB,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;EAIhB,iCAAqB;IACnB,gBAAgB,EAAE,OAAO;IACzB,MAAM,EAAE,OAAO;EAGjB;gDACkC;IAChC,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,CAAC;IACN,KAAK,EAAE,CAAC;IACR,YAAY,EAAE,WAAW;IACzB,YAAY,EAAE,KAAK;IACnB,uBAAuB,EAAE,GAAG;EAG9B,+CAAmC;IACjC,YAAY,EAAE,IAAI;IAClB,kBAAkB,EAAE,OAAO;IAC3B,gBAAgB,EAAE,OAAO;EAG3B,8CAAkC;IAChC,kBAAkB,EAAE,OAAO;IAC3B,gBAAgB,EAAE,OAAO;EAG3B,+DAAmD;IACjD,kBAAkB,ENjPN,OAAO;IMkPnB,gBAAgB,ENlPJ,OAAO;EMqPrB,8DAAkD;IAChD,kBAAkB,ENtPN,OAAO;IMuPnB,gBAAgB,ENvPJ,OAAO;EM2PnB,oDAAQ;IACN,KAAK,EN3QG,IAAI;IM4QZ,SAAS,EAAE,IAAI;IACf,MAAM,EAAE,OAAO;IACf,6DAAS;MACP,SAAS,EAAE,IAAI;MACf,KAAK,ENhRC,IAAI;MMiRV,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;EAKlB,kBAAM;IACJ,KAAK,EAAE,IAAI;IACX,UAAU,ENzPA,OAAO;IM0PjB,KAAK,EN5RG,IAAI;IM6RZ,qBAAqB,EAAE,GAAG;IAC1B,kBAAkB,EAAE,GAAG;IACvB,aAAa,EAAE,GAAG;IAClB,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,UAAU;IACtB,UAAU,EAAE,SAAS;IACrB,iCAAe;MACb,KAAK,ENvSC,IAAI;MMwSV,eAAe,EAAE,SAAS;MAC1B,MAAM,EAAE,OAAO;IAGf,gCAAS;MACP,OAAO,EAAE,MAAM;MACf,UAAU,EAAE,IAAI;IAGpB,+BAAa;MACX,UAAU,EAAE,cAAc;MAC1B,OAAO,EAAE,gBAAgB;MACzB,MAAM,EAAE,OAAO;EAInB,6BAAiB;IACf,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE,iBAAsB;EAGhC,2BAAe;IACb,OAAO,EAAE,mBAAmB;IAC5B,6BAAE;MACA,QAAQ,EAAE,QAAQ;MAClB,GAAG,EAAE,IAAI;MACT,IAAI,EAAE,IAAI;EAId,4BAAgB;IACd,UAAU,ENlSF,OAAO;IMmSf,qCAAS;MACP,KAAK,EAAE,kBAAsB;EAIjC,8BAAkB;IAChB,gBAAgB,EN1SN,OAAO;EM6SnB,4BAAgB;IACd,gBAAgB,EN5SR,OAAO;EM+SjB,6BAAiB;IACf,UAAU,ENjUD,OAAO;IMkUhB,sCAAS;MACP,KAAK,EAAE,kBAAkB;EAI7B,6BAAiB;IACf,UAAU,EN1TD,OAAO;IM2ThB,sCAAS;MACP,KAAK,EAAE,kBAAoB;EAI/B,6BAAiB;IACf,YAAY,EAAE,IAAI;IAClB,cAAc,EAAE,CAAC;IACjB,UAAU,EAAE,IAAI;IAChB,+BAAE;MACA,IAAI,EAAE,CAAC;MACP,KAAK,EAAE,IAAI;MACX,WAAW,EAAE,SAAS;MACtB,mBAAmB,EAAE,SAAS;EAIlC,+BAAmB;IACjB,MAAM,EAAE,cAAc;EAItB,sCAAO;IACL,WAAW,EAAE,IAAI;IACjB,KAAK,ENtXC,IAAI;IMuXV,WAAW,EN1XF,kBAAkB;IM2X3B,SAAS,EAAE,IAAI;EAEjB,qCAAM;IACJ,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,IAAI;EAInB,6BAAiB;IACf,OAAO,EAAE,SAAS;EAGpB,sCAA0B;IACxB,YAAY,EAAE,IAAI;IAClB,wCAAE;MACA,QAAQ,EAAE,QAAQ;MAClB,GAAG,EAAE,IAAI;MACT,IAAI,EAAE,IAAI;EAId,yBAAa;IACX,eAAe,EAAE,IAAI;IACrB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,CAAC;IACV,4BAAG;MACD,aAAa,EAAE,IAAI;IAErB,8BAAK;MACH,OAAO,EAAE,QAAQ;MACjB,OAAO,EAAE,KAAK;MACd,WAAW,EAAE,IAAI;MACjB,KAAK,ENxZG,IAAI;MMyZZ,mCAAK;QACH,SAAS,EAAE,IAAI;QACf,KAAK,EN1ZA,IAAI;QM2ZT,KAAK,EAAE,KAAK;QACZ,YAAY,EAAE,IAAI;MAEpB,2CAAa;QACX,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE,GAAG;QACjB,QAAQ,EAAE,QAAQ;QAClB,GAAG,EAAE,IAAI;QACT,KAAK,ENtaD,IAAI;IMyaZ,wEAAqB;MACnB,MAAM,EAAE,OAAO;MACf,UAAU,EAAE,mBAAkB;MAC9B,KAAK,EN5aC,IAAI;MM6aV,qBAAqB,EAAE,IAAI;MAC3B,kBAAkB,EAAE,IAAI;MACxB,aAAa,EAAE,IAAI;MACnB,WAAW,EAAE,GAAG;IAElB,kCAAS;MACP,WAAW,EAAE,GAAG;EAKlB,qBAAI;IACF,WAAW,EAAE,CAAC;EAEhB,oCAAmB;IACjB,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,YAAY;IACrB,YAAY,EAAE,IAAI;EAEpB,0CAAyB;IACvB,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,KAAK;IACd,YAAY,EAAE,IAAI;IAClB,UAAU,EAAE,IAAI;EAGlB,0BAAS;IACP,cAAc,EAAE,IAAI;IACpB,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,CAAC;IAChB,QAAQ,EAAE,QAAQ;IA2DlB,UAAU,EAAE,0BAA+B;IA1D3C,kCAAQ;MAIN,aAAa,EAAE,IAAI;MAHnB,0CAAQ;QACN,cAAc,EAAE,GAAG;MAGrB,yCAAO;QACL,KAAK,ENldH,IAAI;MModR,2GAAsC;QACpC,OAAO,EAAE,YAAY;QACrB,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,GAAG;QAChB,KAAK,ENxdH,IAAI;QMydN,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,CAAC;MAEX,8FAAyB;QACvB,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,IAAI;QACf,KAAK,EN5dF,IAAI;QM6dP,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,MAAM;QACd,4GAAO;UACL,KAAK,ENheJ,IAAI;UMieL,WAAW,EAAE,GAAG;MAGpB,8CAAY;QACV,OAAO,EAAE,MAAM;MAEjB,iDAAe;QACb,WAAW,EAAE,IAAI;MAEnB,6CAAW;QACT,OAAO,EAAE,MAAM;QACf,cAAc,EAAE,GAAG;MAErB,+CAAa;QACX,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,IAAI;QACf,KAAK,ENlfD,IAAI;QMmfR,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,MAAM;QACd,UAAU,EAAE,SAAS;QACrB,sDAAO;UACL,KAAK,ENvfH,IAAI;UMwfN,WAAW,EAAE,GAAG;IAKpB,8CAAM;MACJ,KAAK,ENhgBH,IAAI;MMigBN,OAAO,EAAE,CAAC;MACV,WAAW,EAAE,IAAI;MACjB,WAAW,EAAE,GAAG;EAKtB,uBAAM;IACJ,UAAU,EAAE,IAAI;EAElB,2CAA0B;IACxB,aAAa,EAAE,CAAC;EAElB,sCAAqB;IACnB,YAAY,EAAE,IAAI;EAMlB,4CAAW;IACT,KAAK,EAAE,IAAI;IACX,0DAAc;MACZ,aAAa,EAAE,WAAW;MAC1B,YAAY,EAAE,IAAI;EAIxB,wBAAG;IACD,eAAe,EAAE,IAAI;IACrB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,CAAC;IACV,2BAAG;MACD,QAAQ,EAAE,MAAM;MAChB,aAAa,EAAE,IAAI;MACnB,+BAAI;QACF,qBAAqB,EAAE,IAAI;QAC3B,kBAAkB,EAAE,IAAI;QACxB,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,YAAY;QACrB,cAAc,EAAE,MAAM;MAExB,qCAAU;QACR,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,YAAY;EAKzB,gCAAK;IACH,OAAO,EAAE,YAAY;IACrB,KAAK,EAAE,GAAG;IACV,sCAAM;MACJ,YAAY,EAAE,CAAC;MACf,+BAA+B,EAAE,GAAG;MACpC,kCAAkC,EAAE,GAAG;MACvC,2BAA2B,EAAE,GAAG;MAChC,8BAA8B,EAAE,GAAG;MACnC,uBAAuB,EAAE,GAAG;MAC5B,0BAA0B,EAAE,GAAG;EAGnC,kCAAO;IACL,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,YAAY;IACrB,8BAA8B,EAAE,GAAG;IACnC,iCAAiC,EAAE,GAAG;IACtC,0BAA0B,EAAE,GAAG;IAC/B,6BAA6B,EAAE,GAAG;IAClC,sBAAsB,EAAE,GAAG;IAC3B,yBAAyB,EAAE,GAAG;IAC9B,KAAK,EAAE,KAAK;EAKlB,mCAAuB;IACrB,MAAM,EAAE,iBAAsB;IAC9B,qBAAqB,EAAE,GAAG;IAC1B,kBAAkB,EAAE,GAAG;IACvB,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,IAAI;EAGlB,sBAAU;IACR,aAAa,EAAE,IAAI;IACnB,mCAAa;MACX,QAAQ,EAAE,QAAQ;MAClB,KAAK,EAAE,GAAG;MACV,KAAK,EAAE,IAAI;MACX,yCAAM;QACJ,QAAQ,EAAE,QAAQ;QAClB,GAAG,EAAE,GAAG;QACR,UAAU,EAAE,KAAK;QACjB,IAAI,EAAE,CAAC;MAET,qDAAkB;QAChB,OAAO,EAAE,YAAY;QACrB,SAAS,EAAE,KAAK;QAChB,KAAK,EAAE,IAAI;QACX,YAAY,EAAE,CAAC;QACf,uBAAuB,EAAE,CAAC;QAC1B,0BAA0B,EAAE,CAAC;QAC7B,QAAQ,EAAE,OAAO;QACjB,sEAAiB;UACf,MAAM,EAAE,IAAI;QAEd,4EAAuB;UACrB,MAAM,EAAE,IAAI;MAGhB,2CAAQ;QACN,KAAK,EAAE,IAAI;QACX,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,CAAC;QACd,sBAAsB,EAAE,CAAC;QACzB,yBAAyB,EAAE,CAAC;EAKlC,iBAAK;IACH,KAAK,EAAE,KAAK;IACZ,sBAAK;MACH,YAAY,EAAE,IAAI;MAClB,SAAS,EAAE,IAAI;MACf,KAAK,EN/nBE,IAAI;IMkoBX,uCAAQ;MACN,MAAM,EAAE,CAAC;MACT,UAAU,EAAE,IAAI;MAChB,MAAM,EAAE,iBAAsB;IAEhC,0EAA2C;MACzC,YAAY,EAAE,CAAC;IAEjB,mDAAoB;MAClB,YAAY,EAAE,CAAC;EAMnB,6CAAmB;IACjB,YAAY,EAAE,CAAC;IACf,YAAY,EAAE,CAAC;IACf,uBAAuB,EAAE,CAAC;IAC1B,0BAA0B,EAAE,CAAC;EAE/B,+CAAqB;IACnB,YAAY,EAAE,CAAC;IACf,uBAAuB,EAAE,CAAC;IAC1B,0BAA0B,EAAE,CAAC;IAC7B,WAAW,EAAE,CAAC;IACd,sBAAsB,EAAE,CAAC;IACzB,yBAAyB,EAAE,CAAC;IAC5B,WAAW,EAAE,IAAI;EAEnB,8CAAoB;IAClB,WAAW,EAAE,CAAC;IACd,sBAAsB,EAAE,CAAC;IACzB,yBAAyB,EAAE,CAAC;IAC5B,WAAW,EAAE,IAAI;EAQrB,2BAAe;IACb,QAAQ,EAAE,KAAK;IACf,GAAG,EAAE,CAAC;IACN,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,YAAY,EAAE,IAAI;IAClB,WAAW,EAAE,IAAI;IACjB,wBAAwB;IACxB,KAAK,EAAE,GAAG;IACV,KAAK,ENxrBG,IAAI;IMyrBZ,OAAO,EAAE,MAAM;IACf,yBAAyB,EAAE,GAAG;IAC9B,0BAA0B,EAAE,GAAG;IAC/B,kBAAkB,EAAE,mCAAmC;IACvD,eAAe,EAAE,mCAAmC;IACpD,UAAU,EAAE,mCAAmC;IAC/C,cAAc,EAAE,MAAM;IACtB,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,WAAW;IACvB,MAAM,EAAE,OAAO;EAGjB,uCAA2B;IACzB,UAAU,ENjrBD,OAAO;EMorBlB,8CAAkC;IAChC,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,gBAAgB;IAC7B,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,MAAM;IACtB,YAAY,EAAE,GAAG;IACjB,KAAK,ENtrBE,OAAO;EMyrBhB,oCAAwB;IACtB,UAAU,EN/rBF,OAAO;EMksBjB,2CAA+B;IAC7B,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,oBAAoB;IACjC,SAAS,EAAE,IAAI;IACf,YAAY,EAAE,GAAG;IACjB,cAAc,EAAE,MAAM;IACtB,KAAK,ENlsBI,OAAO;EMqsBlB,0BAAc;IACZ,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,MAAM;EAGpB,yBAAa;IACX,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE,KAAK;EAOf,8BAAkB;IAChB,OAAO,EAAE,YAAY;IACrB,WAAW,EAAE,eAAe;IAC5B,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,CAAC;IACd,sBAAsB,EAAE,WAAW;IACnC,uBAAuB,EAAE,SAAS;IAClC,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,IAAI;EAGjB,yCAA6B;IAC3B,OAAO,EAAE,OAAO;IAChB,KAAK,ENnuBE,OAAO;EMsuBhB,wCAA4B;IAC1B,OAAO,EAAE,OAAO;EAGlB,6CAAiC;IAC/B,OAAO,EAAE,OAAO;IAChB,KAAK,EN7uBK,OAAO;EMgvBnB,wCAA4B;IAC1B,OAAO,EAAE,OAAO;IAChB,KAAK,ENhvBI,OAAO;EMmvBlB,2CAA+B;IAC7B,OAAO,EAAE,OAAO;IAChB,KAAK,ENvvBK,OAAO;IMwvBjB,OAAO,EAAE,CAAC;EAGZ,wCAA4B;IAC1B,KAAK,EN9wBM,OAAO;EMixBpB,uCAA2B;IACzB,KAAK,EN/vBE,OAAO;EMkwBhB,wCAA4B;IAC1B,KAAK,EAAE,OAAO;EAGhB,qBAAS;IACP,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,MAAM;EAGhB,mBAAO;IACL,KAAK,EAAE,IAAI;IAET,yBAAG;MACD,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,IAAI;MACjB,WAAW,EAAE,GAAG;MAChB,OAAO,EAAE,kBAAkB;MAC3B,KAAK,EN5yBD,IAAI;MM6yBR,UAAU,EAAE,IAAI;MAChB,aAAa,EAAE,iBAAiB;IAGlC,yBAAG;MACD,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,IAAI;MACjB,KAAK,ENpzBD,IAAI;MMqzBR,OAAO,EAAE,SAAS;MAClB,UAAU,EAAE,IAAI;MAChB,aAAa,EAAE,iBAAiB;IAElC,4EAA+B;MAC7B,YAAY,EAAE,CAAC;IAKf,sFAAO;MACL,aAAa,EAAE,IAAI;MACnB,cAAc,EAAE,CAAC;EAMzB,yBAAa;IACX,KAAK,ENr0BI,IAAI;IMs0Bb,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,IAAI;EAGnB,8BAAkB;IAChB,OAAO,EAAE,YAAY;ECj1BnB,sDAAU;IACR,MAAM,EAAE,QAAQ;IAChB,wDAAE;MACA,KAAK,EPCD,IAAI;MOAR,MAAM,EAAE,OAAO;MACf,OAAO,EAAE,KAAK;MACd,KAAK,EAAE,IAAI;IAEb,kEAAY;MACV,OAAO,EAAE,KAAK;MACd,MAAM,EAAE,OAAO;MACf,oEAAE;QACA,cAAc,EAAE,GAAG;QACnB,YAAY,EAAE,GAAG;QACjB,gBAAgB,EAAE,2CAA2C;QAC7D,iBAAiB,EAAE,SAAS;QAC5B,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,YAAY;MAEvB,2EAAS;QACP,OAAO,EAAE,EAAE;ECtBnB,iCAAW;IACT,KAAK,EAAE,GAAG;EAEZ,qCAAe;IACb,KAAK,EAAE,GAAG;EAEZ,mCAAa;IACX,gBAAgB,EAAE,8BAA8B;EAGhD,mCAAM;IACJ,UAAU,ERsBL,OAAO;IQrBZ,WAAW,EAAE,iBAAoB;IACjC,OAAO,EAAE,mBAAmB;IAC5B,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE,OAAO;IACf,+CAAY;MACV,OAAO,EAAE,aAAa;MACtB,MAAM,EAAE,OAAO;MAcf,aAAa,EAAE,iBAAsB;MACrC,QAAQ,EAAE,QAAQ;MAdlB,iDAAE;QACA,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,YAAY;QACrB,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,CAAC;QACP,GAAG,EAAE,GAAG;MAEV,8DAAe;QACb,GAAG,EAAE,GAAG;IAKZ,qDAAkB;MAChB,WAAW,EAAE,oBAAoB;MACjC,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,MAAM;MAClB,WAAW,EAAE,MAAM;MACnB,YAAY,EAAE,MAAM;MACpB,cAAc,EAAE,IAAI;MACpB,WAAW,EAAE,CAAC;MACd,SAAS,EAAE,IAAI;MACf,sBAAsB,EAAE,WAAW;MACnC,uBAAuB,EAAE,SAAS;MAClC,OAAO,EAAE,KAAK;MACd,QAAQ,EAAE,QAAQ;MAClB,GAAG,EAAE,GAAG;MACR,KAAK,EAAE,CAAC;IAEV,iDAAc;MACZ,UAAU,EAAE,IAAI;MAChB,UAAU,EAAE,IAAI;MAChB,OAAO,EAAE,gBAAgB;MACzB,qBAAqB,EAAE,GAAG;MAC1B,kBAAkB,EAAE,GAAG;MACvB,aAAa,EAAE,GAAG;MAClB,QAAQ,EAAE,MAAM;MAChB,UAAU,EAAE,eAAe;MAC3B,oDAAG;QACD,WAAW,EAAE,IAAI;QACjB,KAAK,ER3DL,IAAI;QQ4DJ,WAAW,ER/DR,kBAAkB;QQgErB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,IAAI;QACf,cAAc,EAAE,IAAI;MAGpB,kEAAY;QACV,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,KAAK;QACd,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;MAElB,6DAAO;QACL,WAAW,EAAE,CAAC;IAKlB,2DAAK;MAUH,OAAO,EAAE,YAAY;MACrB,WAAW,EAAE,IAAI;MAVjB,6EAAkB;QAChB,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,YAAY;QACrB,cAAc,EAAE,MAAM;QACtB,MAAM,EAAE,MAAM;MAEhB,mEAAQ;QACN,cAAc,EAAE,MAAM;IAQ1B,uDAAO;MACL,KAAK,ERjGL,IAAI;MQkGJ,WAAW,ERrGR,kBAAkB;MQsGrB,OAAO,EAAE,KAAK;MACd,WAAW,EAAE,IAAI;MACjB,aAAa,EAAE,IAAI;MACnB,SAAS,EAAE,IAAI;MACf,cAAc,EAAE,IAAI;IAGxB,mDAAgB;MACd,QAAQ,EAAE,QAAQ;MAClB,mEAAgB;QACd,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,IAAI;EAIhB,0CAAa;IACX,OAAO,EAAE,gBAAgB;IACzB,UAAU,EAAE,IAAI;IAChB,aAAa,EAAE,iBAAsB;IACrC,sDAAY;MACV,aAAa,EAAE,CAAC;MAChB,OAAO,EAAE,gBAAgB;MACzB,wDAAE;QACA,GAAG,EAAE,IAAI;MAEX,qEAAe;QACb,GAAG,EAAE,IAAI;IAGb,4DAAkB;MAChB,OAAO,EAAE,KAAK;MACd,GAAG,EAAE,IAAI;IAEX,wDAAc;MACZ,OAAO,EAAE,IAAI;EAMjB,0DAAe;IACb,UAAU,EAAE,qDAAqD;IACjE,cAAc,EAAE,GAAG;IACnB,YAAY,EAAE,GAAG;EAEnB,iEAAsB;IACpB,OAAO,EAAE,EAAE;EAIf,+CAAyB;IACvB,UAAU,EAAE,iBAAsB;EAEpC,wCAAkB;IAChB,UAAU,EAAE,qBAAqB;EAGjC,yCAAM;IACJ,WAAW,EAAE,iBAAmB;EAKlC,2CAAM;IACJ,WAAW,EAAE,iBAAsB;EAIjC,gEAAE;IACA,GAAG,EAAE,IAAI;EAGb,oEAAkB;IAChB,OAAO,EAAE,EAAE;EAMb,sCAAE;IACA,aAAa,EAAE,CAAC;IAChB,yDAAmB;MACjB,YAAY,EAAE,IAAI;ECzL5B,2BAAe;IACb,QAAQ,EAAE,MAAM;IAChB,KAAK,EAAE,IAAI;IACX,+CAAoB;MAClB,KAAK,EAAE,IAAI;MACX,KAAK,EAAE,IAAI;MACX,mDAAI;QACF,OAAO,EAAE,YAAY;QACrB,cAAc,EAAE,GAAG;QACnB,YAAY,EAAE,IAAI;MAEpB,oDAAK;QACH,WAAW,EAAE,IAAI;QACjB,WAAW,ETXC,8BAA8B;QSY1C,SAAS,EAAE,IAAI;IAGnB,8CAAmB;MACjB,UAAU,EAAE,OAAO;MACnB,qBAAqB,EAAE,GAAG;MAC1B,kBAAkB,EAAE,GAAG;MACvB,aAAa,EAAE,GAAG;MAClB,MAAM,EAAE,IAAI;MACZ,QAAQ,EAAE,MAAM;MAChB,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,IAAI;MAChB,QAAQ,EAAE,QAAQ;MAClB,mDAAK;QACH,UAAU,ETlBH,OAAO;QSmBd,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,YAAY;QACrB,QAAQ,EAAE,QAAQ;QAClB,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,kBAAkB,EAAE,wBAAwB;QAC5C,eAAe,EAAE,wBAAwB;QACzC,UAAU,EAAE,wBAAwB;EAMxC,+EAAa;IACX,gBAAgB,EAAE,iCAAiC;IACnD,2GAAc;MACZ,YAAY,EAAE,IAAI;MAClB,aAAa,EAAE,CAAC;MAChB,mHAAI;QACF,KAAK,EAAE,GAAG;EAKd,yFAAa;IACX,KAAK,EAAE,GAAG;EAEZ,iGAAiB;IACf,KAAK,EAAE,GAAG;EAId,6GAA4B;IAC1B,KAAK,EAAE,IAAI;EAGb,iEAAM;IACJ,KAAK,EAAE,IAAI;IACX,aAAa,EAAE,IAAI;IACnB,eAAe,EAAE,QAAQ;IACzB,gJAAO;MACL,aAAa,EAAE,iBAAsB;IAGrC,mFAAG;MACD,WAAW,ETzEN,kBAAkB;MS0EvB,UAAU,EAAE,IAAI;MAChB,WAAW,EAAE,IAAI;MACjB,KAAK,ETzEH,IAAI;MS0EN,cAAc,EAAE,GAAG;MACnB,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,IAAI;MACjB,WAAW,EAAE,MAAM;IAKnB,yFAAG;MACD,OAAO,EAAE,cAAc;MACvB,6FAAE;QACA,KAAK,ETnFL,IAAI;QSoFJ,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,IAAI;MAGnB,yHAAgB;QACd,WAAW,EAAE,KAAK;QAClB,KAAK,EAAE,IAAI;IAGf,sNAAwB;MACtB,KAAK,EAAE,IAAI;MACX,cAAc,EAAE,MAAM;IAExB,gOAA6B;MAC3B,KAAK,ETpGL,IAAI;MSqGJ,WAAW,EAAE,IAAI;MACjB,KAAK,EAAE,GAAG;MACV,aAAa,EAAE,IAAI;MACnB,oPAAK;QACH,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,IAAI;QACf,KAAK,ETxGN,IAAI;IS2GP,6VAAkD;MAChD,SAAS,EAAE,IAAI;MACf,cAAc,EAAE,MAAM;IAExB,sOAAgC;MAC9B,UAAU,EAAE,MAAM;MAClB,KAAK,EAAE,IAAI;MACX,8OAAE;QACA,UAAU,EAAE,WAAW;QACvB,OAAO,EAAE,SAAS;MAEpB,sQAAQ;QACN,UAAU,ETxFV,OAAO;MS0FT,0QAAS;QACP,UAAU,ETlGR,OAAO;ESwGnB,+EAAa;IACX,gBAAgB,EAAE,mCAAmC;IACrD,iBAAiB,EAAE,SAAS;IAC5B,mBAAmB,EAAE,OAAO;IAC5B,cAAc,EAAE,KAAK;IACrB,QAAQ,EAAE,QAAQ;IAClB,2GAAc;MACZ,QAAQ,EAAE,QAAQ;MAClB,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,IAAI;MACjB,MAAM,EAAE,IAAI;MACZ,IAAI,EAAE,KAAK;MACX,mHAAI;QACF,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,IAAI;EAIjB,+EAAa;IACX,aAAa,EAAE,CAAC;IAChB,cAAc,EAAE,CAAC;IACjB,kNAA0B;MACxB,OAAO,EAAE,KAAK;MACd,SAAS,EAAE,IAAI;IAEjB,yGAAa;MACX,KAAK,ET3JC,IAAI;MS4JV,UAAU,EAAE,IAAI;IAElB,uGAAY;MACV,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;EAInB,+EAAE;IACA,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;EAEnB,iFAAG;IACD,MAAM,EAAE,gBAAgB;IACxB,qGAAU;MACR,OAAO,EAAE,GAAG;MACZ,YAAY,EAAE,GAAG;IAEnB,uFAAG;MACD,KAAK,ET9KF,IAAI;MS+KP,aAAa,EAAE,GAAG;MAClB,WAAW,EAAE,IAAI;MACjB,SAAS,EAAE,IAAI;MACf,WAAW,ETxLN,kBAAkB;MSyLvB,WAAW,EAAE,MAAM;EAIzB,+EAAa;IACX,SAAS,EAAE,IAAI;IACf,yFAAK;MACH,OAAO,EAAE,YAAY;MACrB,KAAK,EAAE,GAAG;MACV,KAAK,EAAE,IAAI;EAGf,iGAAsB;IACpB,SAAS,EAAE,GAAG;EAIZ,qFAAE;IACA,aAAa,EAAE,CAAC;IAChB,2HAAmB;MACjB,YAAY,EAAE,IAAI;IAEpB,+GAAa;MACX,KAAK,EAAE,KAAK;EC/MlB,wCAAa;IACX,KAAK,EAAE,GAAG;EAEZ,4CAAiB;IACf,KAAK,EAAE,GAAG;EAGd,mCAAa;IACX,gBAAgB,EAAE,6BAA6B;IAC/C,iBAAiB,EAAE,SAAS;IAC5B,mBAAmB,EAAE,SAAS;IAC9B,4CAAS;MACP,UAAU,EAAE,KAAK;MAEf,gEAAM;QACJ,KAAK,EAAE,GAAG;MAGd,kDAAM;QACJ,QAAQ,EAAE,QAAQ;QAClB,yEAAuB;UACrB,KAAK,EAAE,GAAG;UACV,QAAQ,EAAE,QAAQ;UAClB,GAAG,EAAE,GAAG;UACR,SAAS,EAAE,gBAAgB;EAMjC,6CAAa;IACX,KAAK,EAAE,GAAG;IACV,YAAY,EAAE,CAAC;EAGnB,+BAAS;IACP,gBAAgB,EAAE,mCAAmC;IACrD,iBAAiB,EAAE,SAAS;IAC5B,mBAAmB,EAAE,OAAO;IAE1B,iDAAI;MACF,KAAK,EAAE,GAAG;MACV,SAAS,EAAE,IAAI;MACf,gBAAgB,EAAE,OAAO;MACzB,KAAK,EV1CH,IAAI;MU2CN,WAAW,EAAE,IAAI;EAIvB,mCAAa;IACX,MAAM,EAAE,qBAAqB;IAC7B,2CAAQ;MACN,KAAK,EAAE,IAAI;MACX,8FAAO;QACL,aAAa,EAAE,iBAAsB;QACrC,cAAc,EAAE,IAAI;MAGpB,oDAAG;QACD,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,IAAI;QACf,KAAK,EV5DL,IAAI;QU6DJ,OAAO,EAAE,gBAAgB;QACzB,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,MAAM;QACnB,sDAAE;UACA,OAAO,EAAE,CAAC;UACV,MAAM,EAAE,CAAC;UACT,KAAK,EVnEP,IAAI;MUyEJ,6DAAK;QACH,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,IAAI;QACjB,cAAc,EAAE,GAAG;QACnB,sEAAS;UACP,SAAS,EAAE,IAAI;UACf,OAAO,EAAE,KAAK;UACd,WAAW,EAAE,IAAI;MAGrB,yEAAiB;QACf,KAAK,EAAE,GAAG;QACV,OAAO,EAAE,SAAS;MAEpB,gFAAwB;QACtB,OAAO,EAAE,EAAE;QACX,UAAU,EAAE,sCAAsC;QAClD,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,eAAe,EAAE,OAAO;QACxB,OAAO,EAAE,YAAY;QACrB,cAAc,EAAE,GAAG;QACnB,YAAY,EAAE,IAAI;MAEpB,0EAAkB;QAChB,WAAW,EAAE,MAAM;MAErB,0EAAkB;QAChB,WAAW,EAAE,MAAM;MAErB,wEAAgB;QACd,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,SAAS;QAClB,4EAAI;UACF,KAAK,EV1GP,IAAI;UU2GF,SAAS,EAAE,IAAI;UACf,cAAc,EAAE,MAAM;UACtB,8EAAE;YACA,SAAS,EAAE,IAAI;MAKvB,gEAAa;QACX,MAAM,EAAE,OAAO;MAGf,qFAAsB;QACpB,KAAK,EVjGR,OAAO;MUqGN,oFAAsB;QACpB,KAAK,EVvGL,OAAO;MU0GX,mEAAgB;QAkCd,UAAU,EVlIR,OAAO;QUiGT,4FAAyB;UACvB,UAAU,EAAE,IAAI;UAChB,KAAK,EAAE,IAAI;UACX,OAAO,EAAE,KAAK;UACd,UAAU,EAAE,iBAAsB;UAClC,MAAM,EAAE,IAAI;UACZ,WAAW,EAAE,CAAC;UACd,cAAc,EAAE,CAAC;QAEnB,oFAAiB;UACf,UAAU,EAAE,IAAI;UAChB,WAAW,EAAE,CAAC;UAEZ,wGAAO;YACL,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI;YACjB,WAAW,EAAE,IAAI;UAEnB,mGAAE;YACA,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI;YACjB,KAAK,EVrJV,IAAI;UUuJD,uGAAM;YACJ,KAAK,EAAE,IAAI;YACX,sNAAO;cACL,MAAM,EAAE,IAAI;cACZ,KAAK,EAAE,GAAG;cACV,OAAO,EAAE,CAAC;MAOpB,6DAAU;QACR,UAAU,EVrIR,OAAO;QUsIT,gEAAG;UACD,aAAa,EAAE,IAAI;EAO3B,6CAAS;IACP,cAAc,EAAE,SAAS;IACzB,OAAO,EAAE,KAAK;IACd,aAAa,EAAE,IAAI;IACnB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;EAGnB,6CAAS;IACP,aAAa,EAAE,IAAI;IACnB,aAAa,EAAE,IAAI;IACnB,qDAAQ;MACN,cAAc,EAAE,CAAC;MACjB,2DAAM;QACJ,aAAa,EAAE,CAAC;MAElB,oEAAe;QACb,KAAK,EAAE,KAAK;EAKhB,mDAAO;IACL,KAAK,EAAE,IAAI;IACX,YAAY,EAAE,IAAI;IAClB,yDAAM;MACJ,OAAO,EAAE,YAAY;MACrB,OAAO,EAAE,CAAC;EC7MhB,yCAAa;IACX,KAAK,EAAE,GAAG;EAEZ,6CAAiB;IACf,KAAK,EAAE,GAAG;EAIZ,sDAAO;IACL,OAAO,EAAE,MAAM;EAEjB,mEAAoB;IAClB,MAAM,EAAE,eAAe;EAG3B,6BAAM;IACJ,KAAK,EAAE,IAAI;IACX,aAAa,EAAE,IAAI;IACnB,kEAAO;MACL,aAAa,EAAE,iBAAsB;IAGrC,kDAAe;MACb,YAAY,EAAE,IAAI;IAEpB,iDAAc;MACZ,aAAa,EAAE,IAAI;IAErB,sCAAG;MACD,WAAW,EX7BD,8BAA8B;MW8BxC,UAAU,EAAE,IAAI;MAChB,WAAW,EAAE,IAAI;MACjB,KAAK,EX9BH,IAAI;MW+BN,OAAO,EAAE,GAAG;MACZ,cAAc,EAAE,IAAI;MACpB,wCAAE;QACA,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,KAAK,EXpCL,IAAI;IW0CN,0DAAG;MACD,OAAO,EAAE,KAAK;MACd,SAAS,EAAE,IAAI;IAEjB,sEAAe;MACb,KAAK,EAAE,GAAG;MACV,YAAY,EAAE,IAAI;MAClB,aAAa,EAAE,IAAI;MACnB,UAAU,EAAE,uBAAuB;MACnC,KAAK,EXnDL,IAAI;MWoDJ,6FAAuB;QACrB,YAAY,EAAE,IAAI;MAEpB,6EAAO;QACL,UAAU,EXpBV,OAAO;QWqBP,qBAAqB,EAAE,GAAG;QAC1B,kBAAkB,EAAE,GAAG;QACvB,aAAa,EAAE,GAAG;QAClB,SAAS,EAAE,IAAI;QACf,KAAK,EX7DP,IAAI;QW8DF,WAAW,EXhEL,8BAA8B;QWiEpC,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,QAAQ;QACjB,YAAY,EAAE,IAAI;QAClB,cAAc,EAAE,SAAS;IAG7B,qEAAc;MACZ,aAAa,EAAE,IAAI;IAErB,0DAAG;MACD,OAAO,EAAE,MAAM;MACf,MAAM,EAAE,OAAO;IAEjB,iEAAU;MACR,UAAU,EAAE,MAAM;IAIpB,6KAAsB;MACpB,UAAU,EX7DT,OAAO;IWgEZ,8DAA2B;MACzB,UAAU,EAAE,OAAO;MACnB,iEAAG;QACD,aAAa,EAAE,eAAe;IAGlC,iDAAc;MACZ,UAAU,EAAE,OAAO;MACnB,oDAAG;QACD,OAAO,EAAE,SAAS;QAClB,UAAU,EAAE,uBAAuB;QACnC,UAAU,EAAE,IAAI;QAChB,sDAAE;UACA,aAAa,EAAE,GAAG;UAClB,SAAS,EAAE,IAAI;UACf,WAAW,EAAE,IAAI;UACjB,6DAAO;YACL,WAAW,EAAE,GAAG;YAChB,KAAK,EXvGT,IAAI;QW0GJ,+DAAW;UACT,OAAO,EAAE,YAAY;UACrB,YAAY,EAAE,IAAI;UAClB,aAAa,EAAE,GAAG;EAM5B,4CAAqB;IACnB,OAAO,EAAE,MAAM;IACf,qDAAS;MACP,aAAa,EAAE,IAAI;MACnB,aAAa,EAAE,IAAI;MACnB,UAAU,EAAE,IAAI;MAChB,6DAAQ;QACN,cAAc,EAAE,CAAC;QACjB,mEAAM;UACJ,aAAa,EAAE,CAAC;QAElB,oEAAO;UACL,OAAO,EAAE,KAAK;UACd,SAAS,EAAE,IAAI;UACf,WAAW,EAAE,IAAI;UACjB,KAAK,EX/HJ,IAAI;EWqIX,8CAAa;IACX,YAAY,EAAE,CAAC;IACf,KAAK,EAAE,GAAG;IACV,gDAAE;MACA,WAAW,EAAE,IAAI;EAKrB,iDAAO;IACL,KAAK,EX/IA,IAAI;EWiJX,mDAAS;IACP,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,CAAC;IAChB,cAAc,EAAE,CAAC;IACjB,2DAAQ;MAKN,cAAc,EAAE,CAAC;MAJjB,iEAAM;QACJ,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,CAAC;EC9JlB,kCAAI;IACF,YAAY,EAAE,GAAG;IACjB,wCAAM;MACJ,KAAK,EAAE,IAAI;MACX,aAAa,EAAE,IAAI;IAErB,8CAAY;MACV,aAAa,EAAE,iBAAiB;MAChC,yBAAyB,EAAE,CAAC;MAC5B,0BAA0B,EAAE,CAAC;MAC7B,aAAa,EAAE,CAAC;IAGlB,sDAAoB;MAClB,KAAK,EAAE,OAAO;MACd,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,IAAI;MACjB,aAAa,EAAE,IAAI;IAErB,wCAAM;MACJ,KAAK,EAAE,OAAO;MACd,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,GAAG;MAChB,WAAW,EAAE,IAAI;MACjB,OAAO,EAAE,CAAC;MACV,WAAW,EZzBJ,kBAAkB;MY0BzB,6CAAK;QACH,WAAW,EAAE,GAAG;EC1BpB,8CAAa;IACX,KAAK,EAAE,GAAG;EAEZ,kDAAiB;IACf,KAAK,EAAE,GAAG;EAGd,0DAA8B;IAC5B,UAAU,EAAE,qDAAqD;IACjE,IAAI,EAAE,IAAI;IACV,YAAY,EAAE,IAAI;EAEpB,wCAAY;IACV,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAAE,CAAC;EAEV,wDAA4B;IAC1B,IAAI,EAAE,CAAC;EAGT,qCAAS;IACP,UAAU,EAAE,IAAI;IAChB,4CAAO;MACL,KAAK,EAAE,OAAO;MACd,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,GAAG;MAChB,WAAW,EAAE,IAAI;IAEnB,0CAAK;MACH,OAAO,EAAE,KAAK;MACd,KAAK,EAAE,OAAO;MACd,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,IAAI;MACjB,aAAa,EAAE,IAAI;IAInB,gDAAK;MACH,KAAK,EAAE,IAAI;MACX,aAAa,EAAE,CAAC;IAKlB,yDAAE;MACA,OAAO,EAAE,GAAG;MACZ,KAAK,EAAE,OAAO;MACd,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,IAAI;MACjB,WAAW,EAAE,IAAI;MACjB,eAAe,EAAE,IAAI;MACrB,cAAc,EAAE,SAAS;IAE3B,+DAAQ;MACN,OAAO,EAAE,CAAC;EC1DlB,wBAAY;IACV,OAAO,EAAE,IAAI;EhBkMb,2DAAsE;IgB9LtE,yBAAa;MACX,gBAAgB,EAAE,eAAe;MACjC,uCAAc;QAKZ,QAAQ,EAAE,MAAM;QAJhB,2CAAI;UACF,KAAK,EAAE,eAAe;UACtB,UAAU,EAAE,MAAM;IAKxB,yBAAa;MACX,cAAc,EAAE,gBAAgB;IAGhC,6CAAmB;MACjB,KAAK,EAAE,KAAK;IAEd,+CAAqB;MACnB,uBAAuB,EAAE,GAAG;MAC5B,0BAA0B,EAAE,GAAG;MAC/B,WAAW,EAAE,CAAC;MACd,sBAAsB,EAAE,CAAC;MACzB,yBAAyB,EAAE,CAAC;IAE9B,8CAAoB;MAClB,sBAAsB,EAAE,GAAG;MAC3B,yBAAyB,EAAE,GAAG;MAC9B,KAAK,EAAE,IAAI;IAIb,qCAAU;MACR,KAAK,EAAE,IAAI;MACX,aAAa,EAAE,CAAC;EhBqJpB,oCAA4C;IgB/I5C,wBAAY;MACV,OAAO,EAAE,IAAI;IAEf,yBAAa;MACX,gBAAgB,EAAE,eAAe;MACjC,qCAAY;QACV,MAAM,EAAE,CAAC;MAGT,6CAAM;QACJ,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,MAAM;QAClB,aAAa,EAAE,IAAI;QACnB,QAAQ,EAAE,QAAQ;QAClB,GAAG,EAAE,CAAC;QACN,SAAS,EAAE,IAAI;IAQb,8DAAI;MACF,KAAK,EAAE,IAAI;IAIb,yEAAuB;MACrB,KAAK,EAAE,IAAI;MACX,GAAG,EAAE,CAAC;MACN,SAAS,EAAE,IAAI;MACf,QAAQ,EAAE,QAAQ;IAO5B,4EAAsC;MACpC,KAAK,EAAE,eAAe;MACtB,OAAO,EAAE,YAAY;MACrB,OAAO,EAAE,gBAAgB;IAKrB,iDAAI;MACF,KAAK,EAAE,IAAI;IAKnB,yBAAa;MACX,cAAc,EAAE,gBAAgB;IAGhC,6CAAmB;MACjB,GAAG,EAAE,GAAG;MACR,QAAQ,EAAE,QAAQ;IAEpB,+CAAqB;MACnB,uBAAuB,EAAE,GAAG;MAC5B,0BAA0B,EAAE,GAAG;MAC/B,WAAW,EAAE,CAAC;MACd,sBAAsB,EAAE,CAAC;MACzB,yBAAyB,EAAE,CAAC;MAC5B,YAAY,EAAE,IAAI;IAEpB,8CAAoB;MAClB,sBAAsB,EAAE,GAAG;MAC3B,yBAAyB,EAAE,GAAG;IAIhC,wCAAc;MACZ,UAAU,EAAE,IAAI;IAGpB,2BAAe;MACb,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,IAAI;MACjB,OAAO,EAAE,SAAS;MAClB,KAAK,EAAE,IAAI;MACX,aAAa,EAAE,CAAC;MAChB,UAAU,EAAE,MAAM;IAEpB,6FAAoE;MAClE,OAAO,EAAE,EAAE;;AZtFf,qBAAsB;EACpB,SAAS,EAAE,IAAI;EACf,MAAM,EAAE,CAAC",
|
4 |
-
"sources": ["../scss/mixins.sass","../scss/override.scss","../scss/vars.scss","../scss/sale.scss","../scss/main.scss","../scss/misc.scss","../scss/helpers.sass","../scss/grid.sass","../scss/components.scss","../scss/dashboard.scss","../scss/hardener.scss","../scss/scan.scss","../scss/audit.scss","../scss/ip-lockout.scss","../scss/register-modal.scss","../scss/auth.scss","../scss/mobile.scss"],
|
5 |
-
"names": [],
|
6 |
-
"file": "styles.css"
|
7 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/email-assets/img/Blue-Copy.png
ADDED
Binary file
|
assets/email-assets/img/Blue-Copy@2x.png
ADDED
Binary file
|
assets/email-assets/img/Defender-widerec.png
ADDED
Binary file
|
assets/email-assets/img/Defender-widerec@2x.png
ADDED
Binary file
|
assets/email-assets/img/Warning.png
ADDED
Binary file
|
assets/email-assets/img/Warning@2x.png
ADDED
Binary file
|
readme.txt
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
=== Defender Security, Monitoring, and Hack Protection ===
|
2 |
Plugin Name: Defender Security, Monitoring, and Hack Protection
|
3 |
-
Version: 2.1.
|
4 |
Author: WPMU DEV
|
5 |
Author URI: http://premium.wpmudev.org/
|
6 |
Contributors: WPMUDEV
|
7 |
Tags: Security, Security Tweaks, Hardening, IP lockout, Monitoring, Blacklist, Site Protection, Hacked, Security Scan
|
8 |
Requires at least: 4.6
|
9 |
Tested up to: 5.1.1
|
10 |
-
Stable tag: 2.1.
|
11 |
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
12 |
|
13 |
Protect WordPress from hackers with security tweaks, code scans, 2-Step Verification, IP lockouts, and monitoring.
|
@@ -122,6 +122,31 @@ Hackers and bot attacks are not the only threat to your site. No matter what se
|
|
122 |
|
123 |
== Changelog ==
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
= 2.1.2 =
|
126 |
- Feature: Defender Pro now supports the WPMU DEV Dashboard’s white label feature.
|
127 |
- Feature: You can now perform a factory reset of Defender’s settings via the Settings screen, as well as control what happens to data when the plugin is uninstalled.
|
1 |
=== Defender Security, Monitoring, and Hack Protection ===
|
2 |
Plugin Name: Defender Security, Monitoring, and Hack Protection
|
3 |
+
Version: 2.1.4
|
4 |
Author: WPMU DEV
|
5 |
Author URI: http://premium.wpmudev.org/
|
6 |
Contributors: WPMUDEV
|
7 |
Tags: Security, Security Tweaks, Hardening, IP lockout, Monitoring, Blacklist, Site Protection, Hacked, Security Scan
|
8 |
Requires at least: 4.6
|
9 |
Tested up to: 5.1.1
|
10 |
+
Stable tag: 2.1.4
|
11 |
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
12 |
|
13 |
Protect WordPress from hackers with security tweaks, code scans, 2-Step Verification, IP lockouts, and monitoring.
|
122 |
|
123 |
== Changelog ==
|
124 |
|
125 |
+
= 2.1.4 =
|
126 |
+
- Fix: Mask Login cause issue when visiting /wp-admin/network/sites.php
|
127 |
+
|
128 |
+
= 2.1.3 =
|
129 |
+
- Feature: Security tweaks will send reminder when no tweaks were actioned after activation
|
130 |
+
- Improvement: Scanning will be more catchy, especially with code using eval function, however that can lead to more false positive, please consider to check with our support before delete the file.
|
131 |
+
- Fix: Bring back the tooltips system
|
132 |
+
- Fix: Audit filter links doesn't reflect the right results if open in new tab
|
133 |
+
- Fix: Filtering issue type in scanning now show correct results.
|
134 |
+
- Fix: Scanning notification keep sending when the setting turn to "off"
|
135 |
+
- Fix: User IP in IP Lockout->Blacklist now show the correct IP.
|
136 |
+
- Fix: Bring back the subject customization field in Scanning email config.
|
137 |
+
- Fix: Manage Login Duration wont make user to login twice anymore.
|
138 |
+
- Fix: Audit filtering by user now working properly
|
139 |
+
- Fix: We change the Audit logging items' color from red to more neutral.
|
140 |
+
- Fix: Ad Widget won't be show in vulnerability list by accident anymore
|
141 |
+
- Fix: Bottom bulk selector in Scanning page now work properly
|
142 |
+
- Fix: Deprecate warning from the function strpos() in php 7.3
|
143 |
+
- Fix: Sync issues with HUB will be more consistent.
|
144 |
+
- Fix: Mask login doesn't work properly if Wordpress get installed in a sub-folder
|
145 |
+
- Fix: Conflict with Avada theme which making scanning stuck
|
146 |
+
- Fix: Gracefully handle error when php dom extension does not install
|
147 |
+
- Fix: Prevent factory reset revert database prefix into wp_ even though it was not set by Defender.
|
148 |
+
- Fix: Prevent slashes added in email template
- Fix: Minor grammar and UX improvements.
|
149 |
+
|
150 |
= 2.1.2 =
|
151 |
- Feature: Defender Pro now supports the WPMU DEV Dashboard’s white label feature.
|
152 |
- Feature: You can now perform a factory reset of Defender’s settings via the Settings screen, as well as control what happens to data when the plugin is uninstalled.
|
vendor/hammer/base/db-model.php
CHANGED
@@ -284,7 +284,7 @@ class DB_Model extends Model {
|
|
284 |
), array_merge( array( $sql ), $attribute ) );
|
285 |
$condition[] = $sql;
|
286 |
}
|
287 |
-
} elseif ( strpos( '%', $attribute ) === 0 ) {
|
288 |
$condition[] = $wpdb->prepare( $key . ' LIKE %s', $attribute );
|
289 |
} else {
|
290 |
$condition[] = $wpdb->prepare( $key . ' = %s', $attribute );
|
284 |
), array_merge( array( $sql ), $attribute ) );
|
285 |
$condition[] = $sql;
|
286 |
}
|
287 |
+
} elseif ( strlen( $attribute ) && strpos( '%', (string) $attribute ) === 0 ) {
|
288 |
$condition[] = $wpdb->prepare( $key . ' LIKE %s', $attribute );
|
289 |
} else {
|
290 |
$condition[] = $wpdb->prepare( $key . ' = %s', $attribute );
|
vendor/hammer/wp/model.php
CHANGED
@@ -141,7 +141,6 @@ abstract class Model extends \Hammer\Base\Model {
|
|
141 |
if ( ! empty( $limit ) ) {
|
142 |
$sql .= ' LIMIT ' . $limit;
|
143 |
}
|
144 |
-
|
145 |
$ids = self::getWPDB()->get_col( $sql );
|
146 |
|
147 |
foreach ( $ids as $id ) {
|
@@ -219,6 +218,7 @@ abstract class Model extends \Hammer\Base\Model {
|
|
219 |
$fields = static::buildFields();
|
220 |
$join = static::buildJoins();
|
221 |
$where = static::buildWhere( $attributes );
|
|
|
222 |
$sql = "SELECT " . implode( ',', $fields ) . " FROM " . static::getWPDB()->posts . ' AS t0';
|
223 |
$sql = $sql . ' ' . implode( ' ', $join ) . ' ' . implode( ' AND ', $where );
|
224 |
$sql = $sql . ' GROUP BY ID';
|
@@ -371,7 +371,6 @@ abstract class Model extends \Hammer\Base\Model {
|
|
371 |
$sql = $wpdb->prepare( $sql, $value['value'] );
|
372 |
} elseif ( ! empty( $value ) ) {
|
373 |
$sql = 't' . $pos . "." . $field . " IN (" . implode( ', ', array_fill( 0, count( $value ), '%s' ) ) . ")";
|
374 |
-
|
375 |
$sql = call_user_func_array( array( $wpdb, 'prepare' ), array_merge( array( $sql ), $value ) );
|
376 |
} else {
|
377 |
//this case the in array is empty,
|
141 |
if ( ! empty( $limit ) ) {
|
142 |
$sql .= ' LIMIT ' . $limit;
|
143 |
}
|
|
|
144 |
$ids = self::getWPDB()->get_col( $sql );
|
145 |
|
146 |
foreach ( $ids as $id ) {
|
218 |
$fields = static::buildFields();
|
219 |
$join = static::buildJoins();
|
220 |
$where = static::buildWhere( $attributes );
|
221 |
+
|
222 |
$sql = "SELECT " . implode( ',', $fields ) . " FROM " . static::getWPDB()->posts . ' AS t0';
|
223 |
$sql = $sql . ' ' . implode( ' ', $join ) . ' ' . implode( ' AND ', $where );
|
224 |
$sql = $sql . ' GROUP BY ID';
|
371 |
$sql = $wpdb->prepare( $sql, $value['value'] );
|
372 |
} elseif ( ! empty( $value ) ) {
|
373 |
$sql = 't' . $pos . "." . $field . " IN (" . implode( ', ', array_fill( 0, count( $value ), '%s' ) ) . ")";
|
|
|
374 |
$sql = call_user_func_array( array( $wpdb, 'prepare' ), array_merge( array( $sql ), $value ) );
|
375 |
} else {
|
376 |
//this case the in array is empty,
|
vendor/php_codesniffer-3.4.0/CONTRIBUTING.md
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Contributing
|
2 |
+
-------------
|
3 |
+
|
4 |
+
Before you contribute code to PHP\_CodeSniffer, please make sure it conforms to the PHPCS coding standard and that the PHP\_CodeSniffer unit tests still pass. The easiest way to contribute is to work on a checkout of the repository, or your own fork, rather than an installed PEAR version. If you do this, you can run the following commands to check if everything is ready to submit:
|
5 |
+
|
6 |
+
cd PHP_CodeSniffer
|
7 |
+
php bin/phpcs
|
8 |
+
|
9 |
+
Which should display no coding standard errors. And then:
|
10 |
+
|
11 |
+
phpunit
|
12 |
+
|
13 |
+
Which should give you no failures or errors. You can ignore any skipped tests as these are for external tools.
|
vendor/php_codesniffer-3.4.0/CodeSniffer.conf.dist
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$phpCodeSnifferConfig = array (
|
3 |
+
'default_standard' => 'PSR2',
|
4 |
+
'report_format' => 'summary',
|
5 |
+
'show_warnings' => '0',
|
6 |
+
'show_progress' => '1',
|
7 |
+
'report_width' => '120',
|
8 |
+
)
|
9 |
+
?>
|
vendor/php_codesniffer-3.4.0/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## About
|
2 |
+
|
3 |
+
PHP\_CodeSniffer is a set of two PHP scripts; the main `phpcs` script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second `phpcbf` script to automatically correct coding standard violations. PHP\_CodeSniffer is an essential development tool that ensures your code remains clean and consistent.
|
4 |
+
|
5 |
+
[![Build Status](https://travis-ci.org/squizlabs/PHP_CodeSniffer.svg?branch=phpcs-fixer)](https://travis-ci.org/squizlabs/PHP_CodeSniffer) [![Code consistency](http://squizlabs.github.io/PHP_CodeSniffer/analysis/squizlabs/PHP_CodeSniffer/grade.svg)](http://squizlabs.github.io/PHP_CodeSniffer/analysis/squizlabs/PHP_CodeSniffer) [![Join the chat at https://gitter.im/squizlabs/PHP_CodeSniffer](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/squizlabs/PHP_CodeSniffer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
6 |
+
|
7 |
+
## Requirements
|
8 |
+
|
9 |
+
PHP\_CodeSniffer requires PHP version 5.4.0 or greater, although individual sniffs may have additional requirements such as external applications and scripts. See the [Configuration Options manual page](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options) for a list of these requirements.
|
10 |
+
|
11 |
+
## Installation
|
12 |
+
|
13 |
+
The easiest way to get started with PHP\_CodeSniffer is to download the Phar files for each of the commands:
|
14 |
+
```
|
15 |
+
# Download using curl
|
16 |
+
curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
|
17 |
+
curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar
|
18 |
+
|
19 |
+
# Or download using wget
|
20 |
+
wget https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
|
21 |
+
wget https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar
|
22 |
+
|
23 |
+
# Then test the downloaded PHARs
|
24 |
+
php phpcs.phar -h
|
25 |
+
php phpcbf.phar -h
|
26 |
+
```
|
27 |
+
|
28 |
+
### Composer
|
29 |
+
If you use Composer, you can install PHP_CodeSniffer system-wide with the following command:
|
30 |
+
|
31 |
+
composer global require "squizlabs/php_codesniffer=*"
|
32 |
+
|
33 |
+
Make sure you have the composer bin dir in your PATH. The default value is `~/.composer/vendor/bin/`, but you can check the value that you need to use by running `composer global config bin-dir --absolute`.
|
34 |
+
|
35 |
+
Or alternatively, include a dependency for `squizlabs/php_codesniffer` in your `composer.json` file. For example:
|
36 |
+
|
37 |
+
```json
|
38 |
+
{
|
39 |
+
"require-dev": {
|
40 |
+
"squizlabs/php_codesniffer": "3.*"
|
41 |
+
}
|
42 |
+
}
|
43 |
+
```
|
44 |
+
|
45 |
+
You will then be able to run PHP_CodeSniffer from the vendor bin directory:
|
46 |
+
|
47 |
+
./vendor/bin/phpcs -h
|
48 |
+
./vendor/bin/phpcbf -h
|
49 |
+
|
50 |
+
### Phive
|
51 |
+
If you use Phive, you can install PHP_CodeSniffer as a project tool using the following commands:
|
52 |
+
|
53 |
+
phive install phpcs
|
54 |
+
phive install phpcbf
|
55 |
+
|
56 |
+
You will then be able to run PHP_CodeSniffer from the tools directory:
|
57 |
+
|
58 |
+
./tools/phpcs -h
|
59 |
+
./tools/phpcbf -h
|
60 |
+
|
61 |
+
### PEAR
|
62 |
+
If you use PEAR, you can install PHP\_CodeSniffer using the PEAR installer. This will make the `phpcs` and `phpcbf` commands immediately available for use. To install PHP\_CodeSniffer using the PEAR installer, first ensure you have [installed PEAR](http://pear.php.net/manual/en/installation.getting.php) and then run the following command:
|
63 |
+
|
64 |
+
pear install PHP_CodeSniffer
|
65 |
+
|
66 |
+
### Git Clone
|
67 |
+
You can also download the PHP\_CodeSniffer source and run the `phpcs` and `phpcbf` commands directly from the Git clone:
|
68 |
+
|
69 |
+
git clone https://github.com/squizlabs/PHP_CodeSniffer.git
|
70 |
+
cd PHP_CodeSniffer
|
71 |
+
php bin/phpcs -h
|
72 |
+
php bin/phpcbf -h
|
73 |
+
|
74 |
+
## Documentation
|
75 |
+
|
76 |
+
The documentation for PHP\_CodeSniffer is available on the [Github wiki](https://github.com/squizlabs/PHP_CodeSniffer/wiki).
|
77 |
+
|
78 |
+
## Issues
|
79 |
+
|
80 |
+
Bug reports and feature requests can be submitted on the [Github Issue Tracker](https://github.com/squizlabs/PHP_CodeSniffer/issues).
|
81 |
+
|
82 |
+
## Contributing
|
83 |
+
|
84 |
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for information.
|
85 |
+
|
86 |
+
## Versioning
|
87 |
+
|
88 |
+
PHP_CodeSniffer uses a `MAJOR.MINOR.PATCH` version number format.
|
89 |
+
|
90 |
+
The `MAJOR` version is incremented when:
|
91 |
+
- backwards-incompatible changes are made to how the `phpcs` or `phpcbf` commands are used, or
|
92 |
+
- backwards-incompatible changes are made to the `ruleset.xml` format, or
|
93 |
+
- backwards-incompatible changes are made to the API used by sniff developers, or
|
94 |
+
- custom PHP_CodeSniffer token types are removed
|
95 |
+
|
96 |
+
The `MINOR` version is incremented when:
|
97 |
+
- new backwards-compatible features are added to the `phpcs` and `phpcbf` commands, or
|
98 |
+
- backwards-compatible changes are made to the `ruleset.xml` format, or
|
99 |
+
- backwards-compatible changes are made to the API used by sniff developers, or
|
100 |
+
- new sniffs are added to an included standard
|
101 |
+
|
102 |
+
> NOTE: Backwards-compatible changes to the API used by sniff develpers will allow an existing sniff to continue running without producing fatal errors but may not result in the sniff reporting the same errors as it did previously without changes being required.
|
103 |
+
|
104 |
+
The `PATCH` version is incremented when:
|
105 |
+
- backwards-compatible bug fixes are made
|
106 |
+
|
107 |
+
> NOTE: As PHP_CodeSniffer exists to report and fix issues, most bugs are the result of coding standard errors being incorrectly reported or coding standard errors not being reported when they should be. This means that the messages produced by PHP_CodeSniffer, and the fixes it makes, are likely to be different between PATCH versions.
|
vendor/php_codesniffer-3.4.0/composer.json
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "squizlabs/php_codesniffer",
|
3 |
+
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
|
4 |
+
"type": "library",
|
5 |
+
"keywords": [
|
6 |
+
"phpcs",
|
7 |
+
"standards"
|
8 |
+
],
|
9 |
+
"homepage": "http://www.squizlabs.com/php-codesniffer",
|
10 |
+
"license": "BSD-3-Clause",
|
11 |
+
"authors": [
|
12 |
+
{
|
13 |
+
"name": "Greg Sherwood",
|
14 |
+
"role": "lead"
|
15 |
+
}
|
16 |
+
],
|
17 |
+
"support": {
|
18 |
+
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
|
19 |
+
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki",
|
20 |
+
"source": "https://github.com/squizlabs/PHP_CodeSniffer"
|
21 |
+
},
|
22 |
+
"extra": {
|
23 |
+
"branch-alias": {
|
24 |
+
"dev-master": "3.x-dev"
|
25 |
+
}
|
26 |
+
},
|
27 |
+
"require": {
|
28 |
+
"php": ">=5.4.0",
|
29 |
+
"ext-tokenizer": "*",
|
30 |
+
"ext-xmlwriter": "*",
|
31 |
+
"ext-simplexml": "*"
|
32 |
+
},
|
33 |
+
"require-dev": {
|
34 |
+
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
|
35 |
+
},
|
36 |
+
"bin": [
|
37 |
+
"bin/phpcs",
|
38 |
+
"bin/phpcbf"
|
39 |
+
]
|
40 |
+
}
|
vendor/php_codesniffer-3.4.0/licence.txt
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2012, Squiz Pty Ltd (ABN 77 084 670 600)
|
2 |
+
All rights reserved.
|
3 |
+
|
4 |
+
Redistribution and use in source and binary forms, with or without
|
5 |
+
modification, are permitted provided that the following conditions are met:
|
6 |
+
* Redistributions of source code must retain the above copyright
|
7 |
+
notice, this list of conditions and the following disclaimer.
|
8 |
+
* Redistributions in binary form must reproduce the above copyright
|
9 |
+
notice, this list of conditions and the following disclaimer in the
|
10 |
+
documentation and/or other materials provided with the distribution.
|
11 |
+
* Neither the name of Squiz Pty Ltd nor the
|
12 |
+
names of its contributors may be used to endorse or promote products
|
13 |
+
derived from this software without specific prior written permission.
|
14 |
+
|
15 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16 |
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17 |
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18 |
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
|
19 |
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20 |
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21 |
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22 |
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24 |
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
vendor/php_codesniffer-3.4.0/phpcs.xml.dist
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHP_CodeSniffer" xsi:noNamespaceSchemaLocation="phpcs.xsd">
|
3 |
+
<description>The coding standard for PHP_CodeSniffer itself.</description>
|
4 |
+
|
5 |
+
<file>autoload.php</file>
|
6 |
+
<file>bin</file>
|
7 |
+
<file>scripts</file>
|
8 |
+
<file>src</file>
|
9 |
+
<file>tests</file>
|
10 |
+
|
11 |
+
<exclude-pattern>*/Standards/*/Tests/*\.(inc|css|js)</exclude-pattern>
|
12 |
+
|
13 |
+
<arg name="basepath" value="."/>
|
14 |
+
<arg name="colors"/>
|
15 |
+
<arg name="parallel" value="75"/>
|
16 |
+
<arg value="np"/>
|
17 |
+
|
18 |
+
<!-- Don't hide tokenizer exceptions -->
|
19 |
+
<rule ref="Internal.Tokenizer.Exception">
|
20 |
+
<type>error</type>
|
21 |
+
</rule>
|
22 |
+
|
23 |
+
<!-- Include the whole PEAR standard -->
|
24 |
+
<rule ref="PEAR">
|
25 |
+
<exclude name="PEAR.NamingConventions.ValidFunctionName"/>
|
26 |
+
<exclude name="PEAR.NamingConventions.ValidVariableName"/>
|
27 |
+
<exclude name="PEAR.Commenting.ClassComment"/>
|
28 |
+
<exclude name="PEAR.Commenting.FileComment.MissingCategoryTag"/>
|
29 |
+
<exclude name="PEAR.Commenting.FileComment.MissingPackageTag"/>
|
30 |
+
<exclude name="PEAR.Commenting.FileComment.MissingLinkTag"/>
|
31 |
+
<exclude name="PEAR.Commenting.FileComment.MissingVersion"/>
|
32 |
+
<exclude name="PEAR.Commenting.InlineComment"/>
|
33 |
+
</rule>
|
34 |
+
|
35 |
+
<!-- Include some sniffs from other standards that don't conflict with PEAR -->
|
36 |
+
<rule ref="Squiz.Arrays.ArrayBracketSpacing"/>
|
37 |
+
<rule ref="Squiz.Arrays.ArrayDeclaration"/>
|
38 |
+
<rule ref="Squiz.Commenting.ClosingDeclarationComment"/>
|
39 |
+
<rule ref="Squiz.ControlStructures.ControlSignature"/>
|
40 |
+
<rule ref="Squiz.ControlStructures.ElseIfDeclaration"/>
|
41 |
+
<rule ref="Squiz.Commenting.BlockComment"/>
|
42 |
+
<rule ref="Squiz.Commenting.DocCommentAlignment"/>
|
43 |
+
<rule ref="Squiz.Commenting.EmptyCatchComment"/>
|
44 |
+
<rule ref="Squiz.Commenting.InlineComment"/>
|
45 |
+
<rule ref="Squiz.Commenting.LongConditionClosingComment"/>
|
46 |
+
<rule ref="Squiz.Commenting.PostStatementComment"/>
|
47 |
+
<rule ref="Squiz.Commenting.VariableComment"/>
|
48 |
+
<rule ref="Squiz.Formatting.OperatorBracket"/>
|
49 |
+
<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing"/>
|
50 |
+
<rule ref="Squiz.Operators.ComparisonOperatorUsage"/>
|
51 |
+
<rule ref="Squiz.PHP.DisallowInlineIf"/>
|
52 |
+
<rule ref="Squiz.Scope.MethodScope"/>
|
53 |
+
<rule ref="Squiz.Strings.ConcatenationSpacing"/>
|
54 |
+
<rule ref="Squiz.WhiteSpace.ControlStructureSpacing"/>
|
55 |
+
<rule ref="Squiz.WhiteSpace.FunctionClosingBraceSpace"/>
|
56 |
+
<rule ref="Squiz.WhiteSpace.FunctionSpacing"/>
|
57 |
+
<rule ref="Squiz.WhiteSpace.OperatorSpacing"/>
|
58 |
+
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace"/>
|
59 |
+
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
|
60 |
+
<rule ref="Generic.Commenting.Todo"/>
|
61 |
+
<rule ref="Generic.ControlStructures.InlineControlStructure"/>
|
62 |
+
<rule ref="Generic.Formatting.DisallowMultipleStatements"/>
|
63 |
+
<rule ref="Generic.Formatting.SpaceAfterCast"/>
|
64 |
+
<rule ref="Generic.NamingConventions.ConstructorName"/>
|
65 |
+
<rule ref="Generic.PHP.DeprecatedFunctions"/>
|
66 |
+
<rule ref="Generic.PHP.LowerCaseKeyword"/>
|
67 |
+
<rule ref="Generic.Strings.UnnecessaryStringConcat"/>
|
68 |
+
<rule ref="Generic.WhiteSpace.IncrementDecrementSpacing"/>
|
69 |
+
<rule ref="PSR2.Classes.PropertyDeclaration"/>
|
70 |
+
<rule ref="PSR2.Methods.MethodDeclaration"/>
|
71 |
+
<rule ref="PSR2.Files.EndFileNewline"/>
|
72 |
+
<rule ref="Zend.Files.ClosingTag"/>
|
73 |
+
|
74 |
+
<!-- PEAR uses warnings for inline control structures, so switch back to errors -->
|
75 |
+
<rule ref="Generic.ControlStructures.InlineControlStructure">
|
76 |
+
<properties>
|
77 |
+
<property name="error" value="true"/>
|
78 |
+
</properties>
|
79 |
+
</rule>
|
80 |
+
|
81 |
+
<!-- We use custom indent rules for arrays -->
|
82 |
+
<rule ref="Generic.Arrays.ArrayIndent"/>
|
83 |
+
<rule ref="Squiz.Arrays.ArrayDeclaration.KeyNotAligned">
|
84 |
+
<severity>0</severity>
|
85 |
+
</rule>
|
86 |
+
<rule ref="Squiz.Arrays.ArrayDeclaration.ValueNotAligned">
|
87 |
+
<severity>0</severity>
|
88 |
+
</rule>
|
89 |
+
<rule ref="Squiz.Arrays.ArrayDeclaration.CloseBraceNotAligned">
|
90 |
+
<severity>0</severity>
|
91 |
+
</rule>
|
92 |
+
<rule ref="Squiz.Arrays.ArrayDeclaration.CloseBraceNewLine">
|
93 |
+
<severity>0</severity>
|
94 |
+
</rule>
|
95 |
+
|
96 |
+
<!-- Check var names, but we don't want leading underscores for private vars -->
|
97 |
+
<rule ref="Squiz.NamingConventions.ValidVariableName"/>
|
98 |
+
<rule ref="Squiz.NamingConventions.ValidVariableName.PrivateNoUnderscore">
|
99 |
+
<severity>0</severity>
|
100 |
+
</rule>
|
101 |
+
|
102 |
+
<!-- Only one argument per line in multi-line function calls -->
|
103 |
+
<rule ref="PEAR.Functions.FunctionCallSignature">
|
104 |
+
<properties>
|
105 |
+
<property name="allowMultipleArguments" value="false"/>
|
106 |
+
</properties>
|
107 |
+
</rule>
|
108 |
+
|
109 |
+
<!-- Have 12 chars padding maximum and always show as errors -->
|
110 |
+
<rule ref="Generic.Formatting.MultipleStatementAlignment">
|
111 |
+
<properties>
|
112 |
+
<property name="maxPadding" value="12"/>
|
113 |
+
<property name="error" value="true"/>
|
114 |
+
</properties>
|
115 |
+
</rule>
|
116 |
+
|
117 |
+
<!-- Ban some functions -->
|
118 |
+
<rule ref="Generic.PHP.ForbiddenFunctions">
|
119 |
+
<properties>
|
120 |
+
<property name="forbiddenFunctions" type="array">
|
121 |
+
<element key="sizeof" value="count"/>
|
122 |
+
<element key="delete" value="unset"/>
|
123 |
+
<element key="print" value="echo"/>
|
124 |
+
<element key="is_null" value="null"/>
|
125 |
+
<element key="create_function" value="null"/>
|
126 |
+
</property>
|
127 |
+
</properties>
|
128 |
+
</rule>
|
129 |
+
|
130 |
+
<!-- Private methods MUST not be prefixed with an underscore -->
|
131 |
+
<rule ref="PSR2.Methods.MethodDeclaration.Underscore">
|
132 |
+
<type>error</type>
|
133 |
+
</rule>
|
134 |
+
|
135 |
+
<!-- Private properties MUST not be prefixed with an underscore -->
|
136 |
+
<rule ref="PSR2.Classes.PropertyDeclaration.Underscore">
|
137 |
+
<type>error</type>
|
138 |
+
</rule>
|
139 |
+
|
140 |
+
<!-- The testing bootstrap file uses string concats to stop IDEs seeing the class aliases -->
|
141 |
+
<rule ref="Generic.Strings.UnnecessaryStringConcat">
|
142 |
+
<exclude-pattern>tests/bootstrap.php</exclude-pattern>
|
143 |
+
</rule>
|
144 |
+
|
145 |
+
</ruleset>
|
vendor/php_codesniffer-3.4.0/phpcs.xsd
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
2 |
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
|
3 |
+
|
4 |
+
<xs:element name="ruleset">
|
5 |
+
<xs:complexType>
|
6 |
+
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
7 |
+
<xs:element name="description" type="xs:string" maxOccurs="1" minOccurs="0"></xs:element>
|
8 |
+
<xs:element name="config" maxOccurs="unbounded" minOccurs="0">
|
9 |
+
<xs:complexType>
|
10 |
+
<xs:attribute name="name" type="xs:string" use="required"></xs:attribute>
|
11 |
+
<xs:attribute name="value" type="xs:string" use="required"></xs:attribute>
|
12 |
+
</xs:complexType>
|
13 |
+
</xs:element>
|
14 |
+
<xs:element name="file" type="xs:string" maxOccurs="unbounded" minOccurs="0"></xs:element>
|
15 |
+
<xs:element name="exclude-pattern" type="patternType" maxOccurs="unbounded" minOccurs="0"></xs:element>
|
16 |
+
<xs:element name="arg" maxOccurs="unbounded" minOccurs="0">
|
17 |
+
<xs:complexType>
|
18 |
+
<xs:attribute name="name" type="xs:string"></xs:attribute>
|
19 |
+
<xs:attribute name="value" type="xs:string"></xs:attribute>
|
20 |
+
</xs:complexType>
|
21 |
+
</xs:element>
|
22 |
+
<xs:element name="ini" maxOccurs="unbounded" minOccurs="0">
|
23 |
+
<xs:complexType>
|
24 |
+
<xs:attribute name="name" type="xs:string" use="required"></xs:attribute>
|
25 |
+
<xs:attribute name="value" type="xs:string" use="required"></xs:attribute>
|
26 |
+
</xs:complexType>
|
27 |
+
</xs:element>
|
28 |
+
<xs:element name="autoload" type="xs:string" maxOccurs="unbounded" minOccurs="0"></xs:element>
|
29 |
+
<xs:element name="rule" type="ruleType" maxOccurs="unbounded" minOccurs="0"></xs:element>
|
30 |
+
</xs:choice>
|
31 |
+
<xs:attribute name="name" type="xs:string"></xs:attribute>
|
32 |
+
<xs:attribute name="namespace" type="xs:string"></xs:attribute>
|
33 |
+
</xs:complexType>
|
34 |
+
</xs:element>
|
35 |
+
|
36 |
+
<xs:complexType name="ruleType">
|
37 |
+
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
38 |
+
<xs:element name="exclude" maxOccurs="unbounded" minOccurs="0">
|
39 |
+
<xs:complexType>
|
40 |
+
<xs:attribute name="name" type="xs:string" use="required"></xs:attribute>
|
41 |
+
</xs:complexType>
|
42 |
+
</xs:element>
|
43 |
+
<xs:element name="message" type="xs:string" maxOccurs="1" minOccurs="0"></xs:element>
|
44 |
+
<xs:element name="severity" type="xs:integer" maxOccurs="1" minOccurs="0"></xs:element>
|
45 |
+
<xs:element name="type" maxOccurs="1" minOccurs="0">
|
46 |
+
<xs:simpleType>
|
47 |
+
<xs:restriction base="xs:string">
|
48 |
+
<xs:enumeration value="error"></xs:enumeration>
|
49 |
+
<xs:enumeration value="warning"></xs:enumeration>
|
50 |
+
</xs:restriction>
|
51 |
+
</xs:simpleType>
|
52 |
+
</xs:element>
|
53 |
+
<xs:element name="exclude-pattern" type="patternType" maxOccurs="unbounded" minOccurs="0"></xs:element>
|
54 |
+
<xs:element name="include-pattern" type="patternType" maxOccurs="unbounded" minOccurs="0"></xs:element>
|
55 |
+
<xs:element name="properties" type="propertiesType" maxOccurs="1" minOccurs="0"></xs:element>
|
56 |
+
</xs:choice>
|
57 |
+
<xs:attribute name="ref" type="xs:string" use="required"></xs:attribute>
|
58 |
+
</xs:complexType>
|
59 |
+
|
60 |
+
<xs:complexType name="patternType">
|
61 |
+
<xs:simpleContent>
|
62 |
+
<xs:extension base="xs:string">
|
63 |
+
<xs:attribute name="type">
|
64 |
+
<xs:simpleType>
|
65 |
+
<xs:restriction base="xs:string">
|
66 |
+
<xs:enumeration value="relative"></xs:enumeration>
|
67 |
+
</xs:restriction>
|
68 |
+
</xs:simpleType>
|
69 |
+
</xs:attribute>
|
70 |
+
</xs:extension>
|
71 |
+
</xs:simpleContent>
|
72 |
+
</xs:complexType>
|
73 |
+
|
74 |
+
<xs:complexType name="propertiesType">
|
75 |
+
<xs:sequence>
|
76 |
+
<xs:element name="property" maxOccurs="unbounded" minOccurs="1">
|
77 |
+
<xs:complexType>
|
78 |
+
<xs:sequence>
|
79 |
+
<xs:element name="element" maxOccurs="unbounded" minOccurs="0">
|
80 |
+
<xs:complexType>
|
81 |
+
<xs:attribute name="key" type="xs:string"></xs:attribute>
|
82 |
+
<xs:attribute name="value" type="xs:string" use="required"></xs:attribute>
|
83 |
+
</xs:complexType>
|
84 |
+
</xs:element>
|
85 |
+
</xs:sequence>
|
86 |
+
<xs:attribute name="type">
|
87 |
+
<xs:simpleType>
|
88 |
+
<xs:restriction base="xs:string">
|
89 |
+
<xs:enumeration value="array"></xs:enumeration>
|
90 |
+
</xs:restriction>
|
91 |
+
</xs:simpleType>
|
92 |
+
</xs:attribute>
|
93 |
+
<xs:attribute name="name" type="xs:string" use="required"></xs:attribute>
|
94 |
+
<xs:attribute name="value" type="xs:string"></xs:attribute>
|
95 |
+
<xs:attribute name="extend">
|
96 |
+
<xs:simpleType>
|
97 |
+
<xs:restriction base="xs:string">
|
98 |
+
<xs:enumeration value="true"/>
|
99 |
+
<xs:enumeration value="false"/>
|
100 |
+
</xs:restriction>
|
101 |
+
</xs:simpleType>
|
102 |
+
</xs:attribute>
|
103 |
+
</xs:complexType>
|
104 |
+
</xs:element>
|
105 |
+
</xs:sequence>
|
106 |
+
</xs:complexType>
|
107 |
+
|
108 |
+
</xs:schema>
|
vendor/php_codesniffer-3.4.0/src/Exceptions/DeepExitException.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* An exception thrown by PHP_CodeSniffer when it wants to exit from somewhere not in the main runner.
|
4 |
+
*
|
5 |
+
* Allows the runner to return an exit code instead of putting exit codes elsewhere
|
6 |
+
* in the source code.
|
7 |
+
*
|
8 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
9 |
+
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
|
10 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace PHP_CodeSniffer\Exceptions;
|
14 |
+
|
15 |
+
class DeepExitException extends \Exception
|
16 |
+
{
|
17 |
+
|
18 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Exceptions/RuntimeException.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable error.
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Exceptions;
|
11 |
+
|
12 |
+
class RuntimeException extends \Exception
|
13 |
+
{
|
14 |
+
|
15 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Exceptions/TokenizerException.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable tokenizer error.
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Exceptions;
|
11 |
+
|
12 |
+
class TokenizerException extends \Exception
|
13 |
+
{
|
14 |
+
|
15 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Tokenizers/CSS.php
ADDED
@@ -0,0 +1,534 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Tokenizes CSS code.
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Tokenizers;
|
11 |
+
|
12 |
+
use PHP_CodeSniffer\Util;
|
13 |
+
use PHP_CodeSniffer\Config;
|
14 |
+
use PHP_CodeSniffer\Exceptions\TokenizerException;
|
15 |
+
|
16 |
+
class CSS extends PHP
|
17 |
+
{
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Initialise the tokenizer.
|
22 |
+
*
|
23 |
+
* Pre-checks the content to see if it looks minified.
|
24 |
+
*
|
25 |
+
* @param string $content The content to tokenize,
|
26 |
+
* @param \PHP_CodeSniffer\Config $config The config data for the run.
|
27 |
+
* @param string $eolChar The EOL char used in the content.
|
28 |
+
*
|
29 |
+
* @return void
|
30 |
+
* @throws TokenizerException If the file appears to be minified.
|
31 |
+
*/
|
32 |
+
public function __construct($content, Config $config, $eolChar='\n')
|
33 |
+
{
|
34 |
+
if ($this->isMinifiedContent($content, $eolChar) === true) {
|
35 |
+
throw new TokenizerException('File appears to be minified and cannot be processed');
|
36 |
+
}
|
37 |
+
|
38 |
+
return parent::__construct($content, $config, $eolChar);
|
39 |
+
|
40 |
+
}//end __construct()
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Creates an array of tokens when given some CSS code.
|
45 |
+
*
|
46 |
+
* Uses the PHP tokenizer to do all the tricky work
|
47 |
+
*
|
48 |
+
* @param string $string The string to tokenize.
|
49 |
+
*
|
50 |
+
* @return array
|
51 |
+
*/
|
52 |
+
public function tokenize($string)
|
53 |
+
{
|
54 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
55 |
+
echo "\t*** START CSS TOKENIZING 1ST PASS ***".PHP_EOL;
|
56 |
+
}
|
57 |
+
|
58 |
+
// If the content doesn't have an EOL char on the end, add one so
|
59 |
+
// the open and close tags we add are parsed correctly.
|
60 |
+
$eolAdded = false;
|
61 |
+
if (substr($string, (strlen($this->eolChar) * -1)) !== $this->eolChar) {
|
62 |
+
$string .= $this->eolChar;
|
63 |
+
$eolAdded = true;
|
64 |
+
}
|
65 |
+
|
66 |
+
$string = str_replace('<?php', '^PHPCS_CSS_T_OPEN_TAG^', $string);
|
67 |
+
$string = str_replace('?>', '^PHPCS_CSS_T_CLOSE_TAG^', $string);
|
68 |
+
$tokens = parent::tokenize('<?php '.$string.'?>');
|
69 |
+
|
70 |
+
$finalTokens = [];
|
71 |
+
$finalTokens[0] = [
|
72 |
+
'code' => T_OPEN_TAG,
|
73 |
+
'type' => 'T_OPEN_TAG',
|
74 |
+
'content' => '',
|
75 |
+
];
|
76 |
+
|
77 |
+
$newStackPtr = 1;
|
78 |
+
$numTokens = count($tokens);
|
79 |
+
$multiLineComment = false;
|
80 |
+
for ($stackPtr = 1; $stackPtr < $numTokens; $stackPtr++) {
|
81 |
+
$token = $tokens[$stackPtr];
|
82 |
+
|
83 |
+
// CSS files don't have lists, breaks etc, so convert these to
|
84 |
+
// standard strings early so they can be converted into T_STYLE
|
85 |
+
// tokens and joined with other strings if needed.
|
86 |
+
if ($token['code'] === T_BREAK
|
87 |
+
|| $token['code'] === T_LIST
|
88 |
+
|| $token['code'] === T_DEFAULT
|
89 |
+
|| $token['code'] === T_SWITCH
|
90 |
+
|| $token['code'] === T_FOR
|
91 |
+
|| $token['code'] === T_FOREACH
|
92 |
+
|| $token['code'] === T_WHILE
|
93 |
+
|| $token['code'] === T_DEC
|
94 |
+
|| $token['code'] === T_NEW
|
95 |
+
) {
|
96 |
+
$token['type'] = 'T_STRING';
|
97 |
+
$token['code'] = T_STRING;
|
98 |
+
}
|
99 |
+
|
100 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
101 |
+
$type = $token['type'];
|
102 |
+
$content = Util\Common::prepareForOutput($token['content']);
|
103 |
+
echo "\tProcess token $stackPtr: $type => $content".PHP_EOL;
|
104 |
+
}
|
105 |
+
|
106 |
+
if ($token['code'] === T_BITWISE_XOR
|
107 |
+
&& $tokens[($stackPtr + 1)]['content'] === 'PHPCS_CSS_T_OPEN_TAG'
|
108 |
+
) {
|
109 |
+
$content = '<?php';
|
110 |
+
for ($stackPtr += 3; $stackPtr < $numTokens; $stackPtr++) {
|
111 |
+
if ($tokens[$stackPtr]['code'] === T_BITWISE_XOR
|
112 |
+
&& $tokens[($stackPtr + 1)]['content'] === 'PHPCS_CSS_T_CLOSE_TAG'
|
113 |
+
) {
|
114 |
+
// Add the end tag and ignore the * we put at the end.
|
115 |
+
$content .= '?>';
|
116 |
+
$stackPtr += 2;
|
117 |
+
break;
|
118 |
+
} else {
|
119 |
+
$content .= $tokens[$stackPtr]['content'];
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
124 |
+
echo "\t\t=> Found embedded PHP code: ";
|
125 |
+
$cleanContent = Util\Common::prepareForOutput($content);
|
126 |
+
echo $cleanContent.PHP_EOL;
|
127 |
+
}
|
128 |
+
|
129 |
+
$finalTokens[$newStackPtr] = [
|
130 |
+
'type' => 'T_EMBEDDED_PHP',
|
131 |
+
'code' => T_EMBEDDED_PHP,
|
132 |
+
'content' => $content,
|
133 |
+
];
|
134 |
+
|
135 |
+
$newStackPtr++;
|
136 |
+
continue;
|
137 |
+
}//end if
|
138 |
+
|
139 |
+
if ($token['code'] === T_GOTO_LABEL) {
|
140 |
+
// Convert these back to T_STRING followed by T_COLON so we can
|
141 |
+
// more easily process style definitions.
|
142 |
+
$finalTokens[$newStackPtr] = [
|
143 |
+
'type' => 'T_STRING',
|
144 |
+
'code' => T_STRING,
|
145 |
+
'content' => substr($token['content'], 0, -1),
|
146 |
+
];
|
147 |
+
$newStackPtr++;
|
148 |
+
$finalTokens[$newStackPtr] = [
|
149 |
+
'type' => 'T_COLON',
|
150 |
+
'code' => T_COLON,
|
151 |
+
'content' => ':',
|
152 |
+
];
|
153 |
+
$newStackPtr++;
|
154 |
+
continue;
|
155 |
+
}
|
156 |
+
|
157 |
+
if ($token['code'] === T_FUNCTION) {
|
158 |
+
// There are no functions in CSS, so convert this to a string.
|
159 |
+
$finalTokens[$newStackPtr] = [
|
160 |
+
'type' => 'T_STRING',
|
161 |
+
'code' => T_STRING,
|
162 |
+
'content' => $token['content'],
|
163 |
+
];
|
164 |
+
|
165 |
+
$newStackPtr++;
|
166 |
+
continue;
|
167 |
+
}
|
168 |
+
|
169 |
+
if ($token['code'] === T_COMMENT
|
170 |
+
&& substr($token['content'], 0, 2) === '/*'
|
171 |
+
) {
|
172 |
+
// Multi-line comment. Record it so we can ignore other
|
173 |
+
// comment tags until we get out of this one.
|
174 |
+
$multiLineComment = true;
|
175 |
+
}
|
176 |
+
|
177 |
+
if ($token['code'] === T_COMMENT
|
178 |
+
&& $multiLineComment === false
|
179 |
+
&& (substr($token['content'], 0, 2) === '//'
|
180 |
+
|| $token['content']{0} === '#')
|
181 |
+
) {
|
182 |
+
$content = ltrim($token['content'], '#/');
|
183 |
+
|
184 |
+
// Guard against PHP7+ syntax errors by stripping
|
185 |
+
// leading zeros so the content doesn't look like an invalid int.
|
186 |
+
$leadingZero = false;
|
187 |
+
if ($content{0} === '0') {
|
188 |
+
$content = '1'.$content;
|
189 |
+
$leadingZero = true;
|
190 |
+
}
|
191 |
+
|
192 |
+
$commentTokens = parent::tokenize('<?php '.$content.'?>');
|
193 |
+
|
194 |
+
// The first and last tokens are the open/close tags.
|
195 |
+
array_shift($commentTokens);
|
196 |
+
array_pop($commentTokens);
|
197 |
+
|
198 |
+
if ($leadingZero === true) {
|
199 |
+
$commentTokens[0]['content'] = substr($commentTokens[0]['content'], 1);
|
200 |
+
$content = substr($content, 1);
|
201 |
+
}
|
202 |
+
|
203 |
+
if ($token['content']{0} === '#') {
|
204 |
+
// The # character is not a comment in CSS files, so
|
205 |
+
// determine what it means in this context.
|
206 |
+
$firstContent = $commentTokens[0]['content'];
|
207 |
+
|
208 |
+
// If the first content is just a number, it is probably a
|
209 |
+
// colour like 8FB7DB, which PHP splits into 8 and FB7DB.
|
210 |
+
if (($commentTokens[0]['code'] === T_LNUMBER
|
211 |
+
|| $commentTokens[0]['code'] === T_DNUMBER)
|
212 |
+
&& $commentTokens[1]['code'] === T_STRING
|
213 |
+
) {
|
214 |
+
$firstContent .= $commentTokens[1]['content'];
|
215 |
+
array_shift($commentTokens);
|
216 |
+
}
|
217 |
+
|
218 |
+
// If the first content looks like a colour and not a class
|
219 |
+
// definition, join the tokens together.
|
220 |
+
if (preg_match('/^[ABCDEF0-9]+$/i', $firstContent) === 1
|
221 |
+
&& $commentTokens[1]['content'] !== '-'
|
222 |
+
) {
|
223 |
+
array_shift($commentTokens);
|
224 |
+
// Work out what we trimmed off above and remember to re-add it.
|
225 |
+
$trimmed = substr($token['content'], 0, (strlen($token['content']) - strlen($content)));
|
226 |
+
$finalTokens[$newStackPtr] = [
|
227 |
+
'type' => 'T_COLOUR',
|
228 |
+
'code' => T_COLOUR,
|
229 |
+
'content' => $trimmed.$firstContent,
|
230 |
+
];
|
231 |
+
} else {
|
232 |
+
$finalTokens[$newStackPtr] = [
|
233 |
+
'type' => 'T_HASH',
|
234 |
+
'code' => T_HASH,
|
235 |
+
'content' => '#',
|
236 |
+
];
|
237 |
+
}
|
238 |
+
} else {
|
239 |
+
$finalTokens[$newStackPtr] = [
|
240 |
+
'type' => 'T_STRING',
|
241 |
+
'code' => T_STRING,
|
242 |
+
'content' => '//',
|
243 |
+
];
|
244 |
+
}//end if
|
245 |
+
|
246 |
+
$newStackPtr++;
|
247 |
+
|
248 |
+
array_splice($tokens, $stackPtr, 1, $commentTokens);
|
249 |
+
$numTokens = count($tokens);
|
250 |
+
$stackPtr--;
|
251 |
+
continue;
|
252 |
+
}//end if
|
253 |
+
|
254 |
+
if ($token['code'] === T_COMMENT
|
255 |
+
&& substr($token['content'], -2) === '*/'
|
256 |
+
) {
|
257 |
+
// Multi-line comment is done.
|
258 |
+
$multiLineComment = false;
|
259 |
+
}
|
260 |
+
|
261 |
+
$finalTokens[$newStackPtr] = $token;
|
262 |
+
$newStackPtr++;
|
263 |
+
}//end for
|
264 |
+
|
265 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
266 |
+
echo "\t*** END CSS TOKENIZING 1ST PASS ***".PHP_EOL;
|
267 |
+
echo "\t*** START CSS TOKENIZING 2ND PASS ***".PHP_EOL;
|
268 |
+
}
|
269 |
+
|
270 |
+
// A flag to indicate if we are inside a style definition,
|
271 |
+
// which is defined using curly braces.
|
272 |
+
$inStyleDef = false;
|
273 |
+
|
274 |
+
// A flag to indicate if an At-rule like "@media" is used, which will result
|
275 |
+
// in nested curly brackets.
|
276 |
+
$asperandStart = false;
|
277 |
+
|
278 |
+
$numTokens = count($finalTokens);
|
279 |
+
for ($stackPtr = 0; $stackPtr < $numTokens; $stackPtr++) {
|
280 |
+
$token = $finalTokens[$stackPtr];
|
281 |
+
|
282 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
283 |
+
$type = $token['type'];
|
284 |
+
$content = Util\Common::prepareForOutput($token['content']);
|
285 |
+
echo "\tProcess token $stackPtr: $type => $content".PHP_EOL;
|
286 |
+
}
|
287 |
+
|
288 |
+
switch ($token['code']) {
|
289 |
+
case T_OPEN_CURLY_BRACKET:
|
290 |
+
// Opening curly brackets for an At-rule do not start a style
|
291 |
+
// definition. We also reset the asperand flag here because the next
|
292 |
+
// opening curly bracket could be indeed the start of a style
|
293 |
+
// definition.
|
294 |
+
if ($asperandStart === true) {
|
295 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
296 |
+
if ($inStyleDef === true) {
|
297 |
+
echo "\t\t* style definition closed *".PHP_EOL;
|
298 |
+
}
|
299 |
+
|
300 |
+
if ($asperandStart === true) {
|
301 |
+
echo "\t\t* at-rule definition closed *".PHP_EOL;
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
$inStyleDef = false;
|
306 |
+
$asperandStart = false;
|
307 |
+
} else {
|
308 |
+
$inStyleDef = true;
|
309 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
310 |
+
echo "\t\t* style definition opened *".PHP_EOL;
|
311 |
+
}
|
312 |
+
}
|
313 |
+
break;
|
314 |
+
case T_CLOSE_CURLY_BRACKET:
|
315 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
316 |
+
if ($inStyleDef === true) {
|
317 |
+
echo "\t\t* style definition closed *".PHP_EOL;
|
318 |
+
}
|
319 |
+
|
320 |
+
if ($asperandStart === true) {
|
321 |
+
echo "\t\t* at-rule definition closed *".PHP_EOL;
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
$inStyleDef = false;
|
326 |
+
$asperandStart = false;
|
327 |
+
break;
|
328 |
+
case T_MINUS:
|
329 |
+
// Minus signs are often used instead of spaces inside
|
330 |
+
// class names, IDs and styles.
|
331 |
+
if ($finalTokens[($stackPtr + 1)]['code'] === T_STRING) {
|
332 |
+
if ($finalTokens[($stackPtr - 1)]['code'] === T_STRING) {
|
333 |
+
$newContent = $finalTokens[($stackPtr - 1)]['content'].'-'.$finalTokens[($stackPtr + 1)]['content'];
|
334 |
+
|
335 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
336 |
+
echo "\t\t* token is a string joiner; ignoring this and previous token".PHP_EOL;
|
337 |
+
$old = Util\Common::prepareForOutput($finalTokens[($stackPtr + 1)]['content']);
|
338 |
+
$new = Util\Common::prepareForOutput($newContent);
|
339 |
+
echo "\t\t=> token ".($stackPtr + 1)." content changed from \"$old\" to \"$new\"".PHP_EOL;
|
340 |
+
}
|
341 |
+
|
342 |
+
$finalTokens[($stackPtr + 1)]['content'] = $newContent;
|
343 |
+
unset($finalTokens[$stackPtr]);
|
344 |
+
unset($finalTokens[($stackPtr - 1)]);
|
345 |
+
} else {
|
346 |
+
$newContent = '-'.$finalTokens[($stackPtr + 1)]['content'];
|
347 |
+
|
348 |
+
$finalTokens[($stackPtr + 1)]['content'] = $newContent;
|
349 |
+
unset($finalTokens[$stackPtr]);
|
350 |
+
}
|
351 |
+
} else if ($finalTokens[($stackPtr + 1)]['code'] === T_LNUMBER) {
|
352 |
+
// They can also be used to provide negative numbers.
|
353 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
354 |
+
echo "\t\t* token is part of a negative number; adding content to next token and ignoring *".PHP_EOL;
|
355 |
+
$content = Util\Common::prepareForOutput($finalTokens[($stackPtr + 1)]['content']);
|
356 |
+
echo "\t\t=> token ".($stackPtr + 1)." content changed from \"$content\" to \"-$content\"".PHP_EOL;
|
357 |
+
}
|
358 |
+
|
359 |
+
$finalTokens[($stackPtr + 1)]['content'] = '-'.$finalTokens[($stackPtr + 1)]['content'];
|
360 |
+
unset($finalTokens[$stackPtr]);
|
361 |
+
}//end if
|
362 |
+
break;
|
363 |
+
case T_COLON:
|
364 |
+
// Only interested in colons that are defining styles.
|
365 |
+
if ($inStyleDef === false) {
|
366 |
+
break;
|
367 |
+
}
|
368 |
+
|
369 |
+
for ($x = ($stackPtr - 1); $x >= 0; $x--) {
|
370 |
+
if (isset(Util\Tokens::$emptyTokens[$finalTokens[$x]['code']]) === false) {
|
371 |
+
break;
|
372 |
+
}
|
373 |
+
}
|
374 |
+
|
375 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
376 |
+
$type = $finalTokens[$x]['type'];
|
377 |
+
echo "\t\t=> token $x changed from $type to T_STYLE".PHP_EOL;
|
378 |
+
}
|
379 |
+
|
380 |
+
$finalTokens[$x]['type'] = 'T_STYLE';
|
381 |
+
$finalTokens[$x]['code'] = T_STYLE;
|
382 |
+
break;
|
383 |
+
case T_STRING:
|
384 |
+
if (strtolower($token['content']) === 'url') {
|
385 |
+
// Find the next content.
|
386 |
+
for ($x = ($stackPtr + 1); $x < $numTokens; $x++) {
|
387 |
+
if (isset(Util\Tokens::$emptyTokens[$finalTokens[$x]['code']]) === false) {
|
388 |
+
break;
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
// Needs to be in the format "url(" for it to be a URL.
|
393 |
+
if ($finalTokens[$x]['code'] !== T_OPEN_PARENTHESIS) {
|
394 |
+
continue 2;
|
395 |
+
}
|
396 |
+
|
397 |
+
// Make sure the content isn't empty.
|
398 |
+
for ($y = ($x + 1); $y < $numTokens; $y++) {
|
399 |
+
if (isset(Util\Tokens::$emptyTokens[$finalTokens[$y]['code']]) === false) {
|
400 |
+
break;
|
401 |
+
}
|
402 |
+
}
|
403 |
+
|
404 |
+
if ($finalTokens[$y]['code'] === T_CLOSE_PARENTHESIS) {
|
405 |
+
continue 2;
|
406 |
+
}
|
407 |
+
|
408 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
409 |
+
for ($i = ($stackPtr + 1); $i <= $y; $i++) {
|
410 |
+
$type = $finalTokens[$i]['type'];
|
411 |
+
$content = Util\Common::prepareForOutput($finalTokens[$i]['content']);
|
412 |
+
echo "\tProcess token $i: $type => $content".PHP_EOL;
|
413 |
+
}
|
414 |
+
|
415 |
+
echo "\t\t* token starts a URL *".PHP_EOL;
|
416 |
+
}
|
417 |
+
|
418 |
+
// Join all the content together inside the url() statement.
|
419 |
+
$newContent = '';
|
420 |
+
for ($i = ($x + 2); $i < $numTokens; $i++) {
|
421 |
+
if ($finalTokens[$i]['code'] === T_CLOSE_PARENTHESIS) {
|
422 |
+
break;
|
423 |
+
}
|
424 |
+
|
425 |
+
$newContent .= $finalTokens[$i]['content'];
|
426 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
427 |
+
$content = Util\Common::prepareForOutput($finalTokens[$i]['content']);
|
428 |
+
echo "\t\t=> token $i added to URL string and ignored: $content".PHP_EOL;
|
429 |
+
}
|
430 |
+
|
431 |
+
unset($finalTokens[$i]);
|
432 |
+
}
|
433 |
+
|
434 |
+
$stackPtr = $i;
|
435 |
+
|
436 |
+
// If the content inside the "url()" is in double quotes
|
437 |
+
// there will only be one token and so we don't have to do
|
438 |
+
// anything except change its type. If it is not empty,
|
439 |
+
// we need to do some token merging.
|
440 |
+
$finalTokens[($x + 1)]['type'] = 'T_URL';
|
441 |
+
$finalTokens[($x + 1)]['code'] = T_URL;
|
442 |
+
|
443 |
+
if ($newContent !== '') {
|
444 |
+
$finalTokens[($x + 1)]['content'] .= $newContent;
|
445 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
446 |
+
$content = Util\Common::prepareForOutput($finalTokens[($x + 1)]['content']);
|
447 |
+
echo "\t\t=> token content changed to: $content".PHP_EOL;
|
448 |
+
}
|
449 |
+
}
|
450 |
+
} else if ($finalTokens[$stackPtr]['content'][0] === '-'
|
451 |
+
&& $finalTokens[($stackPtr + 1)]['code'] === T_STRING
|
452 |
+
) {
|
453 |
+
if (isset($finalTokens[($stackPtr - 1)]) === true
|
454 |
+
&& $finalTokens[($stackPtr - 1)]['code'] === T_STRING
|
455 |
+
) {
|
456 |
+
$newContent = $finalTokens[($stackPtr - 1)]['content'].$finalTokens[$stackPtr]['content'].$finalTokens[($stackPtr + 1)]['content'];
|
457 |
+
|
458 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
459 |
+
echo "\t\t* token is a string joiner; ignoring this and previous token".PHP_EOL;
|
460 |
+
$old = Util\Common::prepareForOutput($finalTokens[($stackPtr + 1)]['content']);
|
461 |
+
$new = Util\Common::prepareForOutput($newContent);
|
462 |
+
echo "\t\t=> token ".($stackPtr + 1)." content changed from \"$old\" to \"$new\"".PHP_EOL;
|
463 |
+
}
|
464 |
+
|
465 |
+
$finalTokens[($stackPtr + 1)]['content'] = $newContent;
|
466 |
+
unset($finalTokens[$stackPtr]);
|
467 |
+
unset($finalTokens[($stackPtr - 1)]);
|
468 |
+
} else {
|
469 |
+
$newContent = $finalTokens[$stackPtr]['content'].$finalTokens[($stackPtr + 1)]['content'];
|
470 |
+
|
471 |
+
$finalTokens[($stackPtr + 1)]['content'] = $newContent;
|
472 |
+
unset($finalTokens[$stackPtr]);
|
473 |
+
}
|
474 |
+
}//end if
|
475 |
+
break;
|
476 |
+
case T_ASPERAND:
|
477 |
+
$asperandStart = true;
|
478 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
479 |
+
echo "\t\t* at-rule definition opened *".PHP_EOL;
|
480 |
+
}
|
481 |
+
break;
|
482 |
+
default:
|
483 |
+
// Nothing special to be done with this token.
|
484 |
+
break;
|
485 |
+
}//end switch
|
486 |
+
}//end for
|
487 |
+
|
488 |
+
// Reset the array keys to avoid gaps.
|
489 |
+
$finalTokens = array_values($finalTokens);
|
490 |
+
$numTokens = count($finalTokens);
|
491 |
+
|
492 |
+
// Blank out the content of the end tag.
|
493 |
+
$finalTokens[($numTokens - 1)]['content'] = '';
|
494 |
+
|
495 |
+
if ($eolAdded === true) {
|
496 |
+
// Strip off the extra EOL char we added for tokenizing.
|
497 |
+
$finalTokens[($numTokens - 2)]['content'] = substr(
|
498 |
+
$finalTokens[($numTokens - 2)]['content'],
|
499 |
+
0,
|
500 |
+
(strlen($this->eolChar) * -1)
|
501 |
+
);
|
502 |
+
|
503 |
+
if ($finalTokens[($numTokens - 2)]['content'] === '') {
|
504 |
+
unset($finalTokens[($numTokens - 2)]);
|
505 |
+
$finalTokens = array_values($finalTokens);
|
506 |
+
$numTokens = count($finalTokens);
|
507 |
+
}
|
508 |
+
}
|
509 |
+
|
510 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
511 |
+
echo "\t*** END CSS TOKENIZING 2ND PASS ***".PHP_EOL;
|
512 |
+
}
|
513 |
+
|
514 |
+
return $finalTokens;
|
515 |
+
|
516 |
+
}//end tokenize()
|
517 |
+
|
518 |
+
|
519 |
+
/**
|
520 |
+
* Performs additional processing after main tokenizing.
|
521 |
+
*
|
522 |
+
* @return void
|
523 |
+
*/
|
524 |
+
public function processAdditional()
|
525 |
+
{
|
526 |
+
/*
|
527 |
+
We override this method because we don't want the PHP version to
|
528 |
+
run during CSS processing because it is wasted processing time.
|
529 |
+
*/
|
530 |
+
|
531 |
+
}//end processAdditional()
|
532 |
+
|
533 |
+
|
534 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Tokenizers/Comment.php
ADDED
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Tokenizes doc block comments.
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Tokenizers;
|
11 |
+
|
12 |
+
use PHP_CodeSniffer\Util;
|
13 |
+
|
14 |
+
class Comment
|
15 |
+
{
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Creates an array of tokens when given some PHP code.
|
20 |
+
*
|
21 |
+
* Starts by using token_get_all() but does a lot of extra processing
|
22 |
+
* to insert information about the context of the token.
|
23 |
+
*
|
24 |
+
* @param string $string The string to tokenize.
|
25 |
+
* @param string $eolChar The EOL character to use for splitting strings.
|
26 |
+
* @param int $stackPtr The position of the first token in the file.
|
27 |
+
*
|
28 |
+
* @return array
|
29 |
+
*/
|
30 |
+
public function tokenizeString($string, $eolChar, $stackPtr)
|
31 |
+
{
|
32 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
33 |
+
echo "\t\t*** START COMMENT TOKENIZING ***".PHP_EOL;
|
34 |
+
}
|
35 |
+
|
36 |
+
$tokens = [];
|
37 |
+
$numChars = strlen($string);
|
38 |
+
|
39 |
+
/*
|
40 |
+
Doc block comments start with /*, but typically contain an
|
41 |
+
extra star when they are used for function and class comments.
|
42 |
+
*/
|
43 |
+
|
44 |
+
$char = ($numChars - strlen(ltrim($string, '/*')));
|
45 |
+
$openTag = substr($string, 0, $char);
|
46 |
+
$string = ltrim($string, '/*');
|
47 |
+
|
48 |
+
$tokens[$stackPtr] = [
|
49 |
+
'content' => $openTag,
|
50 |
+
'code' => T_DOC_COMMENT_OPEN_TAG,
|
51 |
+
'type' => 'T_DOC_COMMENT_OPEN_TAG',
|
52 |
+
'comment_tags' => [],
|
53 |
+
];
|
54 |
+
|
55 |
+
$openPtr = $stackPtr;
|
56 |
+
$stackPtr++;
|
57 |
+
|
58 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
59 |
+
$content = Util\Common::prepareForOutput($openTag);
|
60 |
+
echo "\t\tCreate comment token: T_DOC_COMMENT_OPEN_TAG => $content".PHP_EOL;
|
61 |
+
}
|
62 |
+
|
63 |
+
/*
|
64 |
+
Strip off the close tag so it doesn't interfere with any
|
65 |
+
of our comment line processing. The token will be added to the
|
66 |
+
stack just before we return it.
|
67 |
+
*/
|
68 |
+
|
69 |
+
$closeTag = [
|
70 |
+
'content' => substr($string, strlen(rtrim($string, '/*'))),
|
71 |
+
'code' => T_DOC_COMMENT_CLOSE_TAG,
|
72 |
+
'type' => 'T_DOC_COMMENT_CLOSE_TAG',
|
73 |
+
'comment_opener' => $openPtr,
|
74 |
+
];
|
75 |
+
|
76 |
+
if ($closeTag['content'] === false) {
|
77 |
+
$closeTag['content'] = '';
|
78 |
+
}
|
79 |
+
|
80 |
+
$string = rtrim($string, '/*');
|
81 |
+
|
82 |
+
/*
|
83 |
+
Process each line of the comment.
|
84 |
+
*/
|
85 |
+
|
86 |
+
$lines = explode($eolChar, $string);
|
87 |
+
$numLines = count($lines);
|
88 |
+
foreach ($lines as $lineNum => $string) {
|
89 |
+
if ($lineNum !== ($numLines - 1)) {
|
90 |
+
$string .= $eolChar;
|
91 |
+
}
|
92 |
+
|
93 |
+
$char = 0;
|
94 |
+
$numChars = strlen($string);
|
95 |
+
|
96 |
+
// We've started a new line, so process the indent.
|
97 |
+
$space = $this->collectWhitespace($string, $char, $numChars);
|
98 |
+
if ($space !== null) {
|
99 |
+
$tokens[$stackPtr] = $space;
|
100 |
+
$stackPtr++;
|
101 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
102 |
+
$content = Util\Common::prepareForOutput($space['content']);
|
103 |
+
echo "\t\tCreate comment token: T_DOC_COMMENT_WHITESPACE => $content".PHP_EOL;
|
104 |
+
}
|
105 |
+
|
106 |
+
$char += strlen($space['content']);
|
107 |
+
if ($char === $numChars) {
|
108 |
+
break;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
if ($string === '') {
|
113 |
+
continue;
|
114 |
+
}
|
115 |
+
|
116 |
+
if ($lineNum > 0 && $string[$char] === '*') {
|
117 |
+
// This is a function or class doc block line.
|
118 |
+
$char++;
|
119 |
+
$tokens[$stackPtr] = [
|
120 |
+
'content' => '*',
|
121 |
+
'code' => T_DOC_COMMENT_STAR,
|
122 |
+
'type' => 'T_DOC_COMMENT_STAR',
|
123 |
+
];
|
124 |
+
|
125 |
+
$stackPtr++;
|
126 |
+
|
127 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
128 |
+
echo "\t\tCreate comment token: T_DOC_COMMENT_STAR => *".PHP_EOL;
|
129 |
+
}
|
130 |
+
}
|
131 |
+
|
132 |
+
// Now we are ready to process the actual content of the line.
|
133 |
+
$lineTokens = $this->processLine($string, $eolChar, $char, $numChars);
|
134 |
+
foreach ($lineTokens as $lineToken) {
|
135 |
+
$tokens[$stackPtr] = $lineToken;
|
136 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
137 |
+
$content = Util\Common::prepareForOutput($lineToken['content']);
|
138 |
+
$type = $lineToken['type'];
|
139 |
+
echo "\t\tCreate comment token: $type => $content".PHP_EOL;
|
140 |
+
}
|
141 |
+
|
142 |
+
if ($lineToken['code'] === T_DOC_COMMENT_TAG) {
|
143 |
+
$tokens[$openPtr]['comment_tags'][] = $stackPtr;
|
144 |
+
}
|
145 |
+
|
146 |
+
$stackPtr++;
|
147 |
+
}
|
148 |
+
}//end foreach
|
149 |
+
|
150 |
+
$tokens[$stackPtr] = $closeTag;
|
151 |
+
$tokens[$openPtr]['comment_closer'] = $stackPtr;
|
152 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
153 |
+
$content = Util\Common::prepareForOutput($closeTag['content']);
|
154 |
+
echo "\t\tCreate comment token: T_DOC_COMMENT_CLOSE_TAG => $content".PHP_EOL;
|
155 |
+
}
|
156 |
+
|
157 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
158 |
+
echo "\t\t*** END COMMENT TOKENIZING ***".PHP_EOL;
|
159 |
+
}
|
160 |
+
|
161 |
+
return $tokens;
|
162 |
+
|
163 |
+
}//end tokenizeString()
|
164 |
+
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Process a single line of a comment.
|
168 |
+
*
|
169 |
+
* @param string $string The comment string being tokenized.
|
170 |
+
* @param string $eolChar The EOL character to use for splitting strings.
|
171 |
+
* @param int $start The position in the string to start processing.
|
172 |
+
* @param int $end The position in the string to end processing.
|
173 |
+
*
|
174 |
+
* @return array
|
175 |
+
*/
|
176 |
+
private function processLine($string, $eolChar, $start, $end)
|
177 |
+
{
|
178 |
+
$tokens = [];
|
179 |
+
|
180 |
+
// Collect content padding.
|
181 |
+
$space = $this->collectWhitespace($string, $start, $end);
|
182 |
+
if ($space !== null) {
|
183 |
+
$tokens[] = $space;
|
184 |
+
$start += strlen($space['content']);
|
185 |
+
}
|
186 |
+
|
187 |
+
if (isset($string[$start]) === false) {
|
188 |
+
return $tokens;
|
189 |
+
}
|
190 |
+
|
191 |
+
if ($string[$start] === '@') {
|
192 |
+
// The content up until the first whitespace is the tag name.
|
193 |
+
$matches = [];
|
194 |
+
preg_match('/@[^\s]+/', $string, $matches, 0, $start);
|
195 |
+
if (isset($matches[0]) === true
|
196 |
+
&& substr(strtolower($matches[0]), 0, 7) !== '@phpcs:'
|
197 |
+
) {
|
198 |
+
$tagName = $matches[0];
|
199 |
+
$start += strlen($tagName);
|
200 |
+
$tokens[] = [
|
201 |
+
'content' => $tagName,
|
202 |
+
'code' => T_DOC_COMMENT_TAG,
|
203 |
+
'type' => 'T_DOC_COMMENT_TAG',
|
204 |
+
];
|
205 |
+
|
206 |
+
// Then there will be some whitespace.
|
207 |
+
$space = $this->collectWhitespace($string, $start, $end);
|
208 |
+
if ($space !== null) {
|
209 |
+
$tokens[] = $space;
|
210 |
+
$start += strlen($space['content']);
|
211 |
+
}
|
212 |
+
}
|
213 |
+
}//end if
|
214 |
+
|
215 |
+
// Process the rest of the line.
|
216 |
+
$eol = strpos($string, $eolChar, $start);
|
217 |
+
if ($eol === false) {
|
218 |
+
$eol = $end;
|
219 |
+
}
|
220 |
+
|
221 |
+
if ($eol > $start) {
|
222 |
+
$tokens[] = [
|
223 |
+
'content' => substr($string, $start, ($eol - $start)),
|
224 |
+
'code' => T_DOC_COMMENT_STRING,
|
225 |
+
'type' => 'T_DOC_COMMENT_STRING',
|
226 |
+
];
|
227 |
+
}
|
228 |
+
|
229 |
+
if ($eol !== $end) {
|
230 |
+
$tokens[] = [
|
231 |
+
'content' => substr($string, $eol, strlen($eolChar)),
|
232 |
+
'code' => T_DOC_COMMENT_WHITESPACE,
|
233 |
+
'type' => 'T_DOC_COMMENT_WHITESPACE',
|
234 |
+
];
|
235 |
+
}
|
236 |
+
|
237 |
+
return $tokens;
|
238 |
+
|
239 |
+
}//end processLine()
|
240 |
+
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Collect consecutive whitespace into a single token.
|
244 |
+
*
|
245 |
+
* @param string $string The comment string being tokenized.
|
246 |
+
* @param int $start The position in the string to start processing.
|
247 |
+
* @param int $end The position in the string to end processing.
|
248 |
+
*
|
249 |
+
* @return array|null
|
250 |
+
*/
|
251 |
+
private function collectWhitespace($string, $start, $end)
|
252 |
+
{
|
253 |
+
$space = '';
|
254 |
+
for ($start; $start < $end; $start++) {
|
255 |
+
if ($string[$start] !== ' ' && $string[$start] !== "\t") {
|
256 |
+
break;
|
257 |
+
}
|
258 |
+
|
259 |
+
$space .= $string[$start];
|
260 |
+
}
|
261 |
+
|
262 |
+
if ($space === '') {
|
263 |
+
return null;
|
264 |
+
}
|
265 |
+
|
266 |
+
$token = [
|
267 |
+
'content' => $space,
|
268 |
+
'code' => T_DOC_COMMENT_WHITESPACE,
|
269 |
+
'type' => 'T_DOC_COMMENT_WHITESPACE',
|
270 |
+
];
|
271 |
+
|
272 |
+
return $token;
|
273 |
+
|
274 |
+
}//end collectWhitespace()
|
275 |
+
|
276 |
+
|
277 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Tokenizers/JS.php
ADDED
@@ -0,0 +1,1264 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Tokenizes JS code.
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Tokenizers;
|
11 |
+
|
12 |
+
use PHP_CodeSniffer\Util;
|
13 |
+
use PHP_CodeSniffer\Exceptions\TokenizerException;
|
14 |
+
use PHP_CodeSniffer\Config;
|
15 |
+
|
16 |
+
class JS extends Tokenizer
|
17 |
+
{
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* A list of tokens that are allowed to open a scope.
|
22 |
+
*
|
23 |
+
* This array also contains information about what kind of token the scope
|
24 |
+
* opener uses to open and close the scope, if the token strictly requires
|
25 |
+
* an opener, if the token can share a scope closer, and who it can be shared
|
26 |
+
* with. An example of a token that shares a scope closer is a CASE scope.
|
27 |
+
*
|
28 |
+
* @var array
|
29 |
+
*/
|
30 |
+
public $scopeOpeners = [
|
31 |
+
T_IF => [
|
32 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
33 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
34 |
+
'strict' => false,
|
35 |
+
'shared' => false,
|
36 |
+
'with' => [],
|
37 |
+
],
|
38 |
+
T_TRY => [
|
39 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
40 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
41 |
+
'strict' => true,
|
42 |
+
'shared' => false,
|
43 |
+
'with' => [],
|
44 |
+
],
|
45 |
+
T_CATCH => [
|
46 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
47 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
48 |
+
'strict' => true,
|
49 |
+
'shared' => false,
|
50 |
+
'with' => [],
|
51 |
+
],
|
52 |
+
T_ELSE => [
|
53 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
54 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
55 |
+
'strict' => false,
|
56 |
+
'shared' => false,
|
57 |
+
'with' => [],
|
58 |
+
],
|
59 |
+
T_FOR => [
|
60 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
61 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
62 |
+
'strict' => false,
|
63 |
+
'shared' => false,
|
64 |
+
'with' => [],
|
65 |
+
],
|
66 |
+
T_CLASS => [
|
67 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
68 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
69 |
+
'strict' => true,
|
70 |
+
'shared' => false,
|
71 |
+
'with' => [],
|
72 |
+
],
|
73 |
+
T_FUNCTION => [
|
74 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
75 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
76 |
+
'strict' => false,
|
77 |
+
'shared' => false,
|
78 |
+
'with' => [],
|
79 |
+
],
|
80 |
+
T_WHILE => [
|
81 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
82 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
83 |
+
'strict' => false,
|
84 |
+
'shared' => false,
|
85 |
+
'with' => [],
|
86 |
+
],
|
87 |
+
T_DO => [
|
88 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
89 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
90 |
+
'strict' => true,
|
91 |
+
'shared' => false,
|
92 |
+
'with' => [],
|
93 |
+
],
|
94 |
+
T_SWITCH => [
|
95 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
96 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
97 |
+
'strict' => true,
|
98 |
+
'shared' => false,
|
99 |
+
'with' => [],
|
100 |
+
],
|
101 |
+
T_CASE => [
|
102 |
+
'start' => [T_COLON => T_COLON],
|
103 |
+
'end' => [
|
104 |
+
T_BREAK => T_BREAK,
|
105 |
+
T_RETURN => T_RETURN,
|
106 |
+
T_CONTINUE => T_CONTINUE,
|
107 |
+
T_THROW => T_THROW,
|
108 |
+
],
|
109 |
+
'strict' => true,
|
110 |
+
'shared' => true,
|
111 |
+
'with' => [
|
112 |
+
T_DEFAULT => T_DEFAULT,
|
113 |
+
T_CASE => T_CASE,
|
114 |
+
T_SWITCH => T_SWITCH,
|
115 |
+
],
|
116 |
+
],
|
117 |
+
T_DEFAULT => [
|
118 |
+
'start' => [T_COLON => T_COLON],
|
119 |
+
'end' => [
|
120 |
+
T_BREAK => T_BREAK,
|
121 |
+
T_RETURN => T_RETURN,
|
122 |
+
T_CONTINUE => T_CONTINUE,
|
123 |
+
T_THROW => T_THROW,
|
124 |
+
],
|
125 |
+
'strict' => true,
|
126 |
+
'shared' => true,
|
127 |
+
'with' => [
|
128 |
+
T_CASE => T_CASE,
|
129 |
+
T_SWITCH => T_SWITCH,
|
130 |
+
],
|
131 |
+
],
|
132 |
+
];
|
133 |
+
|
134 |
+
/**
|
135 |
+
* A list of tokens that end the scope.
|
136 |
+
*
|
137 |
+
* This array is just a unique collection of the end tokens
|
138 |
+
* from the _scopeOpeners array. The data is duplicated here to
|
139 |
+
* save time during parsing of the file.
|
140 |
+
*
|
141 |
+
* @var array
|
142 |
+
*/
|
143 |
+
public $endScopeTokens = [
|
144 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
145 |
+
T_BREAK => T_BREAK,
|
146 |
+
];
|
147 |
+
|
148 |
+
/**
|
149 |
+
* A list of special JS tokens and their types.
|
150 |
+
*
|
151 |
+
* @var array
|
152 |
+
*/
|
153 |
+
protected $tokenValues = [
|
154 |
+
'class' => 'T_CLASS',
|
155 |
+
'function' => 'T_FUNCTION',
|
156 |
+
'prototype' => 'T_PROTOTYPE',
|
157 |
+
'try' => 'T_TRY',
|
158 |
+
'catch' => 'T_CATCH',
|
159 |
+
'return' => 'T_RETURN',
|
160 |
+
'throw' => 'T_THROW',
|
161 |
+
'break' => 'T_BREAK',
|
162 |
+
'switch' => 'T_SWITCH',
|
163 |
+
'continue' => 'T_CONTINUE',
|
164 |
+
'if' => 'T_IF',
|
165 |
+
'else' => 'T_ELSE',
|
166 |
+
'do' => 'T_DO',
|
167 |
+
'while' => 'T_WHILE',
|
168 |
+
'for' => 'T_FOR',
|
169 |
+
'var' => 'T_VAR',
|
170 |
+
'case' => 'T_CASE',
|
171 |
+
'default' => 'T_DEFAULT',
|
172 |
+
'true' => 'T_TRUE',
|
173 |
+
'false' => 'T_FALSE',
|
174 |
+
'null' => 'T_NULL',
|
175 |
+
'this' => 'T_THIS',
|
176 |
+
'typeof' => 'T_TYPEOF',
|
177 |
+
'(' => 'T_OPEN_PARENTHESIS',
|
178 |
+
')' => 'T_CLOSE_PARENTHESIS',
|
179 |
+
'{' => 'T_OPEN_CURLY_BRACKET',
|
180 |
+
'}' => 'T_CLOSE_CURLY_BRACKET',
|
181 |
+
'[' => 'T_OPEN_SQUARE_BRACKET',
|
182 |
+
']' => 'T_CLOSE_SQUARE_BRACKET',
|
183 |
+
'?' => 'T_INLINE_THEN',
|
184 |
+
'.' => 'T_OBJECT_OPERATOR',
|
185 |
+
'+' => 'T_PLUS',
|
186 |
+
'-' => 'T_MINUS',
|
187 |
+
'*' => 'T_MULTIPLY',
|
188 |
+
'%' => 'T_MODULUS',
|
189 |
+
'/' => 'T_DIVIDE',
|
190 |
+
'^' => 'T_LOGICAL_XOR',
|
191 |
+
',' => 'T_COMMA',
|
192 |
+
';' => 'T_SEMICOLON',
|
193 |
+
':' => 'T_COLON',
|
194 |
+
'<' => 'T_LESS_THAN',
|
195 |
+
'>' => 'T_GREATER_THAN',
|
196 |
+
'<<' => 'T_SL',
|
197 |
+
'>>' => 'T_SR',
|
198 |
+
'>>>' => 'T_ZSR',
|
199 |
+
'<<=' => 'T_SL_EQUAL',
|
200 |
+
'>>=' => 'T_SR_EQUAL',
|
201 |
+
'>>>=' => 'T_ZSR_EQUAL',
|
202 |
+
'<=' => 'T_IS_SMALLER_OR_EQUAL',
|
203 |
+
'>=' => 'T_IS_GREATER_OR_EQUAL',
|
204 |
+
'=>' => 'T_DOUBLE_ARROW',
|
205 |
+
'!' => 'T_BOOLEAN_NOT',
|
206 |
+
'||' => 'T_BOOLEAN_OR',
|
207 |
+
'&&' => 'T_BOOLEAN_AND',
|
208 |
+
'|' => 'T_BITWISE_OR',
|
209 |
+
'&' => 'T_BITWISE_AND',
|
210 |
+
'!=' => 'T_IS_NOT_EQUAL',
|
211 |
+
'!==' => 'T_IS_NOT_IDENTICAL',
|
212 |
+
'=' => 'T_EQUAL',
|
213 |
+
'==' => 'T_IS_EQUAL',
|
214 |
+
'===' => 'T_IS_IDENTICAL',
|
215 |
+
'-=' => 'T_MINUS_EQUAL',
|
216 |
+
'+=' => 'T_PLUS_EQUAL',
|
217 |
+
'*=' => 'T_MUL_EQUAL',
|
218 |
+
'/=' => 'T_DIV_EQUAL',
|
219 |
+
'%=' => 'T_MOD_EQUAL',
|
220 |
+
'++' => 'T_INC',
|
221 |
+
'--' => 'T_DEC',
|
222 |
+
'//' => 'T_COMMENT',
|
223 |
+
'/*' => 'T_COMMENT',
|
224 |
+
'/**' => 'T_DOC_COMMENT',
|
225 |
+
'*/' => 'T_COMMENT',
|
226 |
+
];
|
227 |
+
|
228 |
+
/**
|
229 |
+
* A list string delimiters.
|
230 |
+
*
|
231 |
+
* @var array
|
232 |
+
*/
|
233 |
+
protected $stringTokens = [
|
234 |
+
'\'' => '\'',
|
235 |
+
'"' => '"',
|
236 |
+
];
|
237 |
+
|
238 |
+
/**
|
239 |
+
* A list tokens that start and end comments.
|
240 |
+
*
|
241 |
+
* @var array
|
242 |
+
*/
|
243 |
+
protected $commentTokens = [
|
244 |
+
'//' => null,
|
245 |
+
'/*' => '*/',
|
246 |
+
'/**' => '*/',
|
247 |
+
];
|
248 |
+
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Initialise the tokenizer.
|
252 |
+
*
|
253 |
+
* Pre-checks the content to see if it looks minified.
|
254 |
+
*
|
255 |
+
* @param string $content The content to tokenize,
|
256 |
+
* @param \PHP_CodeSniffer\Config $config The config data for the run.
|
257 |
+
* @param string $eolChar The EOL char used in the content.
|
258 |
+
*
|
259 |
+
* @return void
|
260 |
+
* @throws TokenizerException If the file appears to be minified.
|
261 |
+
*/
|
262 |
+
public function __construct($content, Config $config, $eolChar='\n')
|
263 |
+
{
|
264 |
+
if ($this->isMinifiedContent($content, $eolChar) === true) {
|
265 |
+
throw new TokenizerException('File appears to be minified and cannot be processed');
|
266 |
+
}
|
267 |
+
|
268 |
+
return parent::__construct($content, $config, $eolChar);
|
269 |
+
|
270 |
+
}//end __construct()
|
271 |
+
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Creates an array of tokens when given some JS code.
|
275 |
+
*
|
276 |
+
* @param string $string The string to tokenize.
|
277 |
+
*
|
278 |
+
* @return array
|
279 |
+
*/
|
280 |
+
public function tokenize($string)
|
281 |
+
{
|
282 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
283 |
+
echo "\t*** START JS TOKENIZING ***".PHP_EOL;
|
284 |
+
}
|
285 |
+
|
286 |
+
$maxTokenLength = 0;
|
287 |
+
foreach ($this->tokenValues as $token => $values) {
|
288 |
+
if (strlen($token) > $maxTokenLength) {
|
289 |
+
$maxTokenLength = strlen($token);
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
$tokens = [];
|
294 |
+
$inString = '';
|
295 |
+
$stringChar = null;
|
296 |
+
$inComment = '';
|
297 |
+
$buffer = '';
|
298 |
+
$preStringBuffer = '';
|
299 |
+
$cleanBuffer = false;
|
300 |
+
|
301 |
+
$commentTokenizer = new Comment();
|
302 |
+
|
303 |
+
$tokens[] = [
|
304 |
+
'code' => T_OPEN_TAG,
|
305 |
+
'type' => 'T_OPEN_TAG',
|
306 |
+
'content' => '',
|
307 |
+
];
|
308 |
+
|
309 |
+
// Convert newlines to single characters for ease of
|
310 |
+
// processing. We will change them back later.
|
311 |
+
$string = str_replace($this->eolChar, "\n", $string);
|
312 |
+
|
313 |
+
$chars = str_split($string);
|
314 |
+
$numChars = count($chars);
|
315 |
+
for ($i = 0; $i < $numChars; $i++) {
|
316 |
+
$char = $chars[$i];
|
317 |
+
|
318 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
319 |
+
$content = Util\Common::prepareForOutput($char);
|
320 |
+
$bufferContent = Util\Common::prepareForOutput($buffer);
|
321 |
+
|
322 |
+
if ($inString !== '') {
|
323 |
+
echo "\t";
|
324 |
+
}
|
325 |
+
|
326 |
+
if ($inComment !== '') {
|
327 |
+
echo "\t";
|
328 |
+
}
|
329 |
+
|
330 |
+
echo "\tProcess char $i => $content (buffer: $bufferContent)".PHP_EOL;
|
331 |
+
}//end if
|
332 |
+
|
333 |
+
if ($inString === '' && $inComment === '' && $buffer !== '') {
|
334 |
+
// If the buffer only has whitespace and we are about to
|
335 |
+
// add a character, store the whitespace first.
|
336 |
+
if (trim($char) !== '' && trim($buffer) === '') {
|
337 |
+
$tokens[] = [
|
338 |
+
'code' => T_WHITESPACE,
|
339 |
+
'type' => 'T_WHITESPACE',
|
340 |
+
'content' => str_replace("\n", $this->eolChar, $buffer),
|
341 |
+
];
|
342 |
+
|
343 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
344 |
+
$content = Util\Common::prepareForOutput($buffer);
|
345 |
+
echo "\t=> Added token T_WHITESPACE ($content)".PHP_EOL;
|
346 |
+
}
|
347 |
+
|
348 |
+
$buffer = '';
|
349 |
+
}
|
350 |
+
|
351 |
+
// If the buffer is not whitespace and we are about to
|
352 |
+
// add a whitespace character, store the content first.
|
353 |
+
if ($inString === ''
|
354 |
+
&& $inComment === ''
|
355 |
+
&& trim($char) === ''
|
356 |
+
&& trim($buffer) !== ''
|
357 |
+
) {
|
358 |
+
$tokens[] = [
|
359 |
+
'code' => T_STRING,
|
360 |
+
'type' => 'T_STRING',
|
361 |
+
'content' => str_replace("\n", $this->eolChar, $buffer),
|
362 |
+
];
|
363 |
+
|
364 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
365 |
+
$content = Util\Common::prepareForOutput($buffer);
|
366 |
+
echo "\t=> Added token T_STRING ($content)".PHP_EOL;
|
367 |
+
}
|
368 |
+
|
369 |
+
$buffer = '';
|
370 |
+
}
|
371 |
+
}//end if
|
372 |
+
|
373 |
+
// Process strings.
|
374 |
+
if ($inComment === '' && isset($this->stringTokens[$char]) === true) {
|
375 |
+
if ($inString === $char) {
|
376 |
+
// This could be the end of the string, but make sure it
|
377 |
+
// is not escaped first.
|
378 |
+
$escapes = 0;
|
379 |
+
for ($x = ($i - 1); $x >= 0; $x--) {
|
380 |
+
if ($chars[$x] !== '\\') {
|
381 |
+
break;
|
382 |
+
}
|
383 |
+
|
384 |
+
$escapes++;
|
385 |
+
}
|
386 |
+
|
387 |
+
if ($escapes === 0 || ($escapes % 2) === 0) {
|
388 |
+
// There is an even number escape chars,
|
389 |
+
// so this is not escaped, it is the end of the string.
|
390 |
+
$tokens[] = [
|
391 |
+
'code' => T_CONSTANT_ENCAPSED_STRING,
|
392 |
+
'type' => 'T_CONSTANT_ENCAPSED_STRING',
|
393 |
+
'content' => str_replace("\n", $this->eolChar, $buffer).$char,
|
394 |
+
];
|
395 |
+
|
396 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
397 |
+
echo "\t\t* found end of string *".PHP_EOL;
|
398 |
+
$content = Util\Common::prepareForOutput($buffer.$char);
|
399 |
+
echo "\t=> Added token T_CONSTANT_ENCAPSED_STRING ($content)".PHP_EOL;
|
400 |
+
}
|
401 |
+
|
402 |
+
$buffer = '';
|
403 |
+
$preStringBuffer = '';
|
404 |
+
$inString = '';
|
405 |
+
$stringChar = null;
|
406 |
+
continue;
|
407 |
+
}//end if
|
408 |
+
} else if ($inString === '') {
|
409 |
+
$inString = $char;
|
410 |
+
$stringChar = $i;
|
411 |
+
$preStringBuffer = $buffer;
|
412 |
+
|
413 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
414 |
+
echo "\t\t* looking for string closer *".PHP_EOL;
|
415 |
+
}
|
416 |
+
}//end if
|
417 |
+
}//end if
|
418 |
+
|
419 |
+
if ($inString !== '' && $char === "\n") {
|
420 |
+
// Unless this newline character is escaped, the string did not
|
421 |
+
// end before the end of the line, which means it probably
|
422 |
+
// wasn't a string at all (maybe a regex).
|
423 |
+
if ($chars[($i - 1)] !== '\\') {
|
424 |
+
$i = $stringChar;
|
425 |
+
$buffer = $preStringBuffer;
|
426 |
+
$preStringBuffer = '';
|
427 |
+
$inString = '';
|
428 |
+
$stringChar = null;
|
429 |
+
$char = $chars[$i];
|
430 |
+
|
431 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
432 |
+
echo "\t\t* found newline before end of string, bailing *".PHP_EOL;
|
433 |
+
}
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
$buffer .= $char;
|
438 |
+
|
439 |
+
// We don't look for special tokens inside strings,
|
440 |
+
// so if we are in a string, we can continue here now
|
441 |
+
// that the current char is in the buffer.
|
442 |
+
if ($inString !== '') {
|
443 |
+
continue;
|
444 |
+
}
|
445 |
+
|
446 |
+
// Special case for T_DIVIDE which can actually be
|
447 |
+
// the start of a regular expression.
|
448 |
+
if ($buffer === $char && $char === '/' && $chars[($i + 1)] !== '*') {
|
449 |
+
$regex = $this->getRegexToken(
|
450 |
+
$i,
|
451 |
+
$string,
|
452 |
+
$chars,
|
453 |
+
$tokens,
|
454 |
+
$this->eolChar
|
455 |
+
);
|
456 |
+
|
457 |
+
if ($regex !== null) {
|
458 |
+
$tokens[] = [
|
459 |
+
'code' => T_REGULAR_EXPRESSION,
|
460 |
+
'type' => 'T_REGULAR_EXPRESSION',
|
461 |
+
'content' => $regex['content'],
|
462 |
+
];
|
463 |
+
|
464 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
465 |
+
$content = Util\Common::prepareForOutput($regex['content']);
|
466 |
+
echo "\t=> Added token T_REGULAR_EXPRESSION ($content)".PHP_EOL;
|
467 |
+
}
|
468 |
+
|
469 |
+
$i = $regex['end'];
|
470 |
+
$buffer = '';
|
471 |
+
$cleanBuffer = false;
|
472 |
+
continue;
|
473 |
+
}//end if
|
474 |
+
}//end if
|
475 |
+
|
476 |
+
// Check for known tokens, but ignore tokens found that are not at
|
477 |
+
// the end of a string, like FOR and this.FORmat.
|
478 |
+
if (isset($this->tokenValues[strtolower($buffer)]) === true
|
479 |
+
&& (preg_match('|[a-zA-z0-9_]|', $char) === 0
|
480 |
+
|| isset($chars[($i + 1)]) === false
|
481 |
+
|| preg_match('|[a-zA-z0-9_]|', $chars[($i + 1)]) === 0)
|
482 |
+
) {
|
483 |
+
$matchedToken = false;
|
484 |
+
$lookAheadLength = ($maxTokenLength - strlen($buffer));
|
485 |
+
|
486 |
+
if ($lookAheadLength > 0) {
|
487 |
+
// The buffer contains a token type, but we need
|
488 |
+
// to look ahead at the next chars to see if this is
|
489 |
+
// actually part of a larger token. For example,
|
490 |
+
// FOR and FOREACH.
|
491 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
492 |
+
echo "\t\t* buffer possibly contains token, looking ahead $lookAheadLength chars *".PHP_EOL;
|
493 |
+
}
|
494 |
+
|
495 |
+
$charBuffer = $buffer;
|
496 |
+
for ($x = 1; $x <= $lookAheadLength; $x++) {
|
497 |
+
if (isset($chars[($i + $x)]) === false) {
|
498 |
+
break;
|
499 |
+
}
|
500 |
+
|
501 |
+
$charBuffer .= $chars[($i + $x)];
|
502 |
+
|
503 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
504 |
+
$content = Util\Common::prepareForOutput($charBuffer);
|
505 |
+
echo "\t\t=> Looking ahead $x chars => $content".PHP_EOL;
|
506 |
+
}
|
507 |
+
|
508 |
+
if (isset($this->tokenValues[strtolower($charBuffer)]) === true) {
|
509 |
+
// We've found something larger that matches
|
510 |
+
// so we can ignore this char. Except for 1 very specific
|
511 |
+
// case where a comment like /**/ needs to tokenize as
|
512 |
+
// T_COMMENT and not T_DOC_COMMENT.
|
513 |
+
$oldType = $this->tokenValues[strtolower($buffer)];
|
514 |
+
$newType = $this->tokenValues[strtolower($charBuffer)];
|
515 |
+
if ($oldType === 'T_COMMENT'
|
516 |
+
&& $newType === 'T_DOC_COMMENT'
|
517 |
+
&& $chars[($i + $x + 1)] === '/'
|
518 |
+
) {
|
519 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
520 |
+
echo "\t\t* look ahead ignored T_DOC_COMMENT, continuing *".PHP_EOL;
|
521 |
+
}
|
522 |
+
} else {
|
523 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
524 |
+
echo "\t\t* look ahead found more specific token ($newType), ignoring $i *".PHP_EOL;
|
525 |
+
}
|
526 |
+
|
527 |
+
$matchedToken = true;
|
528 |
+
break;
|
529 |
+
}
|
530 |
+
}//end if
|
531 |
+
}//end for
|
532 |
+
}//end if
|
533 |
+
|
534 |
+
if ($matchedToken === false) {
|
535 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1 && $lookAheadLength > 0) {
|
536 |
+
echo "\t\t* look ahead found nothing *".PHP_EOL;
|
537 |
+
}
|
538 |
+
|
539 |
+
$value = $this->tokenValues[strtolower($buffer)];
|
540 |
+
|
541 |
+
if ($value === 'T_FUNCTION' && $buffer !== 'function') {
|
542 |
+
// The function keyword needs to be all lowercase or else
|
543 |
+
// it is just a function called "Function".
|
544 |
+
$value = 'T_STRING';
|
545 |
+
}
|
546 |
+
|
547 |
+
$tokens[] = [
|
548 |
+
'code' => constant($value),
|
549 |
+
'type' => $value,
|
550 |
+
'content' => $buffer,
|
551 |
+
];
|
552 |
+
|
553 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
554 |
+
$content = Util\Common::prepareForOutput($buffer);
|
555 |
+
echo "\t=> Added token $value ($content)".PHP_EOL;
|
556 |
+
}
|
557 |
+
|
558 |
+
$cleanBuffer = true;
|
559 |
+
}//end if
|
560 |
+
} else if (isset($this->tokenValues[strtolower($char)]) === true) {
|
561 |
+
// No matter what token we end up using, we don't
|
562 |
+
// need the content in the buffer any more because we have
|
563 |
+
// found a valid token.
|
564 |
+
$newContent = substr(str_replace("\n", $this->eolChar, $buffer), 0, -1);
|
565 |
+
if ($newContent !== '') {
|
566 |
+
$tokens[] = [
|
567 |
+
'code' => T_STRING,
|
568 |
+
'type' => 'T_STRING',
|
569 |
+
'content' => $newContent,
|
570 |
+
];
|
571 |
+
|
572 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
573 |
+
$content = Util\Common::prepareForOutput(substr($buffer, 0, -1));
|
574 |
+
echo "\t=> Added token T_STRING ($content)".PHP_EOL;
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
579 |
+
echo "\t\t* char is token, looking ahead ".($maxTokenLength - 1).' chars *'.PHP_EOL;
|
580 |
+
}
|
581 |
+
|
582 |
+
// The char is a token type, but we need to look ahead at the
|
583 |
+
// next chars to see if this is actually part of a larger token.
|
584 |
+
// For example, = and ===.
|
585 |
+
$charBuffer = $char;
|
586 |
+
$matchedToken = false;
|
587 |
+
for ($x = 1; $x <= $maxTokenLength; $x++) {
|
588 |
+
if (isset($chars[($i + $x)]) === false) {
|
589 |
+
break;
|
590 |
+
}
|
591 |
+
|
592 |
+
$charBuffer .= $chars[($i + $x)];
|
593 |
+
|
594 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
595 |
+
$content = Util\Common::prepareForOutput($charBuffer);
|
596 |
+
echo "\t\t=> Looking ahead $x chars => $content".PHP_EOL;
|
597 |
+
}
|
598 |
+
|
599 |
+
if (isset($this->tokenValues[strtolower($charBuffer)]) === true) {
|
600 |
+
// We've found something larger that matches
|
601 |
+
// so we can ignore this char.
|
602 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
603 |
+
$type = $this->tokenValues[strtolower($charBuffer)];
|
604 |
+
echo "\t\t* look ahead found more specific token ($type), ignoring $i *".PHP_EOL;
|
605 |
+
}
|
606 |
+
|
607 |
+
$matchedToken = true;
|
608 |
+
break;
|
609 |
+
}
|
610 |
+
}//end for
|
611 |
+
|
612 |
+
if ($matchedToken === false) {
|
613 |
+
$value = $this->tokenValues[strtolower($char)];
|
614 |
+
$tokens[] = [
|
615 |
+
'code' => constant($value),
|
616 |
+
'type' => $value,
|
617 |
+
'content' => $char,
|
618 |
+
];
|
619 |
+
|
620 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
621 |
+
echo "\t\t* look ahead found nothing *".PHP_EOL;
|
622 |
+
$content = Util\Common::prepareForOutput($char);
|
623 |
+
echo "\t=> Added token $value ($content)".PHP_EOL;
|
624 |
+
}
|
625 |
+
|
626 |
+
$cleanBuffer = true;
|
627 |
+
} else {
|
628 |
+
$buffer = $char;
|
629 |
+
}//end if
|
630 |
+
}//end if
|
631 |
+
|
632 |
+
// Keep track of content inside comments.
|
633 |
+
if ($inComment === ''
|
634 |
+
&& array_key_exists($buffer, $this->commentTokens) === true
|
635 |
+
) {
|
636 |
+
// This is not really a comment if the content
|
637 |
+
// looks like \// (i.e., it is escaped).
|
638 |
+
if (isset($chars[($i - 2)]) === true && $chars[($i - 2)] === '\\') {
|
639 |
+
$lastToken = array_pop($tokens);
|
640 |
+
$lastContent = $lastToken['content'];
|
641 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
642 |
+
$value = $this->tokenValues[strtolower($lastContent)];
|
643 |
+
$content = Util\Common::prepareForOutput($lastContent);
|
644 |
+
echo "\t=> Removed token $value ($content)".PHP_EOL;
|
645 |
+
}
|
646 |
+
|
647 |
+
$lastChars = str_split($lastContent);
|
648 |
+
$lastNumChars = count($lastChars);
|
649 |
+
for ($x = 0; $x < $lastNumChars; $x++) {
|
650 |
+
$lastChar = $lastChars[$x];
|
651 |
+
$value = $this->tokenValues[strtolower($lastChar)];
|
652 |
+
$tokens[] = [
|
653 |
+
'code' => constant($value),
|
654 |
+
'type' => $value,
|
655 |
+
'content' => $lastChar,
|
656 |
+
];
|
657 |
+
|
658 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
659 |
+
$content = Util\Common::prepareForOutput($lastChar);
|
660 |
+
echo "\t=> Added token $value ($content)".PHP_EOL;
|
661 |
+
}
|
662 |
+
}
|
663 |
+
} else {
|
664 |
+
// We have started a comment.
|
665 |
+
$inComment = $buffer;
|
666 |
+
|
667 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
668 |
+
echo "\t\t* looking for end of comment *".PHP_EOL;
|
669 |
+
}
|
670 |
+
}//end if
|
671 |
+
} else if ($inComment !== '') {
|
672 |
+
if ($this->commentTokens[$inComment] === null) {
|
673 |
+
// Comment ends at the next newline.
|
674 |
+
if (strpos($buffer, "\n") !== false) {
|
675 |
+
$inComment = '';
|
676 |
+
}
|
677 |
+
} else {
|
678 |
+
if ($this->commentTokens[$inComment] === $buffer) {
|
679 |
+
$inComment = '';
|
680 |
+
}
|
681 |
+
}
|
682 |
+
|
683 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
684 |
+
if ($inComment === '') {
|
685 |
+
echo "\t\t* found end of comment *".PHP_EOL;
|
686 |
+
}
|
687 |
+
}
|
688 |
+
|
689 |
+
if ($inComment === '' && $cleanBuffer === false) {
|
690 |
+
$tokens[] = [
|
691 |
+
'code' => T_STRING,
|
692 |
+
'type' => 'T_STRING',
|
693 |
+
'content' => str_replace("\n", $this->eolChar, $buffer),
|
694 |
+
];
|
695 |
+
|
696 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
697 |
+
$content = Util\Common::prepareForOutput($buffer);
|
698 |
+
echo "\t=> Added token T_STRING ($content)".PHP_EOL;
|
699 |
+
}
|
700 |
+
|
701 |
+
$buffer = '';
|
702 |
+
}
|
703 |
+
}//end if
|
704 |
+
|
705 |
+
if ($cleanBuffer === true) {
|
706 |
+
$buffer = '';
|
707 |
+
$cleanBuffer = false;
|
708 |
+
}
|
709 |
+
}//end for
|
710 |
+
|
711 |
+
if (empty($buffer) === false) {
|
712 |
+
if ($inString !== '') {
|
713 |
+
// The string did not end before the end of the file,
|
714 |
+
// which means there was probably a syntax error somewhere.
|
715 |
+
$tokens[] = [
|
716 |
+
'code' => T_STRING,
|
717 |
+
'type' => 'T_STRING',
|
718 |
+
'content' => str_replace("\n", $this->eolChar, $buffer),
|
719 |
+
];
|
720 |
+
|
721 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
722 |
+
$content = Util\Common::prepareForOutput($buffer);
|
723 |
+
echo "\t=> Added token T_STRING ($content)".PHP_EOL;
|
724 |
+
}
|
725 |
+
} else {
|
726 |
+
// Buffer contains whitespace from the end of the file.
|
727 |
+
$tokens[] = [
|
728 |
+
'code' => T_WHITESPACE,
|
729 |
+
'type' => 'T_WHITESPACE',
|
730 |
+
'content' => str_replace("\n", $this->eolChar, $buffer),
|
731 |
+
];
|
732 |
+
|
733 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
734 |
+
$content = Util\Common::prepareForOutput($buffer);
|
735 |
+
echo "\t=> Added token T_WHITESPACE ($content)".PHP_EOL;
|
736 |
+
}
|
737 |
+
}//end if
|
738 |
+
}//end if
|
739 |
+
|
740 |
+
$tokens[] = [
|
741 |
+
'code' => T_CLOSE_TAG,
|
742 |
+
'type' => 'T_CLOSE_TAG',
|
743 |
+
'content' => '',
|
744 |
+
];
|
745 |
+
|
746 |
+
/*
|
747 |
+
Now that we have done some basic tokenizing, we need to
|
748 |
+
modify the tokens to join some together and split some apart
|
749 |
+
so they match what the PHP tokenizer does.
|
750 |
+
*/
|
751 |
+
|
752 |
+
$finalTokens = [];
|
753 |
+
$newStackPtr = 0;
|
754 |
+
$numTokens = count($tokens);
|
755 |
+
for ($stackPtr = 0; $stackPtr < $numTokens; $stackPtr++) {
|
756 |
+
$token = $tokens[$stackPtr];
|
757 |
+
|
758 |
+
/*
|
759 |
+
Look for comments and join the tokens together.
|
760 |
+
*/
|
761 |
+
|
762 |
+
if ($token['code'] === T_COMMENT || $token['code'] === T_DOC_COMMENT) {
|
763 |
+
$newContent = '';
|
764 |
+
$tokenContent = $token['content'];
|
765 |
+
|
766 |
+
$endContent = null;
|
767 |
+
if (isset($this->commentTokens[$tokenContent]) === true) {
|
768 |
+
$endContent = $this->commentTokens[$tokenContent];
|
769 |
+
}
|
770 |
+
|
771 |
+
while ($tokenContent !== $endContent) {
|
772 |
+
if ($endContent === null
|
773 |
+
&& strpos($tokenContent, $this->eolChar) !== false
|
774 |
+
) {
|
775 |
+
// A null end token means the comment ends at the end of
|
776 |
+
// the line so we look for newlines and split the token.
|
777 |
+
$tokens[$stackPtr]['content'] = substr(
|
778 |
+
$tokenContent,
|
779 |
+
(strpos($tokenContent, $this->eolChar) + strlen($this->eolChar))
|
780 |
+
);
|
781 |
+
|
782 |
+
$tokenContent = substr(
|
783 |
+
$tokenContent,
|
784 |
+
0,
|
785 |
+
(strpos($tokenContent, $this->eolChar) + strlen($this->eolChar))
|
786 |
+
);
|
787 |
+
|
788 |
+
// If the substr failed, skip the token as the content
|
789 |
+
// will now be blank.
|
790 |
+
if ($tokens[$stackPtr]['content'] !== false
|
791 |
+
&& $tokens[$stackPtr]['content'] !== ''
|
792 |
+
) {
|
793 |
+
$stackPtr--;
|
794 |
+
}
|
795 |
+
|
796 |
+
break;
|
797 |
+
}//end if
|
798 |
+
|
799 |
+
$stackPtr++;
|
800 |
+
$newContent .= $tokenContent;
|
801 |
+
if (isset($tokens[$stackPtr]) === false) {
|
802 |
+
break;
|
803 |
+
}
|
804 |
+
|
805 |
+
$tokenContent = $tokens[$stackPtr]['content'];
|
806 |
+
}//end while
|
807 |
+
|
808 |
+
if ($token['code'] === T_DOC_COMMENT) {
|
809 |
+
$commentTokens = $commentTokenizer->tokenizeString($newContent.$tokenContent, $this->eolChar, $newStackPtr);
|
810 |
+
foreach ($commentTokens as $commentToken) {
|
811 |
+
$finalTokens[$newStackPtr] = $commentToken;
|
812 |
+
$newStackPtr++;
|
813 |
+
}
|
814 |
+
|
815 |
+
continue;
|
816 |
+
} else {
|
817 |
+
// Save the new content in the current token so
|
818 |
+
// the code below can chop it up on newlines.
|
819 |
+
$token['content'] = $newContent.$tokenContent;
|
820 |
+
}
|
821 |
+
}//end if
|
822 |
+
|
823 |
+
/*
|
824 |
+
If this token has newlines in its content, split each line up
|
825 |
+
and create a new token for each line. We do this so it's easier
|
826 |
+
to ascertain where errors occur on a line.
|
827 |
+
Note that $token[1] is the token's content.
|
828 |
+
*/
|
829 |
+
|
830 |
+
if (strpos($token['content'], $this->eolChar) !== false) {
|
831 |
+
$tokenLines = explode($this->eolChar, $token['content']);
|
832 |
+
$numLines = count($tokenLines);
|
833 |
+
|
834 |
+
for ($i = 0; $i < $numLines; $i++) {
|
835 |
+
$newToken['content'] = $tokenLines[$i];
|
836 |
+
if ($i === ($numLines - 1)) {
|
837 |
+
if ($tokenLines[$i] === '') {
|
838 |
+
break;
|
839 |
+
}
|
840 |
+
} else {
|
841 |
+
$newToken['content'] .= $this->eolChar;
|
842 |
+
}
|
843 |
+
|
844 |
+
$newToken['type'] = $token['type'];
|
845 |
+
$newToken['code'] = $token['code'];
|
846 |
+
$finalTokens[$newStackPtr] = $newToken;
|
847 |
+
$newStackPtr++;
|
848 |
+
}
|
849 |
+
} else {
|
850 |
+
$finalTokens[$newStackPtr] = $token;
|
851 |
+
$newStackPtr++;
|
852 |
+
}//end if
|
853 |
+
|
854 |
+
// Convert numbers, including decimals.
|
855 |
+
if ($token['code'] === T_STRING
|
856 |
+
|| $token['code'] === T_OBJECT_OPERATOR
|
857 |
+
) {
|
858 |
+
$newContent = '';
|
859 |
+
$oldStackPtr = $stackPtr;
|
860 |
+
while (preg_match('|^[0-9\.]+$|', $tokens[$stackPtr]['content']) !== 0) {
|
861 |
+
$newContent .= $tokens[$stackPtr]['content'];
|
862 |
+
$stackPtr++;
|
863 |
+
}
|
864 |
+
|
865 |
+
if ($newContent !== '' && $newContent !== '.') {
|
866 |
+
$finalTokens[($newStackPtr - 1)]['content'] = $newContent;
|
867 |
+
if (ctype_digit($newContent) === true) {
|
868 |
+
$finalTokens[($newStackPtr - 1)]['code'] = constant('T_LNUMBER');
|
869 |
+
$finalTokens[($newStackPtr - 1)]['type'] = 'T_LNUMBER';
|
870 |
+
} else {
|
871 |
+
$finalTokens[($newStackPtr - 1)]['code'] = constant('T_DNUMBER');
|
872 |
+
$finalTokens[($newStackPtr - 1)]['type'] = 'T_DNUMBER';
|
873 |
+
}
|
874 |
+
|
875 |
+
$stackPtr--;
|
876 |
+
continue;
|
877 |
+
} else {
|
878 |
+
$stackPtr = $oldStackPtr;
|
879 |
+
}
|
880 |
+
}//end if
|
881 |
+
|
882 |
+
// Convert the token after an object operator into a string, in most cases.
|
883 |
+
if ($token['code'] === T_OBJECT_OPERATOR) {
|
884 |
+
for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
|
885 |
+
if (isset(Util\Tokens::$emptyTokens[$tokens[$i]['code']]) === true) {
|
886 |
+
continue;
|
887 |
+
}
|
888 |
+
|
889 |
+
if ($tokens[$i]['code'] !== T_PROTOTYPE
|
890 |
+
&& $tokens[$i]['code'] !== T_LNUMBER
|
891 |
+
&& $tokens[$i]['code'] !== T_DNUMBER
|
892 |
+
) {
|
893 |
+
$tokens[$i]['code'] = T_STRING;
|
894 |
+
$tokens[$i]['type'] = 'T_STRING';
|
895 |
+
}
|
896 |
+
|
897 |
+
break;
|
898 |
+
}
|
899 |
+
}
|
900 |
+
}//end for
|
901 |
+
|
902 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
903 |
+
echo "\t*** END TOKENIZING ***".PHP_EOL;
|
904 |
+
}
|
905 |
+
|
906 |
+
return $finalTokens;
|
907 |
+
|
908 |
+
}//end tokenize()
|
909 |
+
|
910 |
+
|
911 |
+
/**
|
912 |
+
* Tokenizes a regular expression if one is found.
|
913 |
+
*
|
914 |
+
* If a regular expression is not found, NULL is returned.
|
915 |
+
*
|
916 |
+
* @param string $char The index of the possible regex start character.
|
917 |
+
* @param string $string The complete content of the string being tokenized.
|
918 |
+
* @param string $chars An array of characters being tokenized.
|
919 |
+
* @param string $tokens The current array of tokens found in the string.
|
920 |
+
*
|
921 |
+
* @return void
|
922 |
+
*/
|
923 |
+
public function getRegexToken($char, $string, $chars, $tokens)
|
924 |
+
{
|
925 |
+
$beforeTokens = [
|
926 |
+
T_EQUAL => true,
|
927 |
+
T_IS_NOT_EQUAL => true,
|
928 |
+
T_IS_IDENTICAL => true,
|
929 |
+
T_IS_NOT_IDENTICAL => true,
|
930 |
+
T_OPEN_PARENTHESIS => true,
|
931 |
+
T_OPEN_SQUARE_BRACKET => true,
|
932 |
+
T_RETURN => true,
|
933 |
+
T_BOOLEAN_OR => true,
|
934 |
+
T_BOOLEAN_AND => true,
|
935 |
+
T_BOOLEAN_NOT => true,
|
936 |
+
T_BITWISE_OR => true,
|
937 |
+
T_BITWISE_AND => true,
|
938 |
+
T_COMMA => true,
|
939 |
+
T_COLON => true,
|
940 |
+
T_TYPEOF => true,
|
941 |
+
T_INLINE_THEN => true,
|
942 |
+
T_INLINE_ELSE => true,
|
943 |
+
];
|
944 |
+
|
945 |
+
$afterTokens = [
|
946 |
+
',' => true,
|
947 |
+
')' => true,
|
948 |
+
']' => true,
|
949 |
+
';' => true,
|
950 |
+
' ' => true,
|
951 |
+
'.' => true,
|
952 |
+
':' => true,
|
953 |
+
$this->eolChar => true,
|
954 |
+
];
|
955 |
+
|
956 |
+
// Find the last non-whitespace token that was added
|
957 |
+
// to the tokens array.
|
958 |
+
$numTokens = count($tokens);
|
959 |
+
for ($prev = ($numTokens - 1); $prev >= 0; $prev--) {
|
960 |
+
if (isset(Util\Tokens::$emptyTokens[$tokens[$prev]['code']]) === false) {
|
961 |
+
break;
|
962 |
+
}
|
963 |
+
}
|
964 |
+
|
965 |
+
if (isset($beforeTokens[$tokens[$prev]['code']]) === false) {
|
966 |
+
return null;
|
967 |
+
}
|
968 |
+
|
969 |
+
// This is probably a regular expression, so look for the end of it.
|
970 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
971 |
+
echo "\t* token possibly starts a regular expression *".PHP_EOL;
|
972 |
+
}
|
973 |
+
|
974 |
+
$numChars = count($chars);
|
975 |
+
for ($next = ($char + 1); $next < $numChars; $next++) {
|
976 |
+
if ($chars[$next] === '/') {
|
977 |
+
// Just make sure this is not escaped first.
|
978 |
+
if ($chars[($next - 1)] !== '\\') {
|
979 |
+
// In the simple form: /.../ so we found the end.
|
980 |
+
break;
|
981 |
+
} else if ($chars[($next - 2)] === '\\') {
|
982 |
+
// In the form: /...\\/ so we found the end.
|
983 |
+
break;
|
984 |
+
}
|
985 |
+
} else {
|
986 |
+
$possibleEolChar = substr($string, $next, strlen($this->eolChar));
|
987 |
+
if ($possibleEolChar === $this->eolChar) {
|
988 |
+
// This is the last token on the line and regular
|
989 |
+
// expressions need to be defined on a single line,
|
990 |
+
// so this is not a regular expression.
|
991 |
+
break;
|
992 |
+
}
|
993 |
+
}
|
994 |
+
}
|
995 |
+
|
996 |
+
if ($chars[$next] !== '/') {
|
997 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
998 |
+
echo "\t* could not find end of regular expression *".PHP_EOL;
|
999 |
+
}
|
1000 |
+
|
1001 |
+
return null;
|
1002 |
+
}
|
1003 |
+
|
1004 |
+
while (preg_match('|[a-zA-Z]|', $chars[($next + 1)]) !== 0) {
|
1005 |
+
// The token directly after the end of the regex can
|
1006 |
+
// be modifiers like global and case insensitive
|
1007 |
+
// (.e.g, /pattern/gi).
|
1008 |
+
$next++;
|
1009 |
+
}
|
1010 |
+
|
1011 |
+
$regexEnd = $next;
|
1012 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1013 |
+
echo "\t* found end of regular expression at token $regexEnd *".PHP_EOL;
|
1014 |
+
}
|
1015 |
+
|
1016 |
+
for ($next += 1; $next < $numChars; $next++) {
|
1017 |
+
if ($chars[$next] !== ' ') {
|
1018 |
+
break;
|
1019 |
+
} else {
|
1020 |
+
$possibleEolChar = substr($string, $next, strlen($this->eolChar));
|
1021 |
+
if ($possibleEolChar === $this->eolChar) {
|
1022 |
+
// This is the last token on the line.
|
1023 |
+
break;
|
1024 |
+
}
|
1025 |
+
}
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
if (isset($afterTokens[$chars[$next]]) === false) {
|
1029 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1030 |
+
echo "\t* tokens after regular expression do not look correct *".PHP_EOL;
|
1031 |
+
}
|
1032 |
+
|
1033 |
+
return null;
|
1034 |
+
}
|
1035 |
+
|
1036 |
+
// This is a regular expression, so join all the tokens together.
|
1037 |
+
$content = '';
|
1038 |
+
for ($x = $char; $x <= $regexEnd; $x++) {
|
1039 |
+
$content .= $chars[$x];
|
1040 |
+
}
|
1041 |
+
|
1042 |
+
$token = [
|
1043 |
+
'start' => $char,
|
1044 |
+
'end' => $regexEnd,
|
1045 |
+
'content' => $content,
|
1046 |
+
];
|
1047 |
+
|
1048 |
+
return $token;
|
1049 |
+
|
1050 |
+
}//end getRegexToken()
|
1051 |
+
|
1052 |
+
|
1053 |
+
/**
|
1054 |
+
* Performs additional processing after main tokenizing.
|
1055 |
+
*
|
1056 |
+
* This additional processing looks for properties, closures, labels and objects.
|
1057 |
+
*
|
1058 |
+
* @return void
|
1059 |
+
*/
|
1060 |
+
public function processAdditional()
|
1061 |
+
{
|
1062 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1063 |
+
echo "\t*** START ADDITIONAL JS PROCESSING ***".PHP_EOL;
|
1064 |
+
}
|
1065 |
+
|
1066 |
+
$numTokens = count($this->tokens);
|
1067 |
+
$classStack = [];
|
1068 |
+
|
1069 |
+
for ($i = 0; $i < $numTokens; $i++) {
|
1070 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1071 |
+
$type = $this->tokens[$i]['type'];
|
1072 |
+
$content = Util\Common::prepareForOutput($this->tokens[$i]['content']);
|
1073 |
+
|
1074 |
+
echo str_repeat("\t", count($classStack));
|
1075 |
+
echo "\tProcess token $i: $type => $content".PHP_EOL;
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
// Looking for functions that are actually closures.
|
1079 |
+
if ($this->tokens[$i]['code'] === T_FUNCTION && isset($this->tokens[$i]['scope_opener']) === true) {
|
1080 |
+
for ($x = ($i + 1); $x < $numTokens; $x++) {
|
1081 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
|
1082 |
+
break;
|
1083 |
+
}
|
1084 |
+
}
|
1085 |
+
|
1086 |
+
if ($this->tokens[$x]['code'] === T_OPEN_PARENTHESIS) {
|
1087 |
+
$this->tokens[$i]['code'] = T_CLOSURE;
|
1088 |
+
$this->tokens[$i]['type'] = 'T_CLOSURE';
|
1089 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1090 |
+
$line = $this->tokens[$i]['line'];
|
1091 |
+
echo str_repeat("\t", count($classStack));
|
1092 |
+
echo "\t* token $i on line $line changed from T_FUNCTION to T_CLOSURE *".PHP_EOL;
|
1093 |
+
}
|
1094 |
+
|
1095 |
+
for ($x = ($this->tokens[$i]['scope_opener'] + 1); $x < $this->tokens[$i]['scope_closer']; $x++) {
|
1096 |
+
if (isset($this->tokens[$x]['conditions'][$i]) === false) {
|
1097 |
+
continue;
|
1098 |
+
}
|
1099 |
+
|
1100 |
+
$this->tokens[$x]['conditions'][$i] = T_CLOSURE;
|
1101 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1102 |
+
$type = $this->tokens[$x]['type'];
|
1103 |
+
echo str_repeat("\t", count($classStack));
|
1104 |
+
echo "\t\t* cleaned $x ($type) *".PHP_EOL;
|
1105 |
+
}
|
1106 |
+
}
|
1107 |
+
}//end if
|
1108 |
+
|
1109 |
+
continue;
|
1110 |
+
} else if ($this->tokens[$i]['code'] === T_OPEN_CURLY_BRACKET
|
1111 |
+
&& isset($this->tokens[$i]['scope_condition']) === false
|
1112 |
+
&& isset($this->tokens[$i]['bracket_closer']) === true
|
1113 |
+
) {
|
1114 |
+
$condition = end($this->tokens[$i]['conditions']);
|
1115 |
+
reset($this->tokens[$i]['conditions']);
|
1116 |
+
if ($condition === T_CLASS) {
|
1117 |
+
// Possibly an ES6 method. To be classified as one, the previous
|
1118 |
+
// non-empty tokens need to be a set of parenthesis, and then a string
|
1119 |
+
// (the method name).
|
1120 |
+
for ($parenCloser = ($i - 1); $parenCloser > 0; $parenCloser--) {
|
1121 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$parenCloser]['code']]) === false) {
|
1122 |
+
break;
|
1123 |
+
}
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
if ($this->tokens[$parenCloser]['code'] === T_CLOSE_PARENTHESIS) {
|
1127 |
+
$parenOpener = $this->tokens[$parenCloser]['parenthesis_opener'];
|
1128 |
+
for ($name = ($parenOpener - 1); $name > 0; $name--) {
|
1129 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$name]['code']]) === false) {
|
1130 |
+
break;
|
1131 |
+
}
|
1132 |
+
}
|
1133 |
+
|
1134 |
+
if ($this->tokens[$name]['code'] === T_STRING) {
|
1135 |
+
// We found a method name.
|
1136 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1137 |
+
$line = $this->tokens[$name]['line'];
|
1138 |
+
echo str_repeat("\t", count($classStack));
|
1139 |
+
echo "\t* token $name on line $line changed from T_STRING to T_FUNCTION *".PHP_EOL;
|
1140 |
+
}
|
1141 |
+
|
1142 |
+
$closer = $this->tokens[$i]['bracket_closer'];
|
1143 |
+
|
1144 |
+
$this->tokens[$name]['code'] = T_FUNCTION;
|
1145 |
+
$this->tokens[$name]['type'] = 'T_FUNCTION';
|
1146 |
+
|
1147 |
+
foreach ([$name, $i, $closer] as $token) {
|
1148 |
+
$this->tokens[$token]['scope_condition'] = $name;
|
1149 |
+
$this->tokens[$token]['scope_opener'] = $i;
|
1150 |
+
$this->tokens[$token]['scope_closer'] = $closer;
|
1151 |
+
$this->tokens[$token]['parenthesis_opener'] = $parenOpener;
|
1152 |
+
$this->tokens[$token]['parenthesis_closer'] = $parenCloser;
|
1153 |
+
$this->tokens[$token]['parenthesis_owner'] = $name;
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
$this->tokens[$parenOpener]['parenthesis_owner'] = $name;
|
1157 |
+
$this->tokens[$parenCloser]['parenthesis_owner'] = $name;
|
1158 |
+
|
1159 |
+
for ($x = ($i + 1); $x < $closer; $x++) {
|
1160 |
+
$this->tokens[$x]['conditions'][$name] = T_FUNCTION;
|
1161 |
+
ksort($this->tokens[$x]['conditions'], SORT_NUMERIC);
|
1162 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1163 |
+
$type = $this->tokens[$x]['type'];
|
1164 |
+
echo str_repeat("\t", count($classStack));
|
1165 |
+
echo "\t\t* added T_FUNCTION condition to $x ($type) *".PHP_EOL;
|
1166 |
+
}
|
1167 |
+
}
|
1168 |
+
|
1169 |
+
continue;
|
1170 |
+
}//end if
|
1171 |
+
}//end if
|
1172 |
+
}//end if
|
1173 |
+
|
1174 |
+
$classStack[] = $i;
|
1175 |
+
|
1176 |
+
$closer = $this->tokens[$i]['bracket_closer'];
|
1177 |
+
$this->tokens[$i]['code'] = T_OBJECT;
|
1178 |
+
$this->tokens[$i]['type'] = 'T_OBJECT';
|
1179 |
+
$this->tokens[$closer]['code'] = T_CLOSE_OBJECT;
|
1180 |
+
$this->tokens[$closer]['type'] = 'T_CLOSE_OBJECT';
|
1181 |
+
|
1182 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1183 |
+
echo str_repeat("\t", count($classStack));
|
1184 |
+
echo "\t* token $i converted from T_OPEN_CURLY_BRACKET to T_OBJECT *".PHP_EOL;
|
1185 |
+
echo str_repeat("\t", count($classStack));
|
1186 |
+
echo "\t* token $closer converted from T_CLOSE_CURLY_BRACKET to T_CLOSE_OBJECT *".PHP_EOL;
|
1187 |
+
}
|
1188 |
+
|
1189 |
+
for ($x = ($i + 1); $x < $closer; $x++) {
|
1190 |
+
$this->tokens[$x]['conditions'][$i] = T_OBJECT;
|
1191 |
+
ksort($this->tokens[$x]['conditions'], SORT_NUMERIC);
|
1192 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1193 |
+
$type = $this->tokens[$x]['type'];
|
1194 |
+
echo str_repeat("\t", count($classStack));
|
1195 |
+
echo "\t\t* added T_OBJECT condition to $x ($type) *".PHP_EOL;
|
1196 |
+
}
|
1197 |
+
}
|
1198 |
+
} else if ($this->tokens[$i]['code'] === T_CLOSE_OBJECT) {
|
1199 |
+
$opener = array_pop($classStack);
|
1200 |
+
} else if ($this->tokens[$i]['code'] === T_COLON) {
|
1201 |
+
// If it is a scope opener, it belongs to a
|
1202 |
+
// DEFAULT or CASE statement.
|
1203 |
+
if (isset($this->tokens[$i]['scope_condition']) === true) {
|
1204 |
+
continue;
|
1205 |
+
}
|
1206 |
+
|
1207 |
+
// Make sure this is not part of an inline IF statement.
|
1208 |
+
for ($x = ($i - 1); $x >= 0; $x--) {
|
1209 |
+
if ($this->tokens[$x]['code'] === T_INLINE_THEN) {
|
1210 |
+
$this->tokens[$i]['code'] = T_INLINE_ELSE;
|
1211 |
+
$this->tokens[$i]['type'] = 'T_INLINE_ELSE';
|
1212 |
+
|
1213 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1214 |
+
echo str_repeat("\t", count($classStack));
|
1215 |
+
echo "\t* token $i converted from T_COLON to T_INLINE_THEN *".PHP_EOL;
|
1216 |
+
}
|
1217 |
+
|
1218 |
+
continue(2);
|
1219 |
+
} else if ($this->tokens[$x]['line'] < $this->tokens[$i]['line']) {
|
1220 |
+
break;
|
1221 |
+
}
|
1222 |
+
}
|
1223 |
+
|
1224 |
+
// The string to the left of the colon is either a property or label.
|
1225 |
+
for ($label = ($i - 1); $label >= 0; $label--) {
|
1226 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$label]['code']]) === false) {
|
1227 |
+
break;
|
1228 |
+
}
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
if ($this->tokens[$label]['code'] !== T_STRING
|
1232 |
+
&& $this->tokens[$label]['code'] !== T_CONSTANT_ENCAPSED_STRING
|
1233 |
+
) {
|
1234 |
+
continue;
|
1235 |
+
}
|
1236 |
+
|
1237 |
+
if (empty($classStack) === false) {
|
1238 |
+
$this->tokens[$label]['code'] = T_PROPERTY;
|
1239 |
+
$this->tokens[$label]['type'] = 'T_PROPERTY';
|
1240 |
+
|
1241 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1242 |
+
echo str_repeat("\t", count($classStack));
|
1243 |
+
echo "\t* token $label converted from T_STRING to T_PROPERTY *".PHP_EOL;
|
1244 |
+
}
|
1245 |
+
} else {
|
1246 |
+
$this->tokens[$label]['code'] = T_LABEL;
|
1247 |
+
$this->tokens[$label]['type'] = 'T_LABEL';
|
1248 |
+
|
1249 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1250 |
+
echo str_repeat("\t", count($classStack));
|
1251 |
+
echo "\t* token $label converted from T_STRING to T_LABEL *".PHP_EOL;
|
1252 |
+
}
|
1253 |
+
}//end if
|
1254 |
+
}//end if
|
1255 |
+
}//end for
|
1256 |
+
|
1257 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1258 |
+
echo "\t*** END ADDITIONAL JS PROCESSING ***".PHP_EOL;
|
1259 |
+
}
|
1260 |
+
|
1261 |
+
}//end processAdditional()
|
1262 |
+
|
1263 |
+
|
1264 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Tokenizers/PHP.php
ADDED
@@ -0,0 +1,2014 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Tokenizes PHP code.
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Tokenizers;
|
11 |
+
|
12 |
+
use PHP_CodeSniffer\Util;
|
13 |
+
|
14 |
+
class PHP extends Tokenizer
|
15 |
+
{
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* A list of tokens that are allowed to open a scope.
|
20 |
+
*
|
21 |
+
* This array also contains information about what kind of token the scope
|
22 |
+
* opener uses to open and close the scope, if the token strictly requires
|
23 |
+
* an opener, if the token can share a scope closer, and who it can be shared
|
24 |
+
* with. An example of a token that shares a scope closer is a CASE scope.
|
25 |
+
*
|
26 |
+
* @var array
|
27 |
+
*/
|
28 |
+
public $scopeOpeners = [
|
29 |
+
T_IF => [
|
30 |
+
'start' => [
|
31 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
32 |
+
T_COLON => T_COLON,
|
33 |
+
],
|
34 |
+
'end' => [
|
35 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
36 |
+
T_ENDIF => T_ENDIF,
|
37 |
+
T_ELSE => T_ELSE,
|
38 |
+
T_ELSEIF => T_ELSEIF,
|
39 |
+
],
|
40 |
+
'strict' => false,
|
41 |
+
'shared' => false,
|
42 |
+
'with' => [
|
43 |
+
T_ELSE => T_ELSE,
|
44 |
+
T_ELSEIF => T_ELSEIF,
|
45 |
+
],
|
46 |
+
],
|
47 |
+
T_TRY => [
|
48 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
49 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
50 |
+
'strict' => true,
|
51 |
+
'shared' => false,
|
52 |
+
'with' => [],
|
53 |
+
],
|
54 |
+
T_CATCH => [
|
55 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
56 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
57 |
+
'strict' => true,
|
58 |
+
'shared' => false,
|
59 |
+
'with' => [],
|
60 |
+
],
|
61 |
+
T_FINALLY => [
|
62 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
63 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
64 |
+
'strict' => true,
|
65 |
+
'shared' => false,
|
66 |
+
'with' => [],
|
67 |
+
],
|
68 |
+
T_ELSE => [
|
69 |
+
'start' => [
|
70 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
71 |
+
T_COLON => T_COLON,
|
72 |
+
],
|
73 |
+
'end' => [
|
74 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
75 |
+
T_ENDIF => T_ENDIF,
|
76 |
+
],
|
77 |
+
'strict' => false,
|
78 |
+
'shared' => false,
|
79 |
+
'with' => [
|
80 |
+
T_IF => T_IF,
|
81 |
+
T_ELSEIF => T_ELSEIF,
|
82 |
+
],
|
83 |
+
],
|
84 |
+
T_ELSEIF => [
|
85 |
+
'start' => [
|
86 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
87 |
+
T_COLON => T_COLON,
|
88 |
+
],
|
89 |
+
'end' => [
|
90 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
91 |
+
T_ENDIF => T_ENDIF,
|
92 |
+
T_ELSE => T_ELSE,
|
93 |
+
T_ELSEIF => T_ELSEIF,
|
94 |
+
],
|
95 |
+
'strict' => false,
|
96 |
+
'shared' => false,
|
97 |
+
'with' => [
|
98 |
+
T_IF => T_IF,
|
99 |
+
T_ELSE => T_ELSE,
|
100 |
+
],
|
101 |
+
],
|
102 |
+
T_FOR => [
|
103 |
+
'start' => [
|
104 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
105 |
+
T_COLON => T_COLON,
|
106 |
+
],
|
107 |
+
'end' => [
|
108 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
109 |
+
T_ENDFOR => T_ENDFOR,
|
110 |
+
],
|
111 |
+
'strict' => false,
|
112 |
+
'shared' => false,
|
113 |
+
'with' => [],
|
114 |
+
],
|
115 |
+
T_FOREACH => [
|
116 |
+
'start' => [
|
117 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
118 |
+
T_COLON => T_COLON,
|
119 |
+
],
|
120 |
+
'end' => [
|
121 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
122 |
+
T_ENDFOREACH => T_ENDFOREACH,
|
123 |
+
],
|
124 |
+
'strict' => false,
|
125 |
+
'shared' => false,
|
126 |
+
'with' => [],
|
127 |
+
],
|
128 |
+
T_INTERFACE => [
|
129 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
130 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
131 |
+
'strict' => true,
|
132 |
+
'shared' => false,
|
133 |
+
'with' => [],
|
134 |
+
],
|
135 |
+
T_FUNCTION => [
|
136 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
137 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
138 |
+
'strict' => true,
|
139 |
+
'shared' => false,
|
140 |
+
'with' => [],
|
141 |
+
],
|
142 |
+
T_CLASS => [
|
143 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
144 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
145 |
+
'strict' => true,
|
146 |
+
'shared' => false,
|
147 |
+
'with' => [],
|
148 |
+
],
|
149 |
+
T_TRAIT => [
|
150 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
151 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
152 |
+
'strict' => true,
|
153 |
+
'shared' => false,
|
154 |
+
'with' => [],
|
155 |
+
],
|
156 |
+
T_USE => [
|
157 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
158 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
159 |
+
'strict' => false,
|
160 |
+
'shared' => false,
|
161 |
+
'with' => [],
|
162 |
+
],
|
163 |
+
T_DECLARE => [
|
164 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
165 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
166 |
+
'strict' => false,
|
167 |
+
'shared' => false,
|
168 |
+
'with' => [],
|
169 |
+
],
|
170 |
+
T_NAMESPACE => [
|
171 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
172 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
173 |
+
'strict' => false,
|
174 |
+
'shared' => false,
|
175 |
+
'with' => [],
|
176 |
+
],
|
177 |
+
T_WHILE => [
|
178 |
+
'start' => [
|
179 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
180 |
+
T_COLON => T_COLON,
|
181 |
+
],
|
182 |
+
'end' => [
|
183 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
184 |
+
T_ENDWHILE => T_ENDWHILE,
|
185 |
+
],
|
186 |
+
'strict' => false,
|
187 |
+
'shared' => false,
|
188 |
+
'with' => [],
|
189 |
+
],
|
190 |
+
T_DO => [
|
191 |
+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
|
192 |
+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
|
193 |
+
'strict' => true,
|
194 |
+
'shared' => false,
|
195 |
+
'with' => [],
|
196 |
+
],
|
197 |
+
T_SWITCH => [
|
198 |
+
'start' => [
|
199 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
200 |
+
T_COLON => T_COLON,
|
201 |
+
],
|
202 |
+
'end' => [
|
203 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
204 |
+
T_ENDSWITCH => T_ENDSWITCH,
|
205 |
+
],
|
206 |
+
'strict' => true,
|
207 |
+
'shared' => false,
|
208 |
+
'with' => [],
|
209 |
+
],
|
210 |
+
T_CASE => [
|
211 |
+
'start' => [
|
212 |
+
T_COLON => T_COLON,
|
213 |
+
T_SEMICOLON => T_SEMICOLON,
|
214 |
+
],
|
215 |
+
'end' => [
|
216 |
+
T_BREAK => T_BREAK,
|
217 |
+
T_RETURN => T_RETURN,
|
218 |
+
T_CONTINUE => T_CONTINUE,
|
219 |
+
T_THROW => T_THROW,
|
220 |
+
T_EXIT => T_EXIT,
|
221 |
+
],
|
222 |
+
'strict' => true,
|
223 |
+
'shared' => true,
|
224 |
+
'with' => [
|
225 |
+
T_DEFAULT => T_DEFAULT,
|
226 |
+
T_CASE => T_CASE,
|
227 |
+
T_SWITCH => T_SWITCH,
|
228 |
+
],
|
229 |
+
],
|
230 |
+
T_DEFAULT => [
|
231 |
+
'start' => [
|
232 |
+
T_COLON => T_COLON,
|
233 |
+
T_SEMICOLON => T_SEMICOLON,
|
234 |
+
],
|
235 |
+
'end' => [
|
236 |
+
T_BREAK => T_BREAK,
|
237 |
+
T_RETURN => T_RETURN,
|
238 |
+
T_CONTINUE => T_CONTINUE,
|
239 |
+
T_THROW => T_THROW,
|
240 |
+
T_EXIT => T_EXIT,
|
241 |
+
],
|
242 |
+
'strict' => true,
|
243 |
+
'shared' => true,
|
244 |
+
'with' => [
|
245 |
+
T_CASE => T_CASE,
|
246 |
+
T_SWITCH => T_SWITCH,
|
247 |
+
],
|
248 |
+
],
|
249 |
+
T_START_HEREDOC => [
|
250 |
+
'start' => [T_START_HEREDOC => T_START_HEREDOC],
|
251 |
+
'end' => [T_END_HEREDOC => T_END_HEREDOC],
|
252 |
+
'strict' => true,
|
253 |
+
'shared' => false,
|
254 |
+
'with' => [],
|
255 |
+
],
|
256 |
+
T_START_NOWDOC => [
|
257 |
+
'start' => [T_START_NOWDOC => T_START_NOWDOC],
|
258 |
+
'end' => [T_END_NOWDOC => T_END_NOWDOC],
|
259 |
+
'strict' => true,
|
260 |
+
'shared' => false,
|
261 |
+
'with' => [],
|
262 |
+
],
|
263 |
+
];
|
264 |
+
|
265 |
+
/**
|
266 |
+
* A list of tokens that end the scope.
|
267 |
+
*
|
268 |
+
* This array is just a unique collection of the end tokens
|
269 |
+
* from the _scopeOpeners array. The data is duplicated here to
|
270 |
+
* save time during parsing of the file.
|
271 |
+
*
|
272 |
+
* @var array
|
273 |
+
*/
|
274 |
+
public $endScopeTokens = [
|
275 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
276 |
+
T_ENDIF => T_ENDIF,
|
277 |
+
T_ENDFOR => T_ENDFOR,
|
278 |
+
T_ENDFOREACH => T_ENDFOREACH,
|
279 |
+
T_ENDWHILE => T_ENDWHILE,
|
280 |
+
T_ENDSWITCH => T_ENDSWITCH,
|
281 |
+
T_BREAK => T_BREAK,
|
282 |
+
T_END_HEREDOC => T_END_HEREDOC,
|
283 |
+
];
|
284 |
+
|
285 |
+
/**
|
286 |
+
* Known lengths of tokens.
|
287 |
+
*
|
288 |
+
* @var array<int, int>
|
289 |
+
*/
|
290 |
+
public $knownLengths = [
|
291 |
+
T_ABSTRACT => 8,
|
292 |
+
T_AND_EQUAL => 2,
|
293 |
+
T_ARRAY => 5,
|
294 |
+
T_AS => 2,
|
295 |
+
T_BOOLEAN_AND => 2,
|
296 |
+
T_BOOLEAN_OR => 2,
|
297 |
+
T_BREAK => 5,
|
298 |
+
T_CALLABLE => 8,
|
299 |
+
T_CASE => 4,
|
300 |
+
T_CATCH => 5,
|
301 |
+
T_CLASS => 5,
|
302 |
+
T_CLASS_C => 9,
|
303 |
+
T_CLONE => 5,
|
304 |
+
T_CONCAT_EQUAL => 2,
|
305 |
+
T_CONST => 5,
|
306 |
+
T_CONTINUE => 8,
|
307 |
+
T_CURLY_OPEN => 2,
|
308 |
+
T_DEC => 2,
|
309 |
+
T_DECLARE => 7,
|
310 |
+
T_DEFAULT => 7,
|
311 |
+
T_DIR => 7,
|
312 |
+
T_DIV_EQUAL => 2,
|
313 |
+
T_DO => 2,
|
314 |
+
T_DOLLAR_OPEN_CURLY_BRACES => 2,
|
315 |
+
T_DOUBLE_ARROW => 2,
|
316 |
+
T_DOUBLE_COLON => 2,
|
317 |
+
T_ECHO => 4,
|
318 |
+
T_ELSE => 4,
|
319 |
+
T_ELSEIF => 6,
|
320 |
+
T_EMPTY => 5,
|
321 |
+
T_ENDDECLARE => 10,
|
322 |
+
T_ENDFOR => 6,
|
323 |
+
T_ENDFOREACH => 10,
|
324 |
+
T_ENDIF => 5,
|
325 |
+
T_ENDSWITCH => 9,
|
326 |
+
T_ENDWHILE => 8,
|
327 |
+
T_EVAL => 4,
|
328 |
+
T_EXTENDS => 7,
|
329 |
+
T_FILE => 8,
|
330 |
+
T_FINAL => 5,
|
331 |
+
T_FINALLY => 7,
|
332 |
+
T_FOR => 3,
|
333 |
+
T_FOREACH => 7,
|
334 |
+
T_FUNCTION => 8,
|
335 |
+
T_FUNC_C => 12,
|
336 |
+
T_GLOBAL => 6,
|
337 |
+
T_GOTO => 4,
|
338 |
+
T_HALT_COMPILER => 15,
|
339 |
+
T_IF => 2,
|
340 |
+
T_IMPLEMENTS => 10,
|
341 |
+
T_INC => 2,
|
342 |
+
T_INCLUDE => 7,
|
343 |
+
T_INCLUDE_ONCE => 12,
|
344 |
+
T_INSTANCEOF => 10,
|
345 |
+
T_INSTEADOF => 9,
|
346 |
+
T_INTERFACE => 9,
|
347 |
+
T_ISSET => 5,
|
348 |
+
T_IS_EQUAL => 2,
|
349 |
+
T_IS_GREATER_OR_EQUAL => 2,
|
350 |
+
T_IS_IDENTICAL => 3,
|
351 |
+
T_IS_NOT_EQUAL => 2,
|
352 |
+
T_IS_NOT_IDENTICAL => 3,
|
353 |
+
T_IS_SMALLER_OR_EQUAL => 2,
|
354 |
+
T_LINE => 8,
|
355 |
+
T_LIST => 4,
|
356 |
+
T_LOGICAL_AND => 3,
|
357 |
+
T_LOGICAL_OR => 2,
|
358 |
+
T_LOGICAL_XOR => 3,
|
359 |
+
T_METHOD_C => 10,
|
360 |
+
T_MINUS_EQUAL => 2,
|
361 |
+
T_POW_EQUAL => 3,
|
362 |
+
T_MOD_EQUAL => 2,
|
363 |
+
T_MUL_EQUAL => 2,
|
364 |
+
T_NAMESPACE => 9,
|
365 |
+
T_NS_C => 13,
|
366 |
+
T_NS_SEPARATOR => 1,
|
367 |
+
T_NEW => 3,
|
368 |
+
T_OBJECT_OPERATOR => 2,
|
369 |
+
T_OPEN_TAG_WITH_ECHO => 3,
|
370 |
+
T_OR_EQUAL => 2,
|
371 |
+
T_PLUS_EQUAL => 2,
|
372 |
+
T_PRINT => 5,
|
373 |
+
T_PRIVATE => 7,
|
374 |
+
T_PUBLIC => 6,
|
375 |
+
T_PROTECTED => 9,
|
376 |
+
T_REQUIRE => 7,
|
377 |
+
T_REQUIRE_ONCE => 12,
|
378 |
+
T_RETURN => 6,
|
379 |
+
T_STATIC => 6,
|
380 |
+
T_SWITCH => 6,
|
381 |
+
T_THROW => 5,
|
382 |
+
T_TRAIT => 5,
|
383 |
+
T_TRAIT_C => 9,
|
384 |
+
T_TRY => 3,
|
385 |
+
T_UNSET => 5,
|
386 |
+
T_USE => 3,
|
387 |
+
T_VAR => 3,
|
388 |
+
T_WHILE => 5,
|
389 |
+
T_XOR_EQUAL => 2,
|
390 |
+
T_YIELD => 5,
|
391 |
+
T_OPEN_CURLY_BRACKET => 1,
|
392 |
+
T_CLOSE_CURLY_BRACKET => 1,
|
393 |
+
T_OPEN_SQUARE_BRACKET => 1,
|
394 |
+
T_CLOSE_SQUARE_BRACKET => 1,
|
395 |
+
T_OPEN_PARENTHESIS => 1,
|
396 |
+
T_CLOSE_PARENTHESIS => 1,
|
397 |
+
T_COLON => 1,
|
398 |
+
T_STRING_CONCAT => 1,
|
399 |
+
T_INLINE_THEN => 1,
|
400 |
+
T_INLINE_ELSE => 1,
|
401 |
+
T_NULLABLE => 1,
|
402 |
+
T_NULL => 4,
|
403 |
+
T_FALSE => 5,
|
404 |
+
T_TRUE => 4,
|
405 |
+
T_SEMICOLON => 1,
|
406 |
+
T_EQUAL => 1,
|
407 |
+
T_MULTIPLY => 1,
|
408 |
+
T_DIVIDE => 1,
|
409 |
+
T_PLUS => 1,
|
410 |
+
T_MINUS => 1,
|
411 |
+
T_MODULUS => 1,
|
412 |
+
T_POW => 2,
|
413 |
+
T_SPACESHIP => 3,
|
414 |
+
T_COALESCE => 2,
|
415 |
+
T_COALESCE_EQUAL => 3,
|
416 |
+
T_BITWISE_AND => 1,
|
417 |
+
T_BITWISE_OR => 1,
|
418 |
+
T_BITWISE_XOR => 1,
|
419 |
+
T_SL => 2,
|
420 |
+
T_SR => 2,
|
421 |
+
T_SL_EQUAL => 3,
|
422 |
+
T_SR_EQUAL => 3,
|
423 |
+
T_GREATER_THAN => 1,
|
424 |
+
T_LESS_THAN => 1,
|
425 |
+
T_BOOLEAN_NOT => 1,
|
426 |
+
T_SELF => 4,
|
427 |
+
T_PARENT => 6,
|
428 |
+
T_COMMA => 1,
|
429 |
+
T_THIS => 4,
|
430 |
+
T_CLOSURE => 8,
|
431 |
+
T_BACKTICK => 1,
|
432 |
+
T_OPEN_SHORT_ARRAY => 1,
|
433 |
+
T_CLOSE_SHORT_ARRAY => 1,
|
434 |
+
];
|
435 |
+
|
436 |
+
|
437 |
+
/**
|
438 |
+
* A cache of different token types, resolved into arrays.
|
439 |
+
*
|
440 |
+
* @var array
|
441 |
+
* @see standardiseToken()
|
442 |
+
*/
|
443 |
+
private static $resolveTokenCache = [];
|
444 |
+
|
445 |
+
|
446 |
+
/**
|
447 |
+
* Creates an array of tokens when given some PHP code.
|
448 |
+
*
|
449 |
+
* Starts by using token_get_all() but does a lot of extra processing
|
450 |
+
* to insert information about the context of the token.
|
451 |
+
*
|
452 |
+
* @param string $string The string to tokenize.
|
453 |
+
*
|
454 |
+
* @return array
|
455 |
+
*/
|
456 |
+
protected function tokenize($string)
|
457 |
+
{
|
458 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
459 |
+
echo "\t*** START PHP TOKENIZING ***".PHP_EOL;
|
460 |
+
$isWin = false;
|
461 |
+
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
462 |
+
$isWin = true;
|
463 |
+
}
|
464 |
+
}
|
465 |
+
|
466 |
+
$tokens = @token_get_all($string);
|
467 |
+
$finalTokens = [];
|
468 |
+
|
469 |
+
$newStackPtr = 0;
|
470 |
+
$numTokens = count($tokens);
|
471 |
+
$lastNotEmptyToken = 0;
|
472 |
+
|
473 |
+
$insideInlineIf = [];
|
474 |
+
$insideUseGroup = false;
|
475 |
+
|
476 |
+
$commentTokenizer = new Comment();
|
477 |
+
|
478 |
+
for ($stackPtr = 0; $stackPtr < $numTokens; $stackPtr++) {
|
479 |
+
// Special case for tokens we have needed to blank out.
|
480 |
+
if ($tokens[$stackPtr] === null) {
|
481 |
+
continue;
|
482 |
+
}
|
483 |
+
|
484 |
+
$token = (array) $tokens[$stackPtr];
|
485 |
+
$tokenIsArray = isset($token[1]);
|
486 |
+
|
487 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
488 |
+
if ($tokenIsArray === true) {
|
489 |
+
$type = Util\Tokens::tokenName($token[0]);
|
490 |
+
$content = Util\Common::prepareForOutput($token[1]);
|
491 |
+
} else {
|
492 |
+
$newToken = self::resolveSimpleToken($token[0]);
|
493 |
+
$type = $newToken['type'];
|
494 |
+
$content = Util\Common::prepareForOutput($token[0]);
|
495 |
+
}
|
496 |
+
|
497 |
+
echo "\tProcess token ";
|
498 |
+
if ($tokenIsArray === true) {
|
499 |
+
echo "[$stackPtr]";
|
500 |
+
} else {
|
501 |
+
echo " $stackPtr ";
|
502 |
+
}
|
503 |
+
|
504 |
+
echo ": $type => $content";
|
505 |
+
}//end if
|
506 |
+
|
507 |
+
if ($newStackPtr > 0 && $finalTokens[($newStackPtr - 1)]['code'] !== T_WHITESPACE) {
|
508 |
+
$lastNotEmptyToken = ($newStackPtr - 1);
|
509 |
+
}
|
510 |
+
|
511 |
+
/*
|
512 |
+
If we are using \r\n newline characters, the \r and \n are sometimes
|
513 |
+
split over two tokens. This normally occurs after comments. We need
|
514 |
+
to merge these two characters together so that our line endings are
|
515 |
+
consistent for all lines.
|
516 |
+
*/
|
517 |
+
|
518 |
+
if ($tokenIsArray === true && substr($token[1], -1) === "\r") {
|
519 |
+
if (isset($tokens[($stackPtr + 1)]) === true
|
520 |
+
&& is_array($tokens[($stackPtr + 1)]) === true
|
521 |
+
&& $tokens[($stackPtr + 1)][1][0] === "\n"
|
522 |
+
) {
|
523 |
+
$token[1] .= "\n";
|
524 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
525 |
+
if ($isWin === true) {
|
526 |
+
echo '\n';
|
527 |
+
} else {
|
528 |
+
echo "\033[30;1m\\n\033[0m";
|
529 |
+
}
|
530 |
+
}
|
531 |
+
|
532 |
+
if ($tokens[($stackPtr + 1)][1] === "\n") {
|
533 |
+
// This token's content has been merged into the previous,
|
534 |
+
// so we can skip it.
|
535 |
+
$tokens[($stackPtr + 1)] = '';
|
536 |
+
} else {
|
537 |
+
$tokens[($stackPtr + 1)][1] = substr($tokens[($stackPtr + 1)][1], 1);
|
538 |
+
}
|
539 |
+
}
|
540 |
+
}//end if
|
541 |
+
|
542 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
543 |
+
echo PHP_EOL;
|
544 |
+
}
|
545 |
+
|
546 |
+
/*
|
547 |
+
Parse doc blocks into something that can be easily iterated over.
|
548 |
+
*/
|
549 |
+
|
550 |
+
if ($tokenIsArray === true
|
551 |
+
&& ($token[0] === T_DOC_COMMENT
|
552 |
+
|| ($token[0] === T_COMMENT && strpos($token[1], '/**') === 0))
|
553 |
+
) {
|
554 |
+
$commentTokens = $commentTokenizer->tokenizeString($token[1], $this->eolChar, $newStackPtr);
|
555 |
+
foreach ($commentTokens as $commentToken) {
|
556 |
+
$finalTokens[$newStackPtr] = $commentToken;
|
557 |
+
$newStackPtr++;
|
558 |
+
}
|
559 |
+
|
560 |
+
continue;
|
561 |
+
}
|
562 |
+
|
563 |
+
/*
|
564 |
+
If this is a double quoted string, PHP will tokenize the whole
|
565 |
+
thing which causes problems with the scope map when braces are
|
566 |
+
within the string. So we need to merge the tokens together to
|
567 |
+
provide a single string.
|
568 |
+
*/
|
569 |
+
|
570 |
+
if ($tokenIsArray === false && ($token[0] === '"' || $token[0] === 'b"')) {
|
571 |
+
// Binary casts need a special token.
|
572 |
+
if ($token[0] === 'b"') {
|
573 |
+
$finalTokens[$newStackPtr] = [
|
574 |
+
'code' => T_BINARY_CAST,
|
575 |
+
'type' => 'T_BINARY_CAST',
|
576 |
+
'content' => 'b',
|
577 |
+
];
|
578 |
+
$newStackPtr++;
|
579 |
+
}
|
580 |
+
|
581 |
+
$tokenContent = '"';
|
582 |
+
$nestedVars = [];
|
583 |
+
for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
|
584 |
+
$subToken = (array) $tokens[$i];
|
585 |
+
$subTokenIsArray = isset($subToken[1]);
|
586 |
+
|
587 |
+
if ($subTokenIsArray === true) {
|
588 |
+
$tokenContent .= $subToken[1];
|
589 |
+
if ($subToken[1] === '{'
|
590 |
+
&& $subToken[0] !== T_ENCAPSED_AND_WHITESPACE
|
591 |
+
) {
|
592 |
+
$nestedVars[] = $i;
|
593 |
+
}
|
594 |
+
} else {
|
595 |
+
$tokenContent .= $subToken[0];
|
596 |
+
if ($subToken[0] === '}') {
|
597 |
+
array_pop($nestedVars);
|
598 |
+
}
|
599 |
+
}
|
600 |
+
|
601 |
+
if ($subTokenIsArray === false
|
602 |
+
&& $subToken[0] === '"'
|
603 |
+
&& empty($nestedVars) === true
|
604 |
+
) {
|
605 |
+
// We found the other end of the double quoted string.
|
606 |
+
break;
|
607 |
+
}
|
608 |
+
}//end for
|
609 |
+
|
610 |
+
$stackPtr = $i;
|
611 |
+
|
612 |
+
// Convert each line within the double quoted string to a
|
613 |
+
// new token, so it conforms with other multiple line tokens.
|
614 |
+
$tokenLines = explode($this->eolChar, $tokenContent);
|
615 |
+
$numLines = count($tokenLines);
|
616 |
+
$newToken = [];
|
617 |
+
|
618 |
+
for ($j = 0; $j < $numLines; $j++) {
|
619 |
+
$newToken['content'] = $tokenLines[$j];
|
620 |
+
if ($j === ($numLines - 1)) {
|
621 |
+
if ($tokenLines[$j] === '') {
|
622 |
+
break;
|
623 |
+
}
|
624 |
+
} else {
|
625 |
+
$newToken['content'] .= $this->eolChar;
|
626 |
+
}
|
627 |
+
|
628 |
+
$newToken['code'] = T_DOUBLE_QUOTED_STRING;
|
629 |
+
$newToken['type'] = 'T_DOUBLE_QUOTED_STRING';
|
630 |
+
$finalTokens[$newStackPtr] = $newToken;
|
631 |
+
$newStackPtr++;
|
632 |
+
}
|
633 |
+
|
634 |
+
// Continue, as we're done with this token.
|
635 |
+
continue;
|
636 |
+
}//end if
|
637 |
+
|
638 |
+
/*
|
639 |
+
Detect binary casting and assign the casts their own token.
|
640 |
+
*/
|
641 |
+
|
642 |
+
if ($tokenIsArray === true
|
643 |
+
&& $token[0] === T_CONSTANT_ENCAPSED_STRING
|
644 |
+
&& (substr($token[1], 0, 2) === 'b"'
|
645 |
+
|| substr($token[1], 0, 2) === "b'")
|
646 |
+
) {
|
647 |
+
$finalTokens[$newStackPtr] = [
|
648 |
+
'code' => T_BINARY_CAST,
|
649 |
+
'type' => 'T_BINARY_CAST',
|
650 |
+
'content' => 'b',
|
651 |
+
];
|
652 |
+
$newStackPtr++;
|
653 |
+
$token[1] = substr($token[1], 1);
|
654 |
+
}
|
655 |
+
|
656 |
+
if ($tokenIsArray === true
|
657 |
+
&& $token[0] === T_STRING_CAST
|
658 |
+
&& preg_match('`^\(\s*binary\s*\)$`i', $token[1]) === 1
|
659 |
+
) {
|
660 |
+
$finalTokens[$newStackPtr] = [
|
661 |
+
'code' => T_BINARY_CAST,
|
662 |
+
'type' => 'T_BINARY_CAST',
|
663 |
+
'content' => $token[1],
|
664 |
+
];
|
665 |
+
$newStackPtr++;
|
666 |
+
continue;
|
667 |
+
}
|
668 |
+
|
669 |
+
/*
|
670 |
+
If this is a heredoc, PHP will tokenize the whole
|
671 |
+
thing which causes problems when heredocs don't
|
672 |
+
contain real PHP code, which is almost never.
|
673 |
+
We want to leave the start and end heredoc tokens
|
674 |
+
alone though.
|
675 |
+
*/
|
676 |
+
|
677 |
+
if ($tokenIsArray === true && $token[0] === T_START_HEREDOC) {
|
678 |
+
// Add the start heredoc token to the final array.
|
679 |
+
$finalTokens[$newStackPtr] = self::standardiseToken($token);
|
680 |
+
|
681 |
+
// Check if this is actually a nowdoc and use a different token
|
682 |
+
// to help the sniffs.
|
683 |
+
$nowdoc = false;
|
684 |
+
if (strpos($token[1], "'") !== false) {
|
685 |
+
$finalTokens[$newStackPtr]['code'] = T_START_NOWDOC;
|
686 |
+
$finalTokens[$newStackPtr]['type'] = 'T_START_NOWDOC';
|
687 |
+
$nowdoc = true;
|
688 |
+
}
|
689 |
+
|
690 |
+
$tokenContent = '';
|
691 |
+
for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
|
692 |
+
$subTokenIsArray = is_array($tokens[$i]);
|
693 |
+
if ($subTokenIsArray === true
|
694 |
+
&& $tokens[$i][0] === T_END_HEREDOC
|
695 |
+
) {
|
696 |
+
// We found the other end of the heredoc.
|
697 |
+
break;
|
698 |
+
}
|
699 |
+
|
700 |
+
if ($subTokenIsArray === true) {
|
701 |
+
$tokenContent .= $tokens[$i][1];
|
702 |
+
} else {
|
703 |
+
$tokenContent .= $tokens[$i];
|
704 |
+
}
|
705 |
+
}
|
706 |
+
|
707 |
+
if ($i === $numTokens) {
|
708 |
+
// We got to the end of the file and never
|
709 |
+
// found the closing token, so this probably wasn't
|
710 |
+
// a heredoc.
|
711 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
712 |
+
$type = $finalTokens[$newStackPtr]['type'];
|
713 |
+
echo "\t\t* failed to find the end of the here/nowdoc".PHP_EOL;
|
714 |
+
echo "\t\t* token $stackPtr changed from $type to T_STRING".PHP_EOL;
|
715 |
+
}
|
716 |
+
|
717 |
+
$finalTokens[$newStackPtr]['code'] = T_STRING;
|
718 |
+
$finalTokens[$newStackPtr]['type'] = 'T_STRING';
|
719 |
+
$newStackPtr++;
|
720 |
+
continue;
|
721 |
+
}
|
722 |
+
|
723 |
+
$stackPtr = $i;
|
724 |
+
$newStackPtr++;
|
725 |
+
|
726 |
+
// Convert each line within the heredoc to a
|
727 |
+
// new token, so it conforms with other multiple line tokens.
|
728 |
+
$tokenLines = explode($this->eolChar, $tokenContent);
|
729 |
+
$numLines = count($tokenLines);
|
730 |
+
$newToken = [];
|
731 |
+
|
732 |
+
for ($j = 0; $j < $numLines; $j++) {
|
733 |
+
$newToken['content'] = $tokenLines[$j];
|
734 |
+
if ($j === ($numLines - 1)) {
|
735 |
+
if ($tokenLines[$j] === '') {
|
736 |
+
break;
|
737 |
+
}
|
738 |
+
} else {
|
739 |
+
$newToken['content'] .= $this->eolChar;
|
740 |
+
}
|
741 |
+
|
742 |
+
if ($nowdoc === true) {
|
743 |
+
$newToken['code'] = T_NOWDOC;
|
744 |
+
$newToken['type'] = 'T_NOWDOC';
|
745 |
+
} else {
|
746 |
+
$newToken['code'] = T_HEREDOC;
|
747 |
+
$newToken['type'] = 'T_HEREDOC';
|
748 |
+
}
|
749 |
+
|
750 |
+
$finalTokens[$newStackPtr] = $newToken;
|
751 |
+
$newStackPtr++;
|
752 |
+
}//end for
|
753 |
+
|
754 |
+
// Add the end heredoc token to the final array.
|
755 |
+
$finalTokens[$newStackPtr] = self::standardiseToken($tokens[$stackPtr]);
|
756 |
+
|
757 |
+
if ($nowdoc === true) {
|
758 |
+
$finalTokens[$newStackPtr]['code'] = T_END_NOWDOC;
|
759 |
+
$finalTokens[$newStackPtr]['type'] = 'T_END_NOWDOC';
|
760 |
+
}
|
761 |
+
|
762 |
+
$newStackPtr++;
|
763 |
+
|
764 |
+
// Continue, as we're done with this token.
|
765 |
+
continue;
|
766 |
+
}//end if
|
767 |
+
|
768 |
+
/*
|
769 |
+
Before PHP 7.0, the "yield from" was tokenized as
|
770 |
+
T_YIELD, T_WHITESPACE and T_STRING. So look for
|
771 |
+
and change this token in earlier versions.
|
772 |
+
*/
|
773 |
+
|
774 |
+
if (PHP_VERSION_ID < 70000
|
775 |
+
&& PHP_VERSION_ID >= 50500
|
776 |
+
&& $tokenIsArray === true
|
777 |
+
&& $token[0] === T_YIELD
|
778 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
779 |
+
&& isset($tokens[($stackPtr + 2)]) === true
|
780 |
+
&& $tokens[($stackPtr + 1)][0] === T_WHITESPACE
|
781 |
+
&& $tokens[($stackPtr + 2)][0] === T_STRING
|
782 |
+
&& strtolower($tokens[($stackPtr + 2)][1]) === 'from'
|
783 |
+
) {
|
784 |
+
// Could be multi-line, so just the token stack.
|
785 |
+
$token[0] = T_YIELD_FROM;
|
786 |
+
$token[1] = $token[1].$tokens[($stackPtr + 1)][1].$tokens[($stackPtr + 2)][1];
|
787 |
+
|
788 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
789 |
+
for ($i = ($stackPtr + 1); $i <= ($stackPtr + 2); $i++) {
|
790 |
+
$type = Util\Tokens::tokenName($tokens[$i][0]);
|
791 |
+
$content = Util\Common::prepareForOutput($tokens[$i][1]);
|
792 |
+
echo "\t\t* token $i merged into T_YIELD_FROM; was: $type => $content".PHP_EOL;
|
793 |
+
}
|
794 |
+
}
|
795 |
+
|
796 |
+
$tokens[($stackPtr + 1)] = null;
|
797 |
+
$tokens[($stackPtr + 2)] = null;
|
798 |
+
}
|
799 |
+
|
800 |
+
/*
|
801 |
+
Before PHP 5.5, the yield keyword was tokenized as
|
802 |
+
T_STRING. So look for and change this token in
|
803 |
+
earlier versions.
|
804 |
+
Checks also if it is just "yield" or "yield from".
|
805 |
+
*/
|
806 |
+
|
807 |
+
if (PHP_VERSION_ID < 50500
|
808 |
+
&& $tokenIsArray === true
|
809 |
+
&& $token[0] === T_STRING
|
810 |
+
&& strtolower($token[1]) === 'yield'
|
811 |
+
) {
|
812 |
+
if (isset($tokens[($stackPtr + 1)]) === true
|
813 |
+
&& isset($tokens[($stackPtr + 2)]) === true
|
814 |
+
&& $tokens[($stackPtr + 1)][0] === T_WHITESPACE
|
815 |
+
&& $tokens[($stackPtr + 2)][0] === T_STRING
|
816 |
+
&& strtolower($tokens[($stackPtr + 2)][1]) === 'from'
|
817 |
+
) {
|
818 |
+
// Could be multi-line, so just just the token stack.
|
819 |
+
$token[0] = T_YIELD_FROM;
|
820 |
+
$token[1] = $token[1].$tokens[($stackPtr + 1)][1].$tokens[($stackPtr + 2)][1];
|
821 |
+
|
822 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
823 |
+
for ($i = ($stackPtr + 1); $i <= ($stackPtr + 2); $i++) {
|
824 |
+
$type = Util\Tokens::tokenName($tokens[$i][0]);
|
825 |
+
$content = Util\Common::prepareForOutput($tokens[$i][1]);
|
826 |
+
echo "\t\t* token $i merged into T_YIELD_FROM; was: $type => $content".PHP_EOL;
|
827 |
+
}
|
828 |
+
}
|
829 |
+
|
830 |
+
$tokens[($stackPtr + 1)] = null;
|
831 |
+
$tokens[($stackPtr + 2)] = null;
|
832 |
+
} else {
|
833 |
+
$newToken = [];
|
834 |
+
$newToken['code'] = T_YIELD;
|
835 |
+
$newToken['type'] = 'T_YIELD';
|
836 |
+
$newToken['content'] = $token[1];
|
837 |
+
$finalTokens[$newStackPtr] = $newToken;
|
838 |
+
|
839 |
+
$newStackPtr++;
|
840 |
+
continue;
|
841 |
+
}//end if
|
842 |
+
}//end if
|
843 |
+
|
844 |
+
/*
|
845 |
+
Before PHP 5.6, the ... operator was tokenized as three
|
846 |
+
T_STRING_CONCAT tokens in a row. So look for and combine
|
847 |
+
these tokens in earlier versions.
|
848 |
+
*/
|
849 |
+
|
850 |
+
if ($tokenIsArray === false
|
851 |
+
&& $token[0] === '.'
|
852 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
853 |
+
&& isset($tokens[($stackPtr + 2)]) === true
|
854 |
+
&& $tokens[($stackPtr + 1)] === '.'
|
855 |
+
&& $tokens[($stackPtr + 2)] === '.'
|
856 |
+
) {
|
857 |
+
$newToken = [];
|
858 |
+
$newToken['code'] = T_ELLIPSIS;
|
859 |
+
$newToken['type'] = 'T_ELLIPSIS';
|
860 |
+
$newToken['content'] = '...';
|
861 |
+
$finalTokens[$newStackPtr] = $newToken;
|
862 |
+
|
863 |
+
$newStackPtr++;
|
864 |
+
$stackPtr += 2;
|
865 |
+
continue;
|
866 |
+
}
|
867 |
+
|
868 |
+
/*
|
869 |
+
Before PHP 5.6, the ** operator was tokenized as two
|
870 |
+
T_MULTIPLY tokens in a row. So look for and combine
|
871 |
+
these tokens in earlier versions.
|
872 |
+
*/
|
873 |
+
|
874 |
+
if ($tokenIsArray === false
|
875 |
+
&& $token[0] === '*'
|
876 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
877 |
+
&& $tokens[($stackPtr + 1)] === '*'
|
878 |
+
) {
|
879 |
+
$newToken = [];
|
880 |
+
$newToken['code'] = T_POW;
|
881 |
+
$newToken['type'] = 'T_POW';
|
882 |
+
$newToken['content'] = '**';
|
883 |
+
$finalTokens[$newStackPtr] = $newToken;
|
884 |
+
|
885 |
+
$newStackPtr++;
|
886 |
+
$stackPtr++;
|
887 |
+
continue;
|
888 |
+
}
|
889 |
+
|
890 |
+
/*
|
891 |
+
Before PHP 5.6, the **= operator was tokenized as
|
892 |
+
T_MULTIPLY followed by T_MUL_EQUAL. So look for and combine
|
893 |
+
these tokens in earlier versions.
|
894 |
+
*/
|
895 |
+
|
896 |
+
if ($tokenIsArray === false
|
897 |
+
&& $token[0] === '*'
|
898 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
899 |
+
&& is_array($tokens[($stackPtr + 1)]) === true
|
900 |
+
&& $tokens[($stackPtr + 1)][1] === '*='
|
901 |
+
) {
|
902 |
+
$newToken = [];
|
903 |
+
$newToken['code'] = T_POW_EQUAL;
|
904 |
+
$newToken['type'] = 'T_POW_EQUAL';
|
905 |
+
$newToken['content'] = '**=';
|
906 |
+
$finalTokens[$newStackPtr] = $newToken;
|
907 |
+
|
908 |
+
$newStackPtr++;
|
909 |
+
$stackPtr++;
|
910 |
+
continue;
|
911 |
+
}
|
912 |
+
|
913 |
+
/*
|
914 |
+
Before PHP 7, the ??= operator was tokenized as
|
915 |
+
T_INLINE_THEN, T_INLINE_THEN, T_EQUAL.
|
916 |
+
Between PHP 7.0 and 7.2, the ??= operator was tokenized as
|
917 |
+
T_COALESCE, T_EQUAL.
|
918 |
+
So look for and combine these tokens in earlier versions.
|
919 |
+
*/
|
920 |
+
|
921 |
+
if (($tokenIsArray === false
|
922 |
+
&& $token[0] === '?'
|
923 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
924 |
+
&& $tokens[($stackPtr + 1)][0] === '?'
|
925 |
+
&& isset($tokens[($stackPtr + 2)]) === true
|
926 |
+
&& $tokens[($stackPtr + 2)][0] === '=')
|
927 |
+
|| ($tokenIsArray === true
|
928 |
+
&& $token[0] === T_COALESCE
|
929 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
930 |
+
&& $tokens[($stackPtr + 1)][0] === '=')
|
931 |
+
) {
|
932 |
+
$newToken = [];
|
933 |
+
$newToken['code'] = T_COALESCE_EQUAL;
|
934 |
+
$newToken['type'] = 'T_COALESCE_EQUAL';
|
935 |
+
$newToken['content'] = '??=';
|
936 |
+
$finalTokens[$newStackPtr] = $newToken;
|
937 |
+
|
938 |
+
$newStackPtr++;
|
939 |
+
$stackPtr++;
|
940 |
+
|
941 |
+
if ($tokenIsArray === false) {
|
942 |
+
// Pre PHP 7.
|
943 |
+
$stackPtr++;
|
944 |
+
}
|
945 |
+
|
946 |
+
continue;
|
947 |
+
}
|
948 |
+
|
949 |
+
/*
|
950 |
+
Before PHP 7, the ?? operator was tokenized as
|
951 |
+
T_INLINE_THEN followed by T_INLINE_THEN.
|
952 |
+
So look for and combine these tokens in earlier versions.
|
953 |
+
*/
|
954 |
+
|
955 |
+
if ($tokenIsArray === false
|
956 |
+
&& $token[0] === '?'
|
957 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
958 |
+
&& $tokens[($stackPtr + 1)][0] === '?'
|
959 |
+
) {
|
960 |
+
$newToken = [];
|
961 |
+
$newToken['code'] = T_COALESCE;
|
962 |
+
$newToken['type'] = 'T_COALESCE';
|
963 |
+
$newToken['content'] = '??';
|
964 |
+
$finalTokens[$newStackPtr] = $newToken;
|
965 |
+
|
966 |
+
$newStackPtr++;
|
967 |
+
$stackPtr++;
|
968 |
+
continue;
|
969 |
+
}
|
970 |
+
|
971 |
+
/*
|
972 |
+
Convert ? to T_NULLABLE OR T_INLINE_THEN
|
973 |
+
*/
|
974 |
+
|
975 |
+
if ($tokenIsArray === false && $token[0] === '?') {
|
976 |
+
$newToken = [];
|
977 |
+
$newToken['content'] = '?';
|
978 |
+
|
979 |
+
$prevNonEmpty = null;
|
980 |
+
for ($i = ($stackPtr - 1); $i >= 0; $i--) {
|
981 |
+
if (is_array($tokens[$i]) === true) {
|
982 |
+
$tokenType = $tokens[$i][0];
|
983 |
+
} else {
|
984 |
+
$tokenType = $tokens[$i];
|
985 |
+
}
|
986 |
+
|
987 |
+
if ($prevNonEmpty === null
|
988 |
+
&& isset(Util\Tokens::$emptyTokens[$tokenType]) === false
|
989 |
+
) {
|
990 |
+
// Found the previous non-empty token.
|
991 |
+
if ($tokenType === ':' || $tokenType === ',') {
|
992 |
+
$newToken['code'] = T_NULLABLE;
|
993 |
+
$newToken['type'] = 'T_NULLABLE';
|
994 |
+
break;
|
995 |
+
}
|
996 |
+
|
997 |
+
$prevNonEmpty = $tokenType;
|
998 |
+
}
|
999 |
+
|
1000 |
+
if ($tokenType === T_FUNCTION) {
|
1001 |
+
$newToken['code'] = T_NULLABLE;
|
1002 |
+
$newToken['type'] = 'T_NULLABLE';
|
1003 |
+
break;
|
1004 |
+
} else if (in_array($tokenType, [T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO, '=', '{', ';']) === true) {
|
1005 |
+
$newToken['code'] = T_INLINE_THEN;
|
1006 |
+
$newToken['type'] = 'T_INLINE_THEN';
|
1007 |
+
|
1008 |
+
$insideInlineIf[] = $stackPtr;
|
1009 |
+
break;
|
1010 |
+
}
|
1011 |
+
}//end for
|
1012 |
+
|
1013 |
+
$finalTokens[$newStackPtr] = $newToken;
|
1014 |
+
$newStackPtr++;
|
1015 |
+
continue;
|
1016 |
+
}//end if
|
1017 |
+
|
1018 |
+
/*
|
1019 |
+
Tokens after a double colon may be look like scope openers,
|
1020 |
+
such as when writing code like Foo::NAMESPACE, but they are
|
1021 |
+
only ever variables or strings.
|
1022 |
+
*/
|
1023 |
+
|
1024 |
+
if ($stackPtr > 1
|
1025 |
+
&& (is_array($tokens[($stackPtr - 1)]) === true
|
1026 |
+
&& $tokens[($stackPtr - 1)][0] === T_PAAMAYIM_NEKUDOTAYIM)
|
1027 |
+
&& $tokenIsArray === true
|
1028 |
+
&& $token[0] !== T_STRING
|
1029 |
+
&& $token[0] !== T_VARIABLE
|
1030 |
+
&& $token[0] !== T_DOLLAR
|
1031 |
+
&& isset(Util\Tokens::$emptyTokens[$token[0]]) === false
|
1032 |
+
) {
|
1033 |
+
$newToken = [];
|
1034 |
+
$newToken['code'] = T_STRING;
|
1035 |
+
$newToken['type'] = 'T_STRING';
|
1036 |
+
$newToken['content'] = $token[1];
|
1037 |
+
$finalTokens[$newStackPtr] = $newToken;
|
1038 |
+
|
1039 |
+
$newStackPtr++;
|
1040 |
+
continue;
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
/*
|
1044 |
+
The string-like token after a function keyword should always be
|
1045 |
+
tokenized as T_STRING even if it appears to be a different token,
|
1046 |
+
such as when writing code like: function default(): foo
|
1047 |
+
so go forward and change the token type before it is processed.
|
1048 |
+
*/
|
1049 |
+
|
1050 |
+
if ($tokenIsArray === true
|
1051 |
+
&& $token[0] === T_FUNCTION
|
1052 |
+
&& $finalTokens[$lastNotEmptyToken]['code'] !== T_USE
|
1053 |
+
) {
|
1054 |
+
for ($x = ($stackPtr + 1); $x < $numTokens; $x++) {
|
1055 |
+
if (is_array($tokens[$x]) === false
|
1056 |
+
|| isset(Util\Tokens::$emptyTokens[$tokens[$x][0]]) === false
|
1057 |
+
) {
|
1058 |
+
// Non-empty content.
|
1059 |
+
break;
|
1060 |
+
}
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
if ($x < $numTokens && is_array($tokens[$x]) === true) {
|
1064 |
+
$tokens[$x][0] = T_STRING;
|
1065 |
+
}
|
1066 |
+
|
1067 |
+
/*
|
1068 |
+
This is a special condition for T_ARRAY tokens used for
|
1069 |
+
function return types. We want to keep the parenthesis map clean,
|
1070 |
+
so let's tag these tokens as T_STRING.
|
1071 |
+
*/
|
1072 |
+
|
1073 |
+
// Go looking for the colon to start the return type hint.
|
1074 |
+
// Start by finding the closing parenthesis of the function.
|
1075 |
+
$parenthesisStack = [];
|
1076 |
+
$parenthesisCloser = false;
|
1077 |
+
for ($x = ($stackPtr + 1); $x < $numTokens; $x++) {
|
1078 |
+
if (is_array($tokens[$x]) === false && $tokens[$x] === '(') {
|
1079 |
+
$parenthesisStack[] = $x;
|
1080 |
+
} else if (is_array($tokens[$x]) === false && $tokens[$x] === ')') {
|
1081 |
+
array_pop($parenthesisStack);
|
1082 |
+
if (empty($parenthesisStack) === true) {
|
1083 |
+
$parenthesisCloser = $x;
|
1084 |
+
break;
|
1085 |
+
}
|
1086 |
+
}
|
1087 |
+
}
|
1088 |
+
|
1089 |
+
if ($parenthesisCloser !== false) {
|
1090 |
+
for ($x = ($parenthesisCloser + 1); $x < $numTokens; $x++) {
|
1091 |
+
if (is_array($tokens[$x]) === false
|
1092 |
+
|| isset(Util\Tokens::$emptyTokens[$tokens[$x][0]]) === false
|
1093 |
+
) {
|
1094 |
+
// Non-empty content.
|
1095 |
+
if (is_array($tokens[$x]) === true && $tokens[$x][0] === T_USE) {
|
1096 |
+
// Found a use statements, so search ahead for the closing parenthesis.
|
1097 |
+
for ($x += 1; $x < $numTokens; $x++) {
|
1098 |
+
if (is_array($tokens[$x]) === false && $tokens[$x] === ')') {
|
1099 |
+
continue(2);
|
1100 |
+
}
|
1101 |
+
}
|
1102 |
+
}
|
1103 |
+
|
1104 |
+
break;
|
1105 |
+
}
|
1106 |
+
}
|
1107 |
+
|
1108 |
+
if (isset($tokens[$x]) === true
|
1109 |
+
&& is_array($tokens[$x]) === false
|
1110 |
+
&& $tokens[$x] === ':'
|
1111 |
+
) {
|
1112 |
+
$allowed = [
|
1113 |
+
T_STRING => T_STRING,
|
1114 |
+
T_ARRAY => T_ARRAY,
|
1115 |
+
T_CALLABLE => T_CALLABLE,
|
1116 |
+
T_SELF => T_SELF,
|
1117 |
+
T_PARENT => T_PARENT,
|
1118 |
+
T_NS_SEPARATOR => T_NS_SEPARATOR,
|
1119 |
+
];
|
1120 |
+
|
1121 |
+
$allowed += Util\Tokens::$emptyTokens;
|
1122 |
+
|
1123 |
+
// Find the start of the return type.
|
1124 |
+
for ($x += 1; $x < $numTokens; $x++) {
|
1125 |
+
if (is_array($tokens[$x]) === true
|
1126 |
+
&& isset(Util\Tokens::$emptyTokens[$tokens[$x][0]]) === true
|
1127 |
+
) {
|
1128 |
+
// Whitespace or coments before the return type.
|
1129 |
+
continue;
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
if (is_array($tokens[$x]) === false && $tokens[$x] === '?') {
|
1133 |
+
// Found a nullable operator, so skip it.
|
1134 |
+
// But also covert the token to save the tokenizer
|
1135 |
+
// a bit of time later on.
|
1136 |
+
$tokens[$x] = [
|
1137 |
+
T_NULLABLE,
|
1138 |
+
'?',
|
1139 |
+
];
|
1140 |
+
|
1141 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1142 |
+
echo "\t\t* token $x changed from ? to T_NULLABLE".PHP_EOL;
|
1143 |
+
}
|
1144 |
+
|
1145 |
+
continue;
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
break;
|
1149 |
+
}//end for
|
1150 |
+
|
1151 |
+
// Any T_ARRAY tokens we find between here and the next
|
1152 |
+
// token that can't be part of the return type need to be
|
1153 |
+
// converted to T_STRING tokens.
|
1154 |
+
for ($x; $x < $numTokens; $x++) {
|
1155 |
+
if (is_array($tokens[$x]) === false || isset($allowed[$tokens[$x][0]]) === false) {
|
1156 |
+
break;
|
1157 |
+
} else if ($tokens[$x][0] === T_ARRAY) {
|
1158 |
+
$tokens[$x][0] = T_STRING;
|
1159 |
+
|
1160 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1161 |
+
echo "\t\t* token $x changed from T_ARRAY to T_STRING".PHP_EOL;
|
1162 |
+
}
|
1163 |
+
}
|
1164 |
+
}
|
1165 |
+
}//end if
|
1166 |
+
}//end if
|
1167 |
+
}//end if
|
1168 |
+
|
1169 |
+
/*
|
1170 |
+
Before PHP 7, the <=> operator was tokenized as
|
1171 |
+
T_IS_SMALLER_OR_EQUAL followed by T_GREATER_THAN.
|
1172 |
+
So look for and combine these tokens in earlier versions.
|
1173 |
+
*/
|
1174 |
+
|
1175 |
+
if ($tokenIsArray === true
|
1176 |
+
&& $token[0] === T_IS_SMALLER_OR_EQUAL
|
1177 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
1178 |
+
&& $tokens[($stackPtr + 1)][0] === '>'
|
1179 |
+
) {
|
1180 |
+
$newToken = [];
|
1181 |
+
$newToken['code'] = T_SPACESHIP;
|
1182 |
+
$newToken['type'] = 'T_SPACESHIP';
|
1183 |
+
$newToken['content'] = '<=>';
|
1184 |
+
$finalTokens[$newStackPtr] = $newToken;
|
1185 |
+
|
1186 |
+
$newStackPtr++;
|
1187 |
+
$stackPtr++;
|
1188 |
+
continue;
|
1189 |
+
}
|
1190 |
+
|
1191 |
+
/*
|
1192 |
+
PHP doesn't assign a token to goto labels, so we have to.
|
1193 |
+
These are just string tokens with a single colon after them. Double
|
1194 |
+
colons are already tokenized and so don't interfere with this check.
|
1195 |
+
But we do have to account for CASE statements, that look just like
|
1196 |
+
goto labels.
|
1197 |
+
*/
|
1198 |
+
|
1199 |
+
if ($tokenIsArray === true
|
1200 |
+
&& $token[0] === T_STRING
|
1201 |
+
&& isset($tokens[($stackPtr + 1)]) === true
|
1202 |
+
&& $tokens[($stackPtr + 1)] === ':'
|
1203 |
+
&& $tokens[($stackPtr - 1)][0] !== T_PAAMAYIM_NEKUDOTAYIM
|
1204 |
+
) {
|
1205 |
+
$stopTokens = [
|
1206 |
+
T_CASE => true,
|
1207 |
+
T_SEMICOLON => true,
|
1208 |
+
T_OPEN_CURLY_BRACKET => true,
|
1209 |
+
T_INLINE_THEN => true,
|
1210 |
+
];
|
1211 |
+
|
1212 |
+
for ($x = ($newStackPtr - 1); $x > 0; $x--) {
|
1213 |
+
if (isset($stopTokens[$finalTokens[$x]['code']]) === true) {
|
1214 |
+
break;
|
1215 |
+
}
|
1216 |
+
}
|
1217 |
+
|
1218 |
+
if ($finalTokens[$x]['code'] !== T_CASE
|
1219 |
+
&& $finalTokens[$x]['code'] !== T_INLINE_THEN
|
1220 |
+
) {
|
1221 |
+
$finalTokens[$newStackPtr] = [
|
1222 |
+
'content' => $token[1].':',
|
1223 |
+
'code' => T_GOTO_LABEL,
|
1224 |
+
'type' => 'T_GOTO_LABEL',
|
1225 |
+
];
|
1226 |
+
|
1227 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1228 |
+
echo "\t\t* token $stackPtr changed from T_STRING to T_GOTO_LABEL".PHP_EOL;
|
1229 |
+
echo "\t\t* skipping T_COLON token ".($stackPtr + 1).PHP_EOL;
|
1230 |
+
}
|
1231 |
+
|
1232 |
+
$newStackPtr++;
|
1233 |
+
$stackPtr++;
|
1234 |
+
continue;
|
1235 |
+
}
|
1236 |
+
}//end if
|
1237 |
+
|
1238 |
+
/*
|
1239 |
+
If this token has newlines in its content, split each line up
|
1240 |
+
and create a new token for each line. We do this so it's easier
|
1241 |
+
to ascertain where errors occur on a line.
|
1242 |
+
Note that $token[1] is the token's content.
|
1243 |
+
*/
|
1244 |
+
|
1245 |
+
if ($tokenIsArray === true && strpos($token[1], $this->eolChar) !== false) {
|
1246 |
+
$tokenLines = explode($this->eolChar, $token[1]);
|
1247 |
+
$numLines = count($tokenLines);
|
1248 |
+
$newToken = [
|
1249 |
+
'type' => Util\Tokens::tokenName($token[0]),
|
1250 |
+
'code' => $token[0],
|
1251 |
+
'content' => '',
|
1252 |
+
];
|
1253 |
+
|
1254 |
+
for ($i = 0; $i < $numLines; $i++) {
|
1255 |
+
$newToken['content'] = $tokenLines[$i];
|
1256 |
+
if ($i === ($numLines - 1)) {
|
1257 |
+
if ($tokenLines[$i] === '') {
|
1258 |
+
break;
|
1259 |
+
}
|
1260 |
+
} else {
|
1261 |
+
$newToken['content'] .= $this->eolChar;
|
1262 |
+
}
|
1263 |
+
|
1264 |
+
$finalTokens[$newStackPtr] = $newToken;
|
1265 |
+
$newStackPtr++;
|
1266 |
+
}
|
1267 |
+
} else {
|
1268 |
+
if ($tokenIsArray === true && $token[0] === T_STRING) {
|
1269 |
+
// Some T_STRING tokens should remain that way
|
1270 |
+
// due to their context.
|
1271 |
+
$context = [
|
1272 |
+
T_OBJECT_OPERATOR => true,
|
1273 |
+
T_FUNCTION => true,
|
1274 |
+
T_CLASS => true,
|
1275 |
+
T_EXTENDS => true,
|
1276 |
+
T_IMPLEMENTS => true,
|
1277 |
+
T_NEW => true,
|
1278 |
+
T_CONST => true,
|
1279 |
+
T_NS_SEPARATOR => true,
|
1280 |
+
T_USE => true,
|
1281 |
+
T_NAMESPACE => true,
|
1282 |
+
T_PAAMAYIM_NEKUDOTAYIM => true,
|
1283 |
+
];
|
1284 |
+
if (isset($context[$finalTokens[$lastNotEmptyToken]['code']]) === true) {
|
1285 |
+
// Special case for syntax like: return new self
|
1286 |
+
// where self should not be a string.
|
1287 |
+
if ($finalTokens[$lastNotEmptyToken]['code'] === T_NEW
|
1288 |
+
&& strtolower($token[1]) === 'self'
|
1289 |
+
) {
|
1290 |
+
$finalTokens[$newStackPtr] = [
|
1291 |
+
'content' => $token[1],
|
1292 |
+
'code' => T_SELF,
|
1293 |
+
'type' => 'T_SELF',
|
1294 |
+
];
|
1295 |
+
} else {
|
1296 |
+
$finalTokens[$newStackPtr] = [
|
1297 |
+
'content' => $token[1],
|
1298 |
+
'code' => T_STRING,
|
1299 |
+
'type' => 'T_STRING',
|
1300 |
+
];
|
1301 |
+
}
|
1302 |
+
|
1303 |
+
$newStackPtr++;
|
1304 |
+
continue;
|
1305 |
+
}//end if
|
1306 |
+
}//end if
|
1307 |
+
|
1308 |
+
$newToken = null;
|
1309 |
+
if ($tokenIsArray === false) {
|
1310 |
+
if (isset(self::$resolveTokenCache[$token[0]]) === true) {
|
1311 |
+
$newToken = self::$resolveTokenCache[$token[0]];
|
1312 |
+
}
|
1313 |
+
} else {
|
1314 |
+
$cacheKey = null;
|
1315 |
+
if ($token[0] === T_STRING) {
|
1316 |
+
$cacheKey = strtolower($token[1]);
|
1317 |
+
} else if ($token[0] !== T_CURLY_OPEN) {
|
1318 |
+
$cacheKey = $token[0];
|
1319 |
+
}
|
1320 |
+
|
1321 |
+
if ($cacheKey !== null && isset(self::$resolveTokenCache[$cacheKey]) === true) {
|
1322 |
+
$newToken = self::$resolveTokenCache[$cacheKey];
|
1323 |
+
$newToken['content'] = $token[1];
|
1324 |
+
}
|
1325 |
+
}
|
1326 |
+
|
1327 |
+
if ($newToken === null) {
|
1328 |
+
$newToken = self::standardiseToken($token);
|
1329 |
+
}
|
1330 |
+
|
1331 |
+
// Convert colons that are actually the ELSE component of an
|
1332 |
+
// inline IF statement.
|
1333 |
+
if (empty($insideInlineIf) === false && $newToken['code'] === T_COLON) {
|
1334 |
+
// Make sure this isn't the return type separator of a closure.
|
1335 |
+
$isReturnType = false;
|
1336 |
+
for ($i = ($stackPtr - 1); $i > 0; $i--) {
|
1337 |
+
if (is_array($tokens[$i]) === false
|
1338 |
+
|| ($tokens[$i][0] !== T_DOC_COMMENT
|
1339 |
+
&& $tokens[$i][0] !== T_COMMENT
|
1340 |
+
&& $tokens[$i][0] !== T_WHITESPACE)
|
1341 |
+
) {
|
1342 |
+
break;
|
1343 |
+
}
|
1344 |
+
}
|
1345 |
+
|
1346 |
+
if ($tokens[$i] === ')') {
|
1347 |
+
$parenCount = 1;
|
1348 |
+
for ($i--; $i > 0; $i--) {
|
1349 |
+
if ($tokens[$i] === '(') {
|
1350 |
+
$parenCount--;
|
1351 |
+
if ($parenCount === 0) {
|
1352 |
+
break;
|
1353 |
+
}
|
1354 |
+
} else if ($tokens[$i] === ')') {
|
1355 |
+
$parenCount++;
|
1356 |
+
}
|
1357 |
+
}
|
1358 |
+
|
1359 |
+
// We've found the open parenthesis, so if the previous
|
1360 |
+
// non-empty token is FUNCTION or USE, this is a closure.
|
1361 |
+
for ($i--; $i > 0; $i--) {
|
1362 |
+
if (is_array($tokens[$i]) === false
|
1363 |
+
|| ($tokens[$i][0] !== T_DOC_COMMENT
|
1364 |
+
&& $tokens[$i][0] !== T_COMMENT
|
1365 |
+
&& $tokens[$i][0] !== T_WHITESPACE)
|
1366 |
+
) {
|
1367 |
+
break;
|
1368 |
+
}
|
1369 |
+
}
|
1370 |
+
|
1371 |
+
if ($tokens[$i][0] === T_FUNCTION || $tokens[$i][0] === T_USE) {
|
1372 |
+
$isReturnType = true;
|
1373 |
+
}
|
1374 |
+
}//end if
|
1375 |
+
|
1376 |
+
if ($isReturnType === false) {
|
1377 |
+
array_pop($insideInlineIf);
|
1378 |
+
$newToken['code'] = T_INLINE_ELSE;
|
1379 |
+
$newToken['type'] = 'T_INLINE_ELSE';
|
1380 |
+
}
|
1381 |
+
}//end if
|
1382 |
+
|
1383 |
+
// This is a special condition for T_ARRAY tokens used for
|
1384 |
+
// type hinting function arguments as being arrays. We want to keep
|
1385 |
+
// the parenthesis map clean, so let's tag these tokens as
|
1386 |
+
// T_STRING.
|
1387 |
+
if ($newToken['code'] === T_ARRAY) {
|
1388 |
+
for ($i = $stackPtr; $i < $numTokens; $i++) {
|
1389 |
+
if ($tokens[$i] === '(') {
|
1390 |
+
break;
|
1391 |
+
} else if ($tokens[$i][0] === T_VARIABLE) {
|
1392 |
+
$newToken['code'] = T_STRING;
|
1393 |
+
$newToken['type'] = 'T_STRING';
|
1394 |
+
break;
|
1395 |
+
}
|
1396 |
+
}
|
1397 |
+
}
|
1398 |
+
|
1399 |
+
// This is a special case when checking PHP 5.5+ code in PHP < 5.5
|
1400 |
+
// where "finally" should be T_FINALLY instead of T_STRING.
|
1401 |
+
if ($newToken['code'] === T_STRING
|
1402 |
+
&& strtolower($newToken['content']) === 'finally'
|
1403 |
+
) {
|
1404 |
+
$newToken['code'] = T_FINALLY;
|
1405 |
+
$newToken['type'] = 'T_FINALLY';
|
1406 |
+
}
|
1407 |
+
|
1408 |
+
// This is a special case for the PHP 5.5 classname::class syntax
|
1409 |
+
// where "class" should be T_STRING instead of T_CLASS.
|
1410 |
+
if (($newToken['code'] === T_CLASS
|
1411 |
+
|| $newToken['code'] === T_FUNCTION)
|
1412 |
+
&& $finalTokens[$lastNotEmptyToken]['code'] === T_DOUBLE_COLON
|
1413 |
+
) {
|
1414 |
+
$newToken['code'] = T_STRING;
|
1415 |
+
$newToken['type'] = 'T_STRING';
|
1416 |
+
}
|
1417 |
+
|
1418 |
+
// This is a special case for PHP 5.6 use function and use const
|
1419 |
+
// where "function" and "const" should be T_STRING instead of T_FUNCTION
|
1420 |
+
// and T_CONST.
|
1421 |
+
if (($newToken['code'] === T_FUNCTION
|
1422 |
+
|| $newToken['code'] === T_CONST)
|
1423 |
+
&& ($finalTokens[$lastNotEmptyToken]['code'] === T_USE || $insideUseGroup === true)
|
1424 |
+
) {
|
1425 |
+
$newToken['code'] = T_STRING;
|
1426 |
+
$newToken['type'] = 'T_STRING';
|
1427 |
+
}
|
1428 |
+
|
1429 |
+
// This is a special case for use groups in PHP 7+ where leaving
|
1430 |
+
// the curly braces as their normal tokens would confuse
|
1431 |
+
// the scope map and sniffs.
|
1432 |
+
if ($newToken['code'] === T_OPEN_CURLY_BRACKET
|
1433 |
+
&& $finalTokens[$lastNotEmptyToken]['code'] === T_NS_SEPARATOR
|
1434 |
+
) {
|
1435 |
+
$newToken['code'] = T_OPEN_USE_GROUP;
|
1436 |
+
$newToken['type'] = 'T_OPEN_USE_GROUP';
|
1437 |
+
$insideUseGroup = true;
|
1438 |
+
}
|
1439 |
+
|
1440 |
+
if ($insideUseGroup === true && $newToken['code'] === T_CLOSE_CURLY_BRACKET) {
|
1441 |
+
$newToken['code'] = T_CLOSE_USE_GROUP;
|
1442 |
+
$newToken['type'] = 'T_CLOSE_USE_GROUP';
|
1443 |
+
$insideUseGroup = false;
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
$finalTokens[$newStackPtr] = $newToken;
|
1447 |
+
$newStackPtr++;
|
1448 |
+
}//end if
|
1449 |
+
}//end for
|
1450 |
+
|
1451 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1452 |
+
echo "\t*** END PHP TOKENIZING ***".PHP_EOL;
|
1453 |
+
}
|
1454 |
+
|
1455 |
+
return $finalTokens;
|
1456 |
+
|
1457 |
+
}//end tokenize()
|
1458 |
+
|
1459 |
+
|
1460 |
+
/**
|
1461 |
+
* Performs additional processing after main tokenizing.
|
1462 |
+
*
|
1463 |
+
* This additional processing checks for CASE statements that are using curly
|
1464 |
+
* braces for scope openers and closers. It also turns some T_FUNCTION tokens
|
1465 |
+
* into T_CLOSURE when they are not standard function definitions. It also
|
1466 |
+
* detects short array syntax and converts those square brackets into new tokens.
|
1467 |
+
* It also corrects some usage of the static and class keywords. It also
|
1468 |
+
* assigns tokens to function return types.
|
1469 |
+
*
|
1470 |
+
* @return void
|
1471 |
+
*/
|
1472 |
+
protected function processAdditional()
|
1473 |
+
{
|
1474 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1475 |
+
echo "\t*** START ADDITIONAL PHP PROCESSING ***".PHP_EOL;
|
1476 |
+
}
|
1477 |
+
|
1478 |
+
$numTokens = count($this->tokens);
|
1479 |
+
for ($i = ($numTokens - 1); $i >= 0; $i--) {
|
1480 |
+
// Check for any unset scope conditions due to alternate IF/ENDIF syntax.
|
1481 |
+
if (isset($this->tokens[$i]['scope_opener']) === true
|
1482 |
+
&& isset($this->tokens[$i]['scope_condition']) === false
|
1483 |
+
) {
|
1484 |
+
$this->tokens[$i]['scope_condition'] = $this->tokens[$this->tokens[$i]['scope_opener']]['scope_condition'];
|
1485 |
+
}
|
1486 |
+
|
1487 |
+
if ($this->tokens[$i]['code'] === T_FUNCTION) {
|
1488 |
+
/*
|
1489 |
+
Detect functions that are actually closures and
|
1490 |
+
assign them a different token.
|
1491 |
+
*/
|
1492 |
+
|
1493 |
+
if (isset($this->tokens[$i]['scope_opener']) === true) {
|
1494 |
+
for ($x = ($i + 1); $x < $numTokens; $x++) {
|
1495 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false
|
1496 |
+
&& $this->tokens[$x]['code'] !== T_BITWISE_AND
|
1497 |
+
) {
|
1498 |
+
break;
|
1499 |
+
}
|
1500 |
+
}
|
1501 |
+
|
1502 |
+
if ($this->tokens[$x]['code'] === T_OPEN_PARENTHESIS) {
|
1503 |
+
$this->tokens[$i]['code'] = T_CLOSURE;
|
1504 |
+
$this->tokens[$i]['type'] = 'T_CLOSURE';
|
1505 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1506 |
+
$line = $this->tokens[$i]['line'];
|
1507 |
+
echo "\t* token $i on line $line changed from T_FUNCTION to T_CLOSURE".PHP_EOL;
|
1508 |
+
}
|
1509 |
+
|
1510 |
+
for ($x = ($this->tokens[$i]['scope_opener'] + 1); $x < $this->tokens[$i]['scope_closer']; $x++) {
|
1511 |
+
if (isset($this->tokens[$x]['conditions'][$i]) === false) {
|
1512 |
+
continue;
|
1513 |
+
}
|
1514 |
+
|
1515 |
+
$this->tokens[$x]['conditions'][$i] = T_CLOSURE;
|
1516 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1517 |
+
$type = $this->tokens[$x]['type'];
|
1518 |
+
echo "\t\t* cleaned $x ($type) *".PHP_EOL;
|
1519 |
+
}
|
1520 |
+
}
|
1521 |
+
}
|
1522 |
+
}//end if
|
1523 |
+
|
1524 |
+
continue;
|
1525 |
+
} else if ($this->tokens[$i]['code'] === T_CLASS && isset($this->tokens[$i]['scope_opener']) === true) {
|
1526 |
+
/*
|
1527 |
+
Detect anonymous classes and assign them a different token.
|
1528 |
+
*/
|
1529 |
+
|
1530 |
+
for ($x = ($i + 1); $x < $numTokens; $x++) {
|
1531 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
|
1532 |
+
break;
|
1533 |
+
}
|
1534 |
+
}
|
1535 |
+
|
1536 |
+
if ($this->tokens[$x]['code'] === T_OPEN_PARENTHESIS
|
1537 |
+
|| $this->tokens[$x]['code'] === T_OPEN_CURLY_BRACKET
|
1538 |
+
|| $this->tokens[$x]['code'] === T_EXTENDS
|
1539 |
+
|| $this->tokens[$x]['code'] === T_IMPLEMENTS
|
1540 |
+
) {
|
1541 |
+
$this->tokens[$i]['code'] = T_ANON_CLASS;
|
1542 |
+
$this->tokens[$i]['type'] = 'T_ANON_CLASS';
|
1543 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1544 |
+
$line = $this->tokens[$i]['line'];
|
1545 |
+
echo "\t* token $i on line $line changed from T_CLASS to T_ANON_CLASS".PHP_EOL;
|
1546 |
+
}
|
1547 |
+
|
1548 |
+
for ($x = ($this->tokens[$i]['scope_opener'] + 1); $x < $this->tokens[$i]['scope_closer']; $x++) {
|
1549 |
+
if (isset($this->tokens[$x]['conditions'][$i]) === false) {
|
1550 |
+
continue;
|
1551 |
+
}
|
1552 |
+
|
1553 |
+
$this->tokens[$x]['conditions'][$i] = T_ANON_CLASS;
|
1554 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1555 |
+
$type = $this->tokens[$x]['type'];
|
1556 |
+
echo "\t\t* cleaned $x ($type) *".PHP_EOL;
|
1557 |
+
}
|
1558 |
+
}
|
1559 |
+
}
|
1560 |
+
|
1561 |
+
continue;
|
1562 |
+
} else if ($this->tokens[$i]['code'] === T_OPEN_SQUARE_BRACKET) {
|
1563 |
+
if (isset($this->tokens[$i]['bracket_closer']) === false) {
|
1564 |
+
continue;
|
1565 |
+
}
|
1566 |
+
|
1567 |
+
// Unless there is a variable or a bracket before this token,
|
1568 |
+
// it is the start of an array being defined using the short syntax.
|
1569 |
+
$isShortArray = false;
|
1570 |
+
$allowed = [
|
1571 |
+
T_CLOSE_SQUARE_BRACKET => T_CLOSE_SQUARE_BRACKET,
|
1572 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
1573 |
+
T_CLOSE_PARENTHESIS => T_CLOSE_PARENTHESIS,
|
1574 |
+
T_VARIABLE => T_VARIABLE,
|
1575 |
+
T_OBJECT_OPERATOR => T_OBJECT_OPERATOR,
|
1576 |
+
T_STRING => T_STRING,
|
1577 |
+
T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING,
|
1578 |
+
];
|
1579 |
+
|
1580 |
+
for ($x = ($i - 1); $x >= 0; $x--) {
|
1581 |
+
// If we hit a scope opener, the statement has ended
|
1582 |
+
// without finding anything, so it's probably an array
|
1583 |
+
// using PHP 7.1 short list syntax.
|
1584 |
+
if (isset($this->tokens[$x]['scope_opener']) === true) {
|
1585 |
+
$isShortArray = true;
|
1586 |
+
break;
|
1587 |
+
}
|
1588 |
+
|
1589 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
|
1590 |
+
if (isset($allowed[$this->tokens[$x]['code']]) === false) {
|
1591 |
+
$isShortArray = true;
|
1592 |
+
}
|
1593 |
+
|
1594 |
+
break;
|
1595 |
+
}
|
1596 |
+
}
|
1597 |
+
|
1598 |
+
if ($isShortArray === true) {
|
1599 |
+
$this->tokens[$i]['code'] = T_OPEN_SHORT_ARRAY;
|
1600 |
+
$this->tokens[$i]['type'] = 'T_OPEN_SHORT_ARRAY';
|
1601 |
+
|
1602 |
+
$closer = $this->tokens[$i]['bracket_closer'];
|
1603 |
+
$this->tokens[$closer]['code'] = T_CLOSE_SHORT_ARRAY;
|
1604 |
+
$this->tokens[$closer]['type'] = 'T_CLOSE_SHORT_ARRAY';
|
1605 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1606 |
+
$line = $this->tokens[$i]['line'];
|
1607 |
+
echo "\t* token $i on line $line changed from T_OPEN_SQUARE_BRACKET to T_OPEN_SHORT_ARRAY".PHP_EOL;
|
1608 |
+
$line = $this->tokens[$closer]['line'];
|
1609 |
+
echo "\t* token $closer on line $line changed from T_CLOSE_SQUARE_BRACKET to T_CLOSE_SHORT_ARRAY".PHP_EOL;
|
1610 |
+
}
|
1611 |
+
}
|
1612 |
+
|
1613 |
+
continue;
|
1614 |
+
} else if ($this->tokens[$i]['code'] === T_STATIC) {
|
1615 |
+
for ($x = ($i - 1); $x > 0; $x--) {
|
1616 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
|
1617 |
+
break;
|
1618 |
+
}
|
1619 |
+
}
|
1620 |
+
|
1621 |
+
if ($this->tokens[$x]['code'] === T_INSTANCEOF) {
|
1622 |
+
$this->tokens[$i]['code'] = T_STRING;
|
1623 |
+
$this->tokens[$i]['type'] = 'T_STRING';
|
1624 |
+
|
1625 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1626 |
+
$line = $this->tokens[$i]['line'];
|
1627 |
+
echo "\t* token $i on line $line changed from T_STATIC to T_STRING".PHP_EOL;
|
1628 |
+
}
|
1629 |
+
}
|
1630 |
+
|
1631 |
+
continue;
|
1632 |
+
} else if ($this->tokens[$i]['code'] === T_TRUE
|
1633 |
+
|| $this->tokens[$i]['code'] === T_FALSE
|
1634 |
+
|| $this->tokens[$i]['code'] === T_NULL
|
1635 |
+
) {
|
1636 |
+
for ($x = ($i + 1); $i < $numTokens; $x++) {
|
1637 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
|
1638 |
+
// Non-whitespace content.
|
1639 |
+
break;
|
1640 |
+
}
|
1641 |
+
}
|
1642 |
+
|
1643 |
+
$context = [
|
1644 |
+
T_OBJECT_OPERATOR => true,
|
1645 |
+
T_NS_SEPARATOR => true,
|
1646 |
+
T_PAAMAYIM_NEKUDOTAYIM => true,
|
1647 |
+
];
|
1648 |
+
if (isset($context[$this->tokens[$x]['code']]) === true) {
|
1649 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1650 |
+
$line = $this->tokens[$i]['line'];
|
1651 |
+
$type = $this->tokens[$i]['type'];
|
1652 |
+
echo "\t* token $i on line $line changed from $type to T_STRING".PHP_EOL;
|
1653 |
+
}
|
1654 |
+
|
1655 |
+
$this->tokens[$i]['code'] = T_STRING;
|
1656 |
+
$this->tokens[$i]['type'] = 'T_STRING';
|
1657 |
+
}
|
1658 |
+
} else if ($this->tokens[$i]['code'] === T_CONST) {
|
1659 |
+
// Context sensitive keywords support.
|
1660 |
+
for ($x = ($i + 1); $i < $numTokens; $x++) {
|
1661 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
|
1662 |
+
// Non-whitespace content.
|
1663 |
+
break;
|
1664 |
+
}
|
1665 |
+
}
|
1666 |
+
|
1667 |
+
if ($this->tokens[$x]['code'] !== T_STRING) {
|
1668 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1669 |
+
$line = $this->tokens[$x]['line'];
|
1670 |
+
$type = $this->tokens[$x]['type'];
|
1671 |
+
echo "\t* token $x on line $line changed from $type to T_STRING".PHP_EOL;
|
1672 |
+
}
|
1673 |
+
|
1674 |
+
$this->tokens[$x]['code'] = T_STRING;
|
1675 |
+
$this->tokens[$x]['type'] = 'T_STRING';
|
1676 |
+
}
|
1677 |
+
}//end if
|
1678 |
+
|
1679 |
+
if (($this->tokens[$i]['code'] !== T_CASE
|
1680 |
+
&& $this->tokens[$i]['code'] !== T_DEFAULT)
|
1681 |
+
|| isset($this->tokens[$i]['scope_opener']) === false
|
1682 |
+
) {
|
1683 |
+
// Only interested in CASE and DEFAULT statements from here on in.
|
1684 |
+
continue;
|
1685 |
+
}
|
1686 |
+
|
1687 |
+
$scopeOpener = $this->tokens[$i]['scope_opener'];
|
1688 |
+
$scopeCloser = $this->tokens[$i]['scope_closer'];
|
1689 |
+
|
1690 |
+
// If the first char after the opener is a curly brace
|
1691 |
+
// and that brace has been ignored, it is actually
|
1692 |
+
// opening this case statement and the opener and closer are
|
1693 |
+
// probably set incorrectly.
|
1694 |
+
for ($x = ($scopeOpener + 1); $x < $numTokens; $x++) {
|
1695 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
|
1696 |
+
// Non-whitespace content.
|
1697 |
+
break;
|
1698 |
+
}
|
1699 |
+
}
|
1700 |
+
|
1701 |
+
if ($this->tokens[$x]['code'] === T_CASE || $this->tokens[$x]['code'] === T_DEFAULT) {
|
1702 |
+
// Special case for multiple CASE statements that share the same
|
1703 |
+
// closer. Because we are going backwards through the file, this next
|
1704 |
+
// CASE statement is already fixed, so just use its closer and don't
|
1705 |
+
// worry about fixing anything.
|
1706 |
+
$newCloser = $this->tokens[$x]['scope_closer'];
|
1707 |
+
$this->tokens[$i]['scope_closer'] = $newCloser;
|
1708 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1709 |
+
$oldType = $this->tokens[$scopeCloser]['type'];
|
1710 |
+
$newType = $this->tokens[$newCloser]['type'];
|
1711 |
+
$line = $this->tokens[$i]['line'];
|
1712 |
+
echo "\t* token $i (T_CASE) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)".PHP_EOL;
|
1713 |
+
}
|
1714 |
+
|
1715 |
+
continue;
|
1716 |
+
}
|
1717 |
+
|
1718 |
+
if ($this->tokens[$x]['code'] !== T_OPEN_CURLY_BRACKET
|
1719 |
+
|| isset($this->tokens[$x]['scope_condition']) === true
|
1720 |
+
) {
|
1721 |
+
// Not a CASE/DEFAULT with a curly brace opener.
|
1722 |
+
continue;
|
1723 |
+
}
|
1724 |
+
|
1725 |
+
// The closer for this CASE/DEFAULT should be the closing curly brace and
|
1726 |
+
// not whatever it already is. The opener needs to be the opening curly
|
1727 |
+
// brace so everything matches up.
|
1728 |
+
$newCloser = $this->tokens[$x]['bracket_closer'];
|
1729 |
+
foreach ([$i, $x, $newCloser] as $index) {
|
1730 |
+
$this->tokens[$index]['scope_condition'] = $i;
|
1731 |
+
$this->tokens[$index]['scope_opener'] = $x;
|
1732 |
+
$this->tokens[$index]['scope_closer'] = $newCloser;
|
1733 |
+
}
|
1734 |
+
|
1735 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1736 |
+
$line = $this->tokens[$i]['line'];
|
1737 |
+
$tokenType = $this->tokens[$i]['type'];
|
1738 |
+
|
1739 |
+
$oldType = $this->tokens[$scopeOpener]['type'];
|
1740 |
+
$newType = $this->tokens[$x]['type'];
|
1741 |
+
echo "\t* token $i ($tokenType) on line $line opener changed from $scopeOpener ($oldType) to $x ($newType)".PHP_EOL;
|
1742 |
+
|
1743 |
+
$oldType = $this->tokens[$scopeCloser]['type'];
|
1744 |
+
$newType = $this->tokens[$newCloser]['type'];
|
1745 |
+
echo "\t* token $i ($tokenType) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)".PHP_EOL;
|
1746 |
+
}
|
1747 |
+
|
1748 |
+
if ($this->tokens[$scopeOpener]['scope_condition'] === $i) {
|
1749 |
+
unset($this->tokens[$scopeOpener]['scope_condition']);
|
1750 |
+
unset($this->tokens[$scopeOpener]['scope_opener']);
|
1751 |
+
unset($this->tokens[$scopeOpener]['scope_closer']);
|
1752 |
+
}
|
1753 |
+
|
1754 |
+
if ($this->tokens[$scopeCloser]['scope_condition'] === $i) {
|
1755 |
+
unset($this->tokens[$scopeCloser]['scope_condition']);
|
1756 |
+
unset($this->tokens[$scopeCloser]['scope_opener']);
|
1757 |
+
unset($this->tokens[$scopeCloser]['scope_closer']);
|
1758 |
+
} else {
|
1759 |
+
// We were using a shared closer. All tokens that were
|
1760 |
+
// sharing this closer with us, except for the scope condition
|
1761 |
+
// and it's opener, need to now point to the new closer.
|
1762 |
+
$condition = $this->tokens[$scopeCloser]['scope_condition'];
|
1763 |
+
$start = ($this->tokens[$condition]['scope_opener'] + 1);
|
1764 |
+
for ($y = $start; $y < $scopeCloser; $y++) {
|
1765 |
+
if (isset($this->tokens[$y]['scope_closer']) === true
|
1766 |
+
&& $this->tokens[$y]['scope_closer'] === $scopeCloser
|
1767 |
+
) {
|
1768 |
+
$this->tokens[$y]['scope_closer'] = $newCloser;
|
1769 |
+
|
1770 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1771 |
+
$line = $this->tokens[$y]['line'];
|
1772 |
+
$tokenType = $this->tokens[$y]['type'];
|
1773 |
+
$oldType = $this->tokens[$scopeCloser]['type'];
|
1774 |
+
$newType = $this->tokens[$newCloser]['type'];
|
1775 |
+
echo "\t\t* token $y ($tokenType) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)".PHP_EOL;
|
1776 |
+
}
|
1777 |
+
}
|
1778 |
+
}
|
1779 |
+
}//end if
|
1780 |
+
|
1781 |
+
unset($this->tokens[$x]['bracket_opener']);
|
1782 |
+
unset($this->tokens[$x]['bracket_closer']);
|
1783 |
+
unset($this->tokens[$newCloser]['bracket_opener']);
|
1784 |
+
unset($this->tokens[$newCloser]['bracket_closer']);
|
1785 |
+
$this->tokens[$scopeCloser]['conditions'][] = $i;
|
1786 |
+
|
1787 |
+
// Now fix up all the tokens that think they are
|
1788 |
+
// inside the CASE/DEFAULT statement when they are really outside.
|
1789 |
+
for ($x = $newCloser; $x < $scopeCloser; $x++) {
|
1790 |
+
foreach ($this->tokens[$x]['conditions'] as $num => $oldCond) {
|
1791 |
+
if ($oldCond === $this->tokens[$i]['code']) {
|
1792 |
+
$oldConditions = $this->tokens[$x]['conditions'];
|
1793 |
+
unset($this->tokens[$x]['conditions'][$num]);
|
1794 |
+
|
1795 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1796 |
+
$type = $this->tokens[$x]['type'];
|
1797 |
+
$oldConds = '';
|
1798 |
+
foreach ($oldConditions as $condition) {
|
1799 |
+
$oldConds .= Util\Tokens::tokenName($condition).',';
|
1800 |
+
}
|
1801 |
+
|
1802 |
+
$oldConds = rtrim($oldConds, ',');
|
1803 |
+
|
1804 |
+
$newConds = '';
|
1805 |
+
foreach ($this->tokens[$x]['conditions'] as $condition) {
|
1806 |
+
$newConds .= Util\Tokens::tokenName($condition).',';
|
1807 |
+
}
|
1808 |
+
|
1809 |
+
$newConds = rtrim($newConds, ',');
|
1810 |
+
|
1811 |
+
echo "\t\t* cleaned $x ($type) *".PHP_EOL;
|
1812 |
+
echo "\t\t\t=> conditions changed from $oldConds to $newConds".PHP_EOL;
|
1813 |
+
}
|
1814 |
+
|
1815 |
+
break;
|
1816 |
+
}//end if
|
1817 |
+
}//end foreach
|
1818 |
+
}//end for
|
1819 |
+
}//end for
|
1820 |
+
|
1821 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1822 |
+
echo "\t*** END ADDITIONAL PHP PROCESSING ***".PHP_EOL;
|
1823 |
+
}
|
1824 |
+
|
1825 |
+
}//end processAdditional()
|
1826 |
+
|
1827 |
+
|
1828 |
+
/**
|
1829 |
+
* Takes a token produced from <code>token_get_all()</code> and produces a
|
1830 |
+
* more uniform token.
|
1831 |
+
*
|
1832 |
+
* @param string|array $token The token to convert.
|
1833 |
+
*
|
1834 |
+
* @return array The new token.
|
1835 |
+
*/
|
1836 |
+
public static function standardiseToken($token)
|
1837 |
+
{
|
1838 |
+
if (isset($token[1]) === false) {
|
1839 |
+
if (isset(self::$resolveTokenCache[$token[0]]) === true) {
|
1840 |
+
return self::$resolveTokenCache[$token[0]];
|
1841 |
+
}
|
1842 |
+
} else {
|
1843 |
+
$cacheKey = null;
|
1844 |
+
if ($token[0] === T_STRING) {
|
1845 |
+
$cacheKey = strtolower($token[1]);
|
1846 |
+
} else if ($token[0] !== T_CURLY_OPEN) {
|
1847 |
+
$cacheKey = $token[0];
|
1848 |
+
}
|
1849 |
+
|
1850 |
+
if ($cacheKey !== null && isset(self::$resolveTokenCache[$cacheKey]) === true) {
|
1851 |
+
$newToken = self::$resolveTokenCache[$cacheKey];
|
1852 |
+
$newToken['content'] = $token[1];
|
1853 |
+
return $newToken;
|
1854 |
+
}
|
1855 |
+
}
|
1856 |
+
|
1857 |
+
if (isset($token[1]) === false) {
|
1858 |
+
return self::resolveSimpleToken($token[0]);
|
1859 |
+
}
|
1860 |
+
|
1861 |
+
if ($token[0] === T_STRING) {
|
1862 |
+
switch ($cacheKey) {
|
1863 |
+
case 'false':
|
1864 |
+
$newToken['type'] = 'T_FALSE';
|
1865 |
+
break;
|
1866 |
+
case 'true':
|
1867 |
+
$newToken['type'] = 'T_TRUE';
|
1868 |
+
break;
|
1869 |
+
case 'null':
|
1870 |
+
$newToken['type'] = 'T_NULL';
|
1871 |
+
break;
|
1872 |
+
case 'self':
|
1873 |
+
$newToken['type'] = 'T_SELF';
|
1874 |
+
break;
|
1875 |
+
case 'parent':
|
1876 |
+
$newToken['type'] = 'T_PARENT';
|
1877 |
+
break;
|
1878 |
+
default:
|
1879 |
+
$newToken['type'] = 'T_STRING';
|
1880 |
+
break;
|
1881 |
+
}
|
1882 |
+
|
1883 |
+
$newToken['code'] = constant($newToken['type']);
|
1884 |
+
|
1885 |
+
self::$resolveTokenCache[$cacheKey] = $newToken;
|
1886 |
+
} else if ($token[0] === T_CURLY_OPEN) {
|
1887 |
+
$newToken = [
|
1888 |
+
'code' => T_OPEN_CURLY_BRACKET,
|
1889 |
+
'type' => 'T_OPEN_CURLY_BRACKET',
|
1890 |
+
];
|
1891 |
+
} else {
|
1892 |
+
$newToken = [
|
1893 |
+
'code' => $token[0],
|
1894 |
+
'type' => Util\Tokens::tokenName($token[0]),
|
1895 |
+
];
|
1896 |
+
|
1897 |
+
self::$resolveTokenCache[$token[0]] = $newToken;
|
1898 |
+
}//end if
|
1899 |
+
|
1900 |
+
$newToken['content'] = $token[1];
|
1901 |
+
return $newToken;
|
1902 |
+
|
1903 |
+
}//end standardiseToken()
|
1904 |
+
|
1905 |
+
|
1906 |
+
/**
|
1907 |
+
* Converts simple tokens into a format that conforms to complex tokens
|
1908 |
+
* produced by token_get_all().
|
1909 |
+
*
|
1910 |
+
* Simple tokens are tokens that are not in array form when produced from
|
1911 |
+
* token_get_all().
|
1912 |
+
*
|
1913 |
+
* @param string $token The simple token to convert.
|
1914 |
+
*
|
1915 |
+
* @return array The new token in array format.
|
1916 |
+
*/
|
1917 |
+
public static function resolveSimpleToken($token)
|
1918 |
+
{
|
1919 |
+
$newToken = [];
|
1920 |
+
|
1921 |
+
switch ($token) {
|
1922 |
+
case '{':
|
1923 |
+
$newToken['type'] = 'T_OPEN_CURLY_BRACKET';
|
1924 |
+
break;
|
1925 |
+
case '}':
|
1926 |
+
$newToken['type'] = 'T_CLOSE_CURLY_BRACKET';
|
1927 |
+
break;
|
1928 |
+
case '[':
|
1929 |
+
$newToken['type'] = 'T_OPEN_SQUARE_BRACKET';
|
1930 |
+
break;
|
1931 |
+
case ']':
|
1932 |
+
$newToken['type'] = 'T_CLOSE_SQUARE_BRACKET';
|
1933 |
+
break;
|
1934 |
+
case '(':
|
1935 |
+
$newToken['type'] = 'T_OPEN_PARENTHESIS';
|
1936 |
+
break;
|
1937 |
+
case ')':
|
1938 |
+
$newToken['type'] = 'T_CLOSE_PARENTHESIS';
|
1939 |
+
break;
|
1940 |
+
case ':':
|
1941 |
+
$newToken['type'] = 'T_COLON';
|
1942 |
+
break;
|
1943 |
+
case '.':
|
1944 |
+
$newToken['type'] = 'T_STRING_CONCAT';
|
1945 |
+
break;
|
1946 |
+
case ';':
|
1947 |
+
$newToken['type'] = 'T_SEMICOLON';
|
1948 |
+
break;
|
1949 |
+
case '=':
|
1950 |
+
$newToken['type'] = 'T_EQUAL';
|
1951 |
+
break;
|
1952 |
+
case '*':
|
1953 |
+
$newToken['type'] = 'T_MULTIPLY';
|
1954 |
+
break;
|
1955 |
+
case '/':
|
1956 |
+
$newToken['type'] = 'T_DIVIDE';
|
1957 |
+
break;
|
1958 |
+
case '+':
|
1959 |
+
$newToken['type'] = 'T_PLUS';
|
1960 |
+
break;
|
1961 |
+
case '-':
|
1962 |
+
$newToken['type'] = 'T_MINUS';
|
1963 |
+
break;
|
1964 |
+
case '%':
|
1965 |
+
$newToken['type'] = 'T_MODULUS';
|
1966 |
+
break;
|
1967 |
+
case '^':
|
1968 |
+
$newToken['type'] = 'T_BITWISE_XOR';
|
1969 |
+
break;
|
1970 |
+
case '&':
|
1971 |
+
$newToken['type'] = 'T_BITWISE_AND';
|
1972 |
+
break;
|
1973 |
+
case '|':
|
1974 |
+
$newToken['type'] = 'T_BITWISE_OR';
|
1975 |
+
break;
|
1976 |
+
case '~':
|
1977 |
+
$newToken['type'] = 'T_BITWISE_NOT';
|
1978 |
+
break;
|
1979 |
+
case '<':
|
1980 |
+
$newToken['type'] = 'T_LESS_THAN';
|
1981 |
+
break;
|
1982 |
+
case '>':
|
1983 |
+
$newToken['type'] = 'T_GREATER_THAN';
|
1984 |
+
break;
|
1985 |
+
case '!':
|
1986 |
+
$newToken['type'] = 'T_BOOLEAN_NOT';
|
1987 |
+
break;
|
1988 |
+
case ',':
|
1989 |
+
$newToken['type'] = 'T_COMMA';
|
1990 |
+
break;
|
1991 |
+
case '@':
|
1992 |
+
$newToken['type'] = 'T_ASPERAND';
|
1993 |
+
break;
|
1994 |
+
case '$':
|
1995 |
+
$newToken['type'] = 'T_DOLLAR';
|
1996 |
+
break;
|
1997 |
+
case '`':
|
1998 |
+
$newToken['type'] = 'T_BACKTICK';
|
1999 |
+
break;
|
2000 |
+
default:
|
2001 |
+
$newToken['type'] = 'T_NONE';
|
2002 |
+
break;
|
2003 |
+
}//end switch
|
2004 |
+
|
2005 |
+
$newToken['code'] = constant($newToken['type']);
|
2006 |
+
$newToken['content'] = $token;
|
2007 |
+
|
2008 |
+
self::$resolveTokenCache[$token] = $newToken;
|
2009 |
+
return $newToken;
|
2010 |
+
|
2011 |
+
}//end resolveSimpleToken()
|
2012 |
+
|
2013 |
+
|
2014 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Tokenizers/Tokenizer.php
ADDED
@@ -0,0 +1,1614 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The base tokenizer class.
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Tokenizers;
|
11 |
+
|
12 |
+
use PHP_CodeSniffer\Exceptions\RuntimeException;
|
13 |
+
use PHP_CodeSniffer\Util;
|
14 |
+
|
15 |
+
abstract class Tokenizer
|
16 |
+
{
|
17 |
+
|
18 |
+
/**
|
19 |
+
* The config data for the run.
|
20 |
+
*
|
21 |
+
* @var \PHP_CodeSniffer\Config
|
22 |
+
*/
|
23 |
+
protected $config = null;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* The EOL char used in the content.
|
27 |
+
*
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
protected $eolChar = [];
|
31 |
+
|
32 |
+
/**
|
33 |
+
* A token-based representation of the content.
|
34 |
+
*
|
35 |
+
* @var array
|
36 |
+
*/
|
37 |
+
protected $tokens = [];
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Known lengths of tokens.
|
41 |
+
*
|
42 |
+
* @var array<int, int>
|
43 |
+
*/
|
44 |
+
public $knownLengths = [];
|
45 |
+
|
46 |
+
/**
|
47 |
+
* A list of lines being ignored due to error suppression comments.
|
48 |
+
*
|
49 |
+
* @var array
|
50 |
+
*/
|
51 |
+
public $ignoredLines = [];
|
52 |
+
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Initialise and run the tokenizer.
|
56 |
+
*
|
57 |
+
* @param string $content The content to tokenize,
|
58 |
+
* @param \PHP_CodeSniffer\Config | null $config The config data for the run.
|
59 |
+
* @param string $eolChar The EOL char used in the content.
|
60 |
+
*
|
61 |
+
* @return void
|
62 |
+
* @throws TokenizerException If the file appears to be minified.
|
63 |
+
*/
|
64 |
+
public function __construct($content, $config, $eolChar='\n')
|
65 |
+
{
|
66 |
+
$this->eolChar = $eolChar;
|
67 |
+
|
68 |
+
$this->config = $config;
|
69 |
+
$this->tokens = $this->tokenize($content);
|
70 |
+
|
71 |
+
if ($config === null) {
|
72 |
+
return;
|
73 |
+
}
|
74 |
+
|
75 |
+
$this->createPositionMap();
|
76 |
+
$this->createTokenMap();
|
77 |
+
$this->createParenthesisNestingMap();
|
78 |
+
$this->createScopeMap();
|
79 |
+
$this->createLevelMap();
|
80 |
+
|
81 |
+
// Allow the tokenizer to do additional processing if required.
|
82 |
+
$this->processAdditional();
|
83 |
+
|
84 |
+
}//end __construct()
|
85 |
+
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Checks the content to see if it looks minified.
|
89 |
+
*
|
90 |
+
* @param string $content The content to tokenize.
|
91 |
+
* @param string $eolChar The EOL char used in the content.
|
92 |
+
*
|
93 |
+
* @return boolean
|
94 |
+
*/
|
95 |
+
protected function isMinifiedContent($content, $eolChar='\n')
|
96 |
+
{
|
97 |
+
// Minified files often have a very large number of characters per line
|
98 |
+
// and cause issues when tokenizing.
|
99 |
+
$numChars = strlen($content);
|
100 |
+
$numLines = (substr_count($content, $eolChar) + 1);
|
101 |
+
$average = ($numChars / $numLines);
|
102 |
+
if ($average > 100) {
|
103 |
+
return true;
|
104 |
+
}
|
105 |
+
|
106 |
+
return false;
|
107 |
+
|
108 |
+
}//end isMinifiedContent()
|
109 |
+
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Gets the array of tokens.
|
113 |
+
*
|
114 |
+
* @return array
|
115 |
+
*/
|
116 |
+
public function getTokens()
|
117 |
+
{
|
118 |
+
return $this->tokens;
|
119 |
+
|
120 |
+
}//end getTokens()
|
121 |
+
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Creates an array of tokens when given some content.
|
125 |
+
*
|
126 |
+
* @param string $string The string to tokenize.
|
127 |
+
*
|
128 |
+
* @return array
|
129 |
+
*/
|
130 |
+
abstract protected function tokenize($string);
|
131 |
+
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Performs additional processing after main tokenizing.
|
135 |
+
*
|
136 |
+
* @return void
|
137 |
+
*/
|
138 |
+
abstract protected function processAdditional();
|
139 |
+
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Sets token position information.
|
143 |
+
*
|
144 |
+
* Can also convert tabs into spaces. Each tab can represent between
|
145 |
+
* 1 and $width spaces, so this cannot be a straight string replace.
|
146 |
+
*
|
147 |
+
* @return void
|
148 |
+
*/
|
149 |
+
private function createPositionMap()
|
150 |
+
{
|
151 |
+
$currColumn = 1;
|
152 |
+
$lineNumber = 1;
|
153 |
+
$eolLen = strlen($this->eolChar);
|
154 |
+
$ignoring = null;
|
155 |
+
$inTests = defined('PHP_CODESNIFFER_IN_TESTS');
|
156 |
+
|
157 |
+
$checkEncoding = false;
|
158 |
+
if (function_exists('iconv_strlen') === true) {
|
159 |
+
$checkEncoding = true;
|
160 |
+
}
|
161 |
+
|
162 |
+
$checkAnnotations = $this->config->annotations;
|
163 |
+
$encoding = $this->config->encoding;
|
164 |
+
$tabWidth = $this->config->tabWidth;
|
165 |
+
|
166 |
+
$this->tokensWithTabs = [
|
167 |
+
T_WHITESPACE => true,
|
168 |
+
T_COMMENT => true,
|
169 |
+
T_DOC_COMMENT => true,
|
170 |
+
T_DOC_COMMENT_WHITESPACE => true,
|
171 |
+
T_DOC_COMMENT_STRING => true,
|
172 |
+
T_CONSTANT_ENCAPSED_STRING => true,
|
173 |
+
T_DOUBLE_QUOTED_STRING => true,
|
174 |
+
T_HEREDOC => true,
|
175 |
+
T_NOWDOC => true,
|
176 |
+
T_INLINE_HTML => true,
|
177 |
+
];
|
178 |
+
|
179 |
+
$this->numTokens = count($this->tokens);
|
180 |
+
for ($i = 0; $i < $this->numTokens; $i++) {
|
181 |
+
$this->tokens[$i]['line'] = $lineNumber;
|
182 |
+
$this->tokens[$i]['column'] = $currColumn;
|
183 |
+
|
184 |
+
if (isset($this->knownLengths[$this->tokens[$i]['code']]) === true) {
|
185 |
+
// There are no tabs in the tokens we know the length of.
|
186 |
+
$length = $this->knownLengths[$this->tokens[$i]['code']];
|
187 |
+
$currColumn += $length;
|
188 |
+
} else if ($tabWidth === 0
|
189 |
+
|| isset($this->tokensWithTabs[$this->tokens[$i]['code']]) === false
|
190 |
+
|| strpos($this->tokens[$i]['content'], "\t") === false
|
191 |
+
) {
|
192 |
+
// There are no tabs in this content, or we aren't replacing them.
|
193 |
+
if ($checkEncoding === true) {
|
194 |
+
// Not using the default encoding, so take a bit more care.
|
195 |
+
$oldLevel = error_reporting();
|
196 |
+
error_reporting(0);
|
197 |
+
$length = iconv_strlen($this->tokens[$i]['content'], $encoding);
|
198 |
+
error_reporting($oldLevel);
|
199 |
+
|
200 |
+
if ($length === false) {
|
201 |
+
// String contained invalid characters, so revert to default.
|
202 |
+
$length = strlen($this->tokens[$i]['content']);
|
203 |
+
}
|
204 |
+
} else {
|
205 |
+
$length = strlen($this->tokens[$i]['content']);
|
206 |
+
}
|
207 |
+
|
208 |
+
$currColumn += $length;
|
209 |
+
} else {
|
210 |
+
$this->replaceTabsInToken($this->tokens[$i]);
|
211 |
+
$length = $this->tokens[$i]['length'];
|
212 |
+
$currColumn += $length;
|
213 |
+
}//end if
|
214 |
+
|
215 |
+
$this->tokens[$i]['length'] = $length;
|
216 |
+
|
217 |
+
if (isset($this->knownLengths[$this->tokens[$i]['code']]) === false
|
218 |
+
&& strpos($this->tokens[$i]['content'], $this->eolChar) !== false
|
219 |
+
) {
|
220 |
+
$lineNumber++;
|
221 |
+
$currColumn = 1;
|
222 |
+
|
223 |
+
// Newline chars are not counted in the token length.
|
224 |
+
$this->tokens[$i]['length'] -= $eolLen;
|
225 |
+
}
|
226 |
+
|
227 |
+
if ($this->tokens[$i]['code'] === T_COMMENT
|
228 |
+
|| $this->tokens[$i]['code'] === T_DOC_COMMENT_STRING
|
229 |
+
|| $this->tokens[$i]['code'] === T_DOC_COMMENT_TAG
|
230 |
+
|| ($inTests === true && $this->tokens[$i]['code'] === T_INLINE_HTML)
|
231 |
+
) {
|
232 |
+
$commentText = ltrim($this->tokens[$i]['content'], " \t/*");
|
233 |
+
$commentText = rtrim($commentText, " */\t\r\n");
|
234 |
+
$commentTextLower = strtolower($commentText);
|
235 |
+
if (strpos($commentText, '@codingStandards') !== false) {
|
236 |
+
// If this comment is the only thing on the line, it tells us
|
237 |
+
// to ignore the following line. If the line contains other content
|
238 |
+
// then we are just ignoring this one single line.
|
239 |
+
$ownLine = false;
|
240 |
+
if ($i > 0) {
|
241 |
+
for ($prev = ($i - 1); $prev >= 0; $prev--) {
|
242 |
+
if ($this->tokens[$prev]['code'] === T_WHITESPACE) {
|
243 |
+
continue;
|
244 |
+
}
|
245 |
+
|
246 |
+
break;
|
247 |
+
}
|
248 |
+
|
249 |
+
if ($this->tokens[$prev]['line'] !== $this->tokens[$i]['line']) {
|
250 |
+
$ownLine = true;
|
251 |
+
}
|
252 |
+
}
|
253 |
+
|
254 |
+
if ($ignoring === null
|
255 |
+
&& strpos($commentText, '@codingStandardsIgnoreStart') !== false
|
256 |
+
) {
|
257 |
+
$ignoring = ['.all' => true];
|
258 |
+
if ($ownLine === true) {
|
259 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring;
|
260 |
+
}
|
261 |
+
} else if ($ignoring !== null
|
262 |
+
&& strpos($commentText, '@codingStandardsIgnoreEnd') !== false
|
263 |
+
) {
|
264 |
+
if ($ownLine === true) {
|
265 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = ['.all' => true];
|
266 |
+
} else {
|
267 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring;
|
268 |
+
}
|
269 |
+
|
270 |
+
$ignoring = null;
|
271 |
+
} else if ($ignoring === null
|
272 |
+
&& strpos($commentText, '@codingStandardsIgnoreLine') !== false
|
273 |
+
) {
|
274 |
+
$ignoring = ['.all' => true];
|
275 |
+
if ($ownLine === true) {
|
276 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring;
|
277 |
+
$this->ignoredLines[($this->tokens[$i]['line'] + 1)] = $ignoring;
|
278 |
+
} else {
|
279 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring;
|
280 |
+
}
|
281 |
+
|
282 |
+
$ignoring = null;
|
283 |
+
}//end if
|
284 |
+
} else if (substr($commentTextLower, 0, 6) === 'phpcs:'
|
285 |
+
|| substr($commentTextLower, 0, 7) === '@phpcs:'
|
286 |
+
) {
|
287 |
+
// If the @phpcs: syntax is being used, strip the @ to make
|
288 |
+
// comparisons easier.
|
289 |
+
if ($commentText[0] === '@') {
|
290 |
+
$commentText = substr($commentText, 1);
|
291 |
+
$commentTextLower = strtolower($commentText);
|
292 |
+
}
|
293 |
+
|
294 |
+
// If there is a comment on the end, strip it off.
|
295 |
+
$commentStart = strpos($commentTextLower, ' --');
|
296 |
+
if ($commentStart !== false) {
|
297 |
+
$commentText = substr($commentText, 0, $commentStart);
|
298 |
+
$commentTextLower = strtolower($commentText);
|
299 |
+
}
|
300 |
+
|
301 |
+
// If this comment is the only thing on the line, it tells us
|
302 |
+
// to ignore the following line. If the line contains other content
|
303 |
+
// then we are just ignoring this one single line.
|
304 |
+
$lineHasOtherContent = false;
|
305 |
+
$lineHasOtherTokens = false;
|
306 |
+
if ($i > 0) {
|
307 |
+
for ($prev = ($i - 1); $prev > 0; $prev--) {
|
308 |
+
if ($this->tokens[$prev]['line'] !== $this->tokens[$i]['line']) {
|
309 |
+
// Changed lines.
|
310 |
+
break;
|
311 |
+
}
|
312 |
+
|
313 |
+
if ($this->tokens[$prev]['code'] === T_WHITESPACE
|
314 |
+
|| ($this->tokens[$prev]['code'] === T_INLINE_HTML
|
315 |
+
&& trim($this->tokens[$prev]['content']) === '')
|
316 |
+
) {
|
317 |
+
continue;
|
318 |
+
}
|
319 |
+
|
320 |
+
$lineHasOtherTokens = true;
|
321 |
+
|
322 |
+
if ($this->tokens[$prev]['code'] === T_OPEN_TAG) {
|
323 |
+
continue;
|
324 |
+
}
|
325 |
+
|
326 |
+
$lineHasOtherContent = true;
|
327 |
+
break;
|
328 |
+
}//end for
|
329 |
+
|
330 |
+
$changedLines = false;
|
331 |
+
for ($next = $i; $next < $this->numTokens; $next++) {
|
332 |
+
if ($changedLines === true) {
|
333 |
+
// Changed lines.
|
334 |
+
break;
|
335 |
+
}
|
336 |
+
|
337 |
+
if (isset($this->knownLengths[$this->tokens[$next]['code']]) === false
|
338 |
+
&& strpos($this->tokens[$next]['content'], $this->eolChar) !== false
|
339 |
+
) {
|
340 |
+
// Last token on the current line.
|
341 |
+
$changedLines = true;
|
342 |
+
}
|
343 |
+
|
344 |
+
if ($next === $i) {
|
345 |
+
continue;
|
346 |
+
}
|
347 |
+
|
348 |
+
if ($this->tokens[$next]['code'] === T_WHITESPACE
|
349 |
+
|| ($this->tokens[$next]['code'] === T_INLINE_HTML
|
350 |
+
&& trim($this->tokens[$next]['content']) === '')
|
351 |
+
) {
|
352 |
+
continue;
|
353 |
+
}
|
354 |
+
|
355 |
+
$lineHasOtherTokens = true;
|
356 |
+
|
357 |
+
if ($this->tokens[$next]['code'] === T_CLOSE_TAG) {
|
358 |
+
continue;
|
359 |
+
}
|
360 |
+
|
361 |
+
$lineHasOtherContent = true;
|
362 |
+
break;
|
363 |
+
}//end for
|
364 |
+
}//end if
|
365 |
+
|
366 |
+
if (substr($commentTextLower, 0, 9) === 'phpcs:set') {
|
367 |
+
// Ignore standards for complete lines that change sniff settings.
|
368 |
+
if ($lineHasOtherTokens === false) {
|
369 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = ['.all' => true];
|
370 |
+
}
|
371 |
+
|
372 |
+
$this->tokens[$i]['code'] = T_PHPCS_SET;
|
373 |
+
$this->tokens[$i]['type'] = 'T_PHPCS_SET';
|
374 |
+
} else if (substr($commentTextLower, 0, 16) === 'phpcs:ignorefile') {
|
375 |
+
// The whole file will be ignored, but at least set the correct token.
|
376 |
+
$this->tokens[$i]['code'] = T_PHPCS_IGNORE_FILE;
|
377 |
+
$this->tokens[$i]['type'] = 'T_PHPCS_IGNORE_FILE';
|
378 |
+
} else if (substr($commentTextLower, 0, 13) === 'phpcs:disable') {
|
379 |
+
if ($lineHasOtherContent === false) {
|
380 |
+
// Completely ignore the comment line.
|
381 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = ['.all' => true];
|
382 |
+
}
|
383 |
+
|
384 |
+
if ($ignoring === null) {
|
385 |
+
$ignoring = [];
|
386 |
+
}
|
387 |
+
|
388 |
+
$disabledSniffs = [];
|
389 |
+
|
390 |
+
$additionalText = substr($commentText, 14);
|
391 |
+
if ($additionalText === false) {
|
392 |
+
$ignoring = ['.all' => true];
|
393 |
+
} else {
|
394 |
+
$parts = explode(',', substr($commentText, 13));
|
395 |
+
foreach ($parts as $sniffCode) {
|
396 |
+
$sniffCode = trim($sniffCode);
|
397 |
+
$disabledSniffs[$sniffCode] = true;
|
398 |
+
$ignoring[$sniffCode] = true;
|
399 |
+
|
400 |
+
// This newly disabled sniff might be disabling an existing
|
401 |
+
// enabled exception that we are tracking.
|
402 |
+
if (isset($ignoring['.except']) === true) {
|
403 |
+
foreach (array_keys($ignoring['.except']) as $ignoredSniffCode) {
|
404 |
+
if ($ignoredSniffCode === $sniffCode
|
405 |
+
|| strpos($ignoredSniffCode, $sniffCode.'.') === 0
|
406 |
+
) {
|
407 |
+
unset($ignoring['.except'][$ignoredSniffCode]);
|
408 |
+
}
|
409 |
+
}
|
410 |
+
|
411 |
+
if (empty($ignoring['.except']) === true) {
|
412 |
+
unset($ignoring['.except']);
|
413 |
+
}
|
414 |
+
}
|
415 |
+
}//end foreach
|
416 |
+
}//end if
|
417 |
+
|
418 |
+
$this->tokens[$i]['code'] = T_PHPCS_DISABLE;
|
419 |
+
$this->tokens[$i]['type'] = 'T_PHPCS_DISABLE';
|
420 |
+
$this->tokens[$i]['sniffCodes'] = $disabledSniffs;
|
421 |
+
} else if (substr($commentTextLower, 0, 12) === 'phpcs:enable') {
|
422 |
+
if ($ignoring !== null) {
|
423 |
+
$enabledSniffs = [];
|
424 |
+
|
425 |
+
$additionalText = substr($commentText, 13);
|
426 |
+
if ($additionalText === false) {
|
427 |
+
$ignoring = null;
|
428 |
+
} else {
|
429 |
+
$parts = explode(',', substr($commentText, 13));
|
430 |
+
foreach ($parts as $sniffCode) {
|
431 |
+
$sniffCode = trim($sniffCode);
|
432 |
+
$enabledSniffs[$sniffCode] = true;
|
433 |
+
|
434 |
+
// This new enabled sniff might remove previously disabled
|
435 |
+
// sniffs if it is actually a standard or category of sniffs.
|
436 |
+
foreach (array_keys($ignoring) as $ignoredSniffCode) {
|
437 |
+
if ($ignoredSniffCode === $sniffCode
|
438 |
+
|| strpos($ignoredSniffCode, $sniffCode.'.') === 0
|
439 |
+
) {
|
440 |
+
unset($ignoring[$ignoredSniffCode]);
|
441 |
+
}
|
442 |
+
}
|
443 |
+
|
444 |
+
// This new enabled sniff might be able to clear up
|
445 |
+
// previously enabled sniffs if it is actually a standard or
|
446 |
+
// category of sniffs.
|
447 |
+
if (isset($ignoring['.except']) === true) {
|
448 |
+
foreach (array_keys($ignoring['.except']) as $ignoredSniffCode) {
|
449 |
+
if ($ignoredSniffCode === $sniffCode
|
450 |
+
|| strpos($ignoredSniffCode, $sniffCode.'.') === 0
|
451 |
+
) {
|
452 |
+
unset($ignoring['.except'][$ignoredSniffCode]);
|
453 |
+
}
|
454 |
+
}
|
455 |
+
}
|
456 |
+
}//end foreach
|
457 |
+
|
458 |
+
if (empty($ignoring) === true) {
|
459 |
+
$ignoring = null;
|
460 |
+
} else {
|
461 |
+
if (isset($ignoring['.except']) === true) {
|
462 |
+
$ignoring['.except'] += $enabledSniffs;
|
463 |
+
} else {
|
464 |
+
$ignoring['.except'] = $enabledSniffs;
|
465 |
+
}
|
466 |
+
}
|
467 |
+
}//end if
|
468 |
+
|
469 |
+
if ($lineHasOtherContent === false) {
|
470 |
+
// Completely ignore the comment line.
|
471 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = ['.all' => true];
|
472 |
+
} else {
|
473 |
+
// The comment is on the same line as the code it is ignoring,
|
474 |
+
// so respect the new ignore rules.
|
475 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring;
|
476 |
+
}
|
477 |
+
|
478 |
+
$this->tokens[$i]['sniffCodes'] = $enabledSniffs;
|
479 |
+
}//end if
|
480 |
+
|
481 |
+
$this->tokens[$i]['code'] = T_PHPCS_ENABLE;
|
482 |
+
$this->tokens[$i]['type'] = 'T_PHPCS_ENABLE';
|
483 |
+
} else if (substr($commentTextLower, 0, 12) === 'phpcs:ignore') {
|
484 |
+
$ignoreRules = [];
|
485 |
+
|
486 |
+
$additionalText = substr($commentText, 13);
|
487 |
+
if ($additionalText === false) {
|
488 |
+
$ignoreRules = ['.all' => true];
|
489 |
+
} else {
|
490 |
+
$parts = explode(',', substr($commentText, 13));
|
491 |
+
foreach ($parts as $sniffCode) {
|
492 |
+
$ignoreRules[trim($sniffCode)] = true;
|
493 |
+
}
|
494 |
+
}
|
495 |
+
|
496 |
+
$this->tokens[$i]['code'] = T_PHPCS_IGNORE;
|
497 |
+
$this->tokens[$i]['type'] = 'T_PHPCS_IGNORE';
|
498 |
+
$this->tokens[$i]['sniffCodes'] = $ignoreRules;
|
499 |
+
|
500 |
+
if ($ignoring !== null) {
|
501 |
+
$ignoreRules += $ignoring;
|
502 |
+
}
|
503 |
+
|
504 |
+
if ($lineHasOtherContent === false) {
|
505 |
+
// Completely ignore the comment line, and set the folllowing
|
506 |
+
// line to include the ignore rules we've set.
|
507 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = ['.all' => true];
|
508 |
+
$this->ignoredLines[($this->tokens[$i]['line'] + 1)] = $ignoreRules;
|
509 |
+
} else {
|
510 |
+
// The comment is on the same line as the code it is ignoring,
|
511 |
+
// so respect the ignore rules it set.
|
512 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoreRules;
|
513 |
+
}
|
514 |
+
}//end if
|
515 |
+
}//end if
|
516 |
+
}//end if
|
517 |
+
|
518 |
+
if ($ignoring !== null && isset($this->ignoredLines[$this->tokens[$i]['line']]) === false) {
|
519 |
+
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring;
|
520 |
+
}
|
521 |
+
}//end for
|
522 |
+
|
523 |
+
// If annotations are being ignored, we clear out all the ignore rules
|
524 |
+
// but leave the annotations tokenized as normal.
|
525 |
+
if ($checkAnnotations === false) {
|
526 |
+
$this->ignoredLines = [];
|
527 |
+
}
|
528 |
+
|
529 |
+
}//end createPositionMap()
|
530 |
+
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Replaces tabs in original token content with spaces.
|
534 |
+
*
|
535 |
+
* Each tab can represent between 1 and $config->tabWidth spaces,
|
536 |
+
* so this cannot be a straight string replace. The original content
|
537 |
+
* is placed into an orig_content index and the new token length is also
|
538 |
+
* set in the length index.
|
539 |
+
*
|
540 |
+
* @param array $token The token to replace tabs inside.
|
541 |
+
* @param string $prefix The character to use to represent the start of a tab.
|
542 |
+
* @param string $padding The character to use to represent the end of a tab.
|
543 |
+
* @param int $tabWidth The number of spaces each tab represents.
|
544 |
+
*
|
545 |
+
* @return void
|
546 |
+
*/
|
547 |
+
public function replaceTabsInToken(&$token, $prefix=' ', $padding=' ', $tabWidth=null)
|
548 |
+
{
|
549 |
+
$checkEncoding = false;
|
550 |
+
if (function_exists('iconv_strlen') === true) {
|
551 |
+
$checkEncoding = true;
|
552 |
+
}
|
553 |
+
|
554 |
+
$currColumn = $token['column'];
|
555 |
+
if ($tabWidth === null) {
|
556 |
+
$tabWidth = $this->config->tabWidth;
|
557 |
+
if ($tabWidth === 0) {
|
558 |
+
$tabWidth = 1;
|
559 |
+
}
|
560 |
+
}
|
561 |
+
|
562 |
+
if (rtrim($token['content'], "\t") === '') {
|
563 |
+
// String only contains tabs, so we can shortcut the process.
|
564 |
+
$numTabs = strlen($token['content']);
|
565 |
+
|
566 |
+
$firstTabSize = ($tabWidth - (($currColumn - 1) % $tabWidth));
|
567 |
+
$length = ($firstTabSize + ($tabWidth * ($numTabs - 1)));
|
568 |
+
$newContent = $prefix.str_repeat($padding, ($length - 1));
|
569 |
+
} else {
|
570 |
+
// We need to determine the length of each tab.
|
571 |
+
$tabs = explode("\t", $token['content']);
|
572 |
+
|
573 |
+
$numTabs = (count($tabs) - 1);
|
574 |
+
$tabNum = 0;
|
575 |
+
$newContent = '';
|
576 |
+
$length = 0;
|
577 |
+
|
578 |
+
foreach ($tabs as $content) {
|
579 |
+
if ($content !== '') {
|
580 |
+
$newContent .= $content;
|
581 |
+
if ($checkEncoding === true) {
|
582 |
+
// Not using the default encoding, so take a bit more care.
|
583 |
+
$oldLevel = error_reporting();
|
584 |
+
error_reporting(0);
|
585 |
+
$contentLength = iconv_strlen($content, $this->config->encoding);
|
586 |
+
error_reporting($oldLevel);
|
587 |
+
if ($contentLength === false) {
|
588 |
+
// String contained invalid characters, so revert to default.
|
589 |
+
$contentLength = strlen($content);
|
590 |
+
}
|
591 |
+
} else {
|
592 |
+
$contentLength = strlen($content);
|
593 |
+
}
|
594 |
+
|
595 |
+
$currColumn += $contentLength;
|
596 |
+
$length += $contentLength;
|
597 |
+
}
|
598 |
+
|
599 |
+
// The last piece of content does not have a tab after it.
|
600 |
+
if ($tabNum === $numTabs) {
|
601 |
+
break;
|
602 |
+
}
|
603 |
+
|
604 |
+
// Process the tab that comes after the content.
|
605 |
+
$lastCurrColumn = $currColumn;
|
606 |
+
$tabNum++;
|
607 |
+
|
608 |
+
// Move the pointer to the next tab stop.
|
609 |
+
if (($currColumn % $tabWidth) === 0) {
|
610 |
+
// This is the first tab, and we are already at a
|
611 |
+
// tab stop, so this tab counts as a single space.
|
612 |
+
$currColumn++;
|
613 |
+
} else {
|
614 |
+
$currColumn++;
|
615 |
+
while (($currColumn % $tabWidth) !== 0) {
|
616 |
+
$currColumn++;
|
617 |
+
}
|
618 |
+
|
619 |
+
$currColumn++;
|
620 |
+
}
|
621 |
+
|
622 |
+
$length += ($currColumn - $lastCurrColumn);
|
623 |
+
$newContent .= $prefix.str_repeat($padding, ($currColumn - $lastCurrColumn - 1));
|
624 |
+
}//end foreach
|
625 |
+
}//end if
|
626 |
+
|
627 |
+
$token['orig_content'] = $token['content'];
|
628 |
+
$token['content'] = $newContent;
|
629 |
+
$token['length'] = $length;
|
630 |
+
|
631 |
+
}//end replaceTabsInToken()
|
632 |
+
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Creates a map of brackets positions.
|
636 |
+
*
|
637 |
+
* @return void
|
638 |
+
*/
|
639 |
+
private function createTokenMap()
|
640 |
+
{
|
641 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
642 |
+
echo "\t*** START TOKEN MAP ***".PHP_EOL;
|
643 |
+
}
|
644 |
+
|
645 |
+
$squareOpeners = [];
|
646 |
+
$curlyOpeners = [];
|
647 |
+
$this->numTokens = count($this->tokens);
|
648 |
+
|
649 |
+
$openers = [];
|
650 |
+
$openOwner = null;
|
651 |
+
|
652 |
+
for ($i = 0; $i < $this->numTokens; $i++) {
|
653 |
+
/*
|
654 |
+
Parenthesis mapping.
|
655 |
+
*/
|
656 |
+
|
657 |
+
if (isset(Util\Tokens::$parenthesisOpeners[$this->tokens[$i]['code']]) === true) {
|
658 |
+
$this->tokens[$i]['parenthesis_opener'] = null;
|
659 |
+
$this->tokens[$i]['parenthesis_closer'] = null;
|
660 |
+
$this->tokens[$i]['parenthesis_owner'] = $i;
|
661 |
+
$openOwner = $i;
|
662 |
+
} else if ($this->tokens[$i]['code'] === T_OPEN_PARENTHESIS) {
|
663 |
+
$openers[] = $i;
|
664 |
+
$this->tokens[$i]['parenthesis_opener'] = $i;
|
665 |
+
if ($openOwner !== null) {
|
666 |
+
$this->tokens[$openOwner]['parenthesis_opener'] = $i;
|
667 |
+
$this->tokens[$i]['parenthesis_owner'] = $openOwner;
|
668 |
+
$openOwner = null;
|
669 |
+
}
|
670 |
+
} else if ($this->tokens[$i]['code'] === T_CLOSE_PARENTHESIS) {
|
671 |
+
// Did we set an owner for this set of parenthesis?
|
672 |
+
$numOpeners = count($openers);
|
673 |
+
if ($numOpeners !== 0) {
|
674 |
+
$opener = array_pop($openers);
|
675 |
+
if (isset($this->tokens[$opener]['parenthesis_owner']) === true) {
|
676 |
+
$owner = $this->tokens[$opener]['parenthesis_owner'];
|
677 |
+
|
678 |
+
$this->tokens[$owner]['parenthesis_closer'] = $i;
|
679 |
+
$this->tokens[$i]['parenthesis_owner'] = $owner;
|
680 |
+
}
|
681 |
+
|
682 |
+
$this->tokens[$i]['parenthesis_opener'] = $opener;
|
683 |
+
$this->tokens[$i]['parenthesis_closer'] = $i;
|
684 |
+
$this->tokens[$opener]['parenthesis_closer'] = $i;
|
685 |
+
}
|
686 |
+
}//end if
|
687 |
+
|
688 |
+
/*
|
689 |
+
Bracket mapping.
|
690 |
+
*/
|
691 |
+
|
692 |
+
switch ($this->tokens[$i]['code']) {
|
693 |
+
case T_OPEN_SQUARE_BRACKET:
|
694 |
+
$squareOpeners[] = $i;
|
695 |
+
|
696 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
697 |
+
echo str_repeat("\t", count($squareOpeners));
|
698 |
+
echo str_repeat("\t", count($curlyOpeners));
|
699 |
+
echo "=> Found square bracket opener at $i".PHP_EOL;
|
700 |
+
}
|
701 |
+
break;
|
702 |
+
case T_OPEN_CURLY_BRACKET:
|
703 |
+
if (isset($this->tokens[$i]['scope_closer']) === false) {
|
704 |
+
$curlyOpeners[] = $i;
|
705 |
+
|
706 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
707 |
+
echo str_repeat("\t", count($squareOpeners));
|
708 |
+
echo str_repeat("\t", count($curlyOpeners));
|
709 |
+
echo "=> Found curly bracket opener at $i".PHP_EOL;
|
710 |
+
}
|
711 |
+
}
|
712 |
+
break;
|
713 |
+
case T_CLOSE_SQUARE_BRACKET:
|
714 |
+
if (empty($squareOpeners) === false) {
|
715 |
+
$opener = array_pop($squareOpeners);
|
716 |
+
$this->tokens[$i]['bracket_opener'] = $opener;
|
717 |
+
$this->tokens[$i]['bracket_closer'] = $i;
|
718 |
+
$this->tokens[$opener]['bracket_opener'] = $opener;
|
719 |
+
$this->tokens[$opener]['bracket_closer'] = $i;
|
720 |
+
|
721 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
722 |
+
echo str_repeat("\t", count($squareOpeners));
|
723 |
+
echo str_repeat("\t", count($curlyOpeners));
|
724 |
+
echo "\t=> Found square bracket closer at $i for $opener".PHP_EOL;
|
725 |
+
}
|
726 |
+
}
|
727 |
+
break;
|
728 |
+
case T_CLOSE_CURLY_BRACKET:
|
729 |
+
if (empty($curlyOpeners) === false
|
730 |
+
&& isset($this->tokens[$i]['scope_opener']) === false
|
731 |
+
) {
|
732 |
+
$opener = array_pop($curlyOpeners);
|
733 |
+
$this->tokens[$i]['bracket_opener'] = $opener;
|
734 |
+
$this->tokens[$i]['bracket_closer'] = $i;
|
735 |
+
$this->tokens[$opener]['bracket_opener'] = $opener;
|
736 |
+
$this->tokens[$opener]['bracket_closer'] = $i;
|
737 |
+
|
738 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
739 |
+
echo str_repeat("\t", count($squareOpeners));
|
740 |
+
echo str_repeat("\t", count($curlyOpeners));
|
741 |
+
echo "\t=> Found curly bracket closer at $i for $opener".PHP_EOL;
|
742 |
+
}
|
743 |
+
}
|
744 |
+
break;
|
745 |
+
default:
|
746 |
+
continue 2;
|
747 |
+
}//end switch
|
748 |
+
}//end for
|
749 |
+
|
750 |
+
// Cleanup for any openers that we didn't find closers for.
|
751 |
+
// This typically means there was a syntax error breaking things.
|
752 |
+
foreach ($openers as $opener) {
|
753 |
+
unset($this->tokens[$opener]['parenthesis_opener']);
|
754 |
+
unset($this->tokens[$opener]['parenthesis_owner']);
|
755 |
+
}
|
756 |
+
|
757 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
758 |
+
echo "\t*** END TOKEN MAP ***".PHP_EOL;
|
759 |
+
}
|
760 |
+
|
761 |
+
}//end createTokenMap()
|
762 |
+
|
763 |
+
|
764 |
+
/**
|
765 |
+
* Creates a map for the parenthesis tokens that surround other tokens.
|
766 |
+
*
|
767 |
+
* @return void
|
768 |
+
*/
|
769 |
+
private function createParenthesisNestingMap()
|
770 |
+
{
|
771 |
+
$map = [];
|
772 |
+
for ($i = 0; $i < $this->numTokens; $i++) {
|
773 |
+
if (isset($this->tokens[$i]['parenthesis_opener']) === true
|
774 |
+
&& $i === $this->tokens[$i]['parenthesis_opener']
|
775 |
+
) {
|
776 |
+
if (empty($map) === false) {
|
777 |
+
$this->tokens[$i]['nested_parenthesis'] = $map;
|
778 |
+
}
|
779 |
+
|
780 |
+
if (isset($this->tokens[$i]['parenthesis_closer']) === true) {
|
781 |
+
$map[$this->tokens[$i]['parenthesis_opener']]
|
782 |
+
= $this->tokens[$i]['parenthesis_closer'];
|
783 |
+
}
|
784 |
+
} else if (isset($this->tokens[$i]['parenthesis_closer']) === true
|
785 |
+
&& $i === $this->tokens[$i]['parenthesis_closer']
|
786 |
+
) {
|
787 |
+
array_pop($map);
|
788 |
+
if (empty($map) === false) {
|
789 |
+
$this->tokens[$i]['nested_parenthesis'] = $map;
|
790 |
+
}
|
791 |
+
} else {
|
792 |
+
if (empty($map) === false) {
|
793 |
+
$this->tokens[$i]['nested_parenthesis'] = $map;
|
794 |
+
}
|
795 |
+
}//end if
|
796 |
+
}//end for
|
797 |
+
|
798 |
+
}//end createParenthesisNestingMap()
|
799 |
+
|
800 |
+
|
801 |
+
/**
|
802 |
+
* Creates a scope map of tokens that open scopes.
|
803 |
+
*
|
804 |
+
* @return void
|
805 |
+
* @see recurseScopeMap()
|
806 |
+
*/
|
807 |
+
private function createScopeMap()
|
808 |
+
{
|
809 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
810 |
+
echo "\t*** START SCOPE MAP ***".PHP_EOL;
|
811 |
+
}
|
812 |
+
|
813 |
+
for ($i = 0; $i < $this->numTokens; $i++) {
|
814 |
+
// Check to see if the current token starts a new scope.
|
815 |
+
if (isset($this->scopeOpeners[$this->tokens[$i]['code']]) === true) {
|
816 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
817 |
+
$type = $this->tokens[$i]['type'];
|
818 |
+
$content = Util\Common::prepareForOutput($this->tokens[$i]['content']);
|
819 |
+
echo "\tStart scope map at $i:$type => $content".PHP_EOL;
|
820 |
+
}
|
821 |
+
|
822 |
+
if (isset($this->tokens[$i]['scope_condition']) === true) {
|
823 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
824 |
+
echo "\t* already processed, skipping *".PHP_EOL;
|
825 |
+
}
|
826 |
+
|
827 |
+
continue;
|
828 |
+
}
|
829 |
+
|
830 |
+
$i = $this->recurseScopeMap($i);
|
831 |
+
}//end if
|
832 |
+
}//end for
|
833 |
+
|
834 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
835 |
+
echo "\t*** END SCOPE MAP ***".PHP_EOL;
|
836 |
+
}
|
837 |
+
|
838 |
+
}//end createScopeMap()
|
839 |
+
|
840 |
+
|
841 |
+
/**
|
842 |
+
* Recurses though the scope openers to build a scope map.
|
843 |
+
*
|
844 |
+
* @param int $stackPtr The position in the stack of the token that
|
845 |
+
* opened the scope (eg. an IF token or FOR token).
|
846 |
+
* @param int $depth How many scope levels down we are.
|
847 |
+
* @param int $ignore How many curly braces we are ignoring.
|
848 |
+
*
|
849 |
+
* @return int The position in the stack that closed the scope.
|
850 |
+
*/
|
851 |
+
private function recurseScopeMap($stackPtr, $depth=1, &$ignore=0)
|
852 |
+
{
|
853 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
854 |
+
echo str_repeat("\t", $depth);
|
855 |
+
echo "=> Begin scope map recursion at token $stackPtr with depth $depth".PHP_EOL;
|
856 |
+
}
|
857 |
+
|
858 |
+
$opener = null;
|
859 |
+
$currType = $this->tokens[$stackPtr]['code'];
|
860 |
+
$startLine = $this->tokens[$stackPtr]['line'];
|
861 |
+
|
862 |
+
// We will need this to restore the value if we end up
|
863 |
+
// returning a token ID that causes our calling function to go back
|
864 |
+
// over already ignored braces.
|
865 |
+
$originalIgnore = $ignore;
|
866 |
+
|
867 |
+
// If the start token for this scope opener is the same as
|
868 |
+
// the scope token, we have already found our opener.
|
869 |
+
if (isset($this->scopeOpeners[$currType]['start'][$currType]) === true) {
|
870 |
+
$opener = $stackPtr;
|
871 |
+
}
|
872 |
+
|
873 |
+
for ($i = ($stackPtr + 1); $i < $this->numTokens; $i++) {
|
874 |
+
$tokenType = $this->tokens[$i]['code'];
|
875 |
+
|
876 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
877 |
+
$type = $this->tokens[$i]['type'];
|
878 |
+
$line = $this->tokens[$i]['line'];
|
879 |
+
$content = Util\Common::prepareForOutput($this->tokens[$i]['content']);
|
880 |
+
|
881 |
+
echo str_repeat("\t", $depth);
|
882 |
+
echo "Process token $i on line $line [";
|
883 |
+
if ($opener !== null) {
|
884 |
+
echo "opener:$opener;";
|
885 |
+
}
|
886 |
+
|
887 |
+
if ($ignore > 0) {
|
888 |
+
echo "ignore=$ignore;";
|
889 |
+
}
|
890 |
+
|
891 |
+
echo "]: $type => $content".PHP_EOL;
|
892 |
+
}//end if
|
893 |
+
|
894 |
+
// Very special case for IF statements in PHP that can be defined without
|
895 |
+
// scope tokens. E.g., if (1) 1; 1 ? (1 ? 1 : 1) : 1;
|
896 |
+
// If an IF statement below this one has an opener but no
|
897 |
+
// keyword, the opener will be incorrectly assigned to this IF statement.
|
898 |
+
// The same case also applies to USE statements, which don't have to have
|
899 |
+
// openers, so a following USE statement can cause an incorrect brace match.
|
900 |
+
if (($currType === T_IF || $currType === T_ELSE || $currType === T_USE)
|
901 |
+
&& $opener === null
|
902 |
+
&& ($this->tokens[$i]['code'] === T_SEMICOLON
|
903 |
+
|| $this->tokens[$i]['code'] === T_CLOSE_TAG)
|
904 |
+
) {
|
905 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
906 |
+
$type = $this->tokens[$stackPtr]['type'];
|
907 |
+
echo str_repeat("\t", $depth);
|
908 |
+
if ($this->tokens[$i]['code'] === T_SEMICOLON) {
|
909 |
+
$closerType = 'semicolon';
|
910 |
+
} else {
|
911 |
+
$closerType = 'close tag';
|
912 |
+
}
|
913 |
+
|
914 |
+
echo "=> Found $closerType before scope opener for $stackPtr:$type, bailing".PHP_EOL;
|
915 |
+
}
|
916 |
+
|
917 |
+
return $i;
|
918 |
+
}
|
919 |
+
|
920 |
+
// Special case for PHP control structures that have no braces.
|
921 |
+
// If we find a curly brace closer before we find the opener,
|
922 |
+
// we're not going to find an opener. That closer probably belongs to
|
923 |
+
// a control structure higher up.
|
924 |
+
if ($opener === null
|
925 |
+
&& $ignore === 0
|
926 |
+
&& $tokenType === T_CLOSE_CURLY_BRACKET
|
927 |
+
&& isset($this->scopeOpeners[$currType]['end'][$tokenType]) === true
|
928 |
+
) {
|
929 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
930 |
+
$type = $this->tokens[$stackPtr]['type'];
|
931 |
+
echo str_repeat("\t", $depth);
|
932 |
+
echo "=> Found curly brace closer before scope opener for $stackPtr:$type, bailing".PHP_EOL;
|
933 |
+
}
|
934 |
+
|
935 |
+
return ($i - 1);
|
936 |
+
}
|
937 |
+
|
938 |
+
if ($opener !== null
|
939 |
+
&& (isset($this->tokens[$i]['scope_opener']) === false
|
940 |
+
|| $this->scopeOpeners[$this->tokens[$stackPtr]['code']]['shared'] === true)
|
941 |
+
&& isset($this->scopeOpeners[$currType]['end'][$tokenType]) === true
|
942 |
+
) {
|
943 |
+
if ($ignore > 0 && $tokenType === T_CLOSE_CURLY_BRACKET) {
|
944 |
+
// The last opening bracket must have been for a string
|
945 |
+
// offset or alike, so let's ignore it.
|
946 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
947 |
+
echo str_repeat("\t", $depth);
|
948 |
+
echo '* finished ignoring curly brace *'.PHP_EOL;
|
949 |
+
}
|
950 |
+
|
951 |
+
$ignore--;
|
952 |
+
continue;
|
953 |
+
} else if ($this->tokens[$opener]['code'] === T_OPEN_CURLY_BRACKET
|
954 |
+
&& $tokenType !== T_CLOSE_CURLY_BRACKET
|
955 |
+
) {
|
956 |
+
// The opener is a curly bracket so the closer must be a curly bracket as well.
|
957 |
+
// We ignore this closer to handle cases such as T_ELSE or T_ELSEIF being considered
|
958 |
+
// a closer of T_IF when it should not.
|
959 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
960 |
+
$type = $this->tokens[$stackPtr]['type'];
|
961 |
+
echo str_repeat("\t", $depth);
|
962 |
+
echo "=> Ignoring non-curly scope closer for $stackPtr:$type".PHP_EOL;
|
963 |
+
}
|
964 |
+
} else {
|
965 |
+
$scopeCloser = $i;
|
966 |
+
$todo = [
|
967 |
+
$stackPtr,
|
968 |
+
$opener,
|
969 |
+
];
|
970 |
+
|
971 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
972 |
+
$type = $this->tokens[$stackPtr]['type'];
|
973 |
+
$closerType = $this->tokens[$scopeCloser]['type'];
|
974 |
+
echo str_repeat("\t", $depth);
|
975 |
+
echo "=> Found scope closer ($scopeCloser:$closerType) for $stackPtr:$type".PHP_EOL;
|
976 |
+
}
|
977 |
+
|
978 |
+
$validCloser = true;
|
979 |
+
if (($this->tokens[$stackPtr]['code'] === T_IF || $this->tokens[$stackPtr]['code'] === T_ELSEIF)
|
980 |
+
&& ($tokenType === T_ELSE || $tokenType === T_ELSEIF)
|
981 |
+
) {
|
982 |
+
// To be a closer, this token must have an opener.
|
983 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
984 |
+
echo str_repeat("\t", $depth);
|
985 |
+
echo "* closer needs to be tested *".PHP_EOL;
|
986 |
+
}
|
987 |
+
|
988 |
+
$i = self::recurseScopeMap($i, ($depth + 1), $ignore);
|
989 |
+
|
990 |
+
if (isset($this->tokens[$scopeCloser]['scope_opener']) === false) {
|
991 |
+
$validCloser = false;
|
992 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
993 |
+
echo str_repeat("\t", $depth);
|
994 |
+
echo "* closer is not valid (no opener found) *".PHP_EOL;
|
995 |
+
}
|
996 |
+
} else if ($this->tokens[$this->tokens[$scopeCloser]['scope_opener']]['code'] !== $this->tokens[$opener]['code']) {
|
997 |
+
$validCloser = false;
|
998 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
999 |
+
echo str_repeat("\t", $depth);
|
1000 |
+
$type = $this->tokens[$this->tokens[$scopeCloser]['scope_opener']]['type'];
|
1001 |
+
$openerType = $this->tokens[$opener]['type'];
|
1002 |
+
echo "* closer is not valid (mismatched opener type; $type != $openerType) *".PHP_EOL;
|
1003 |
+
}
|
1004 |
+
} else if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1005 |
+
echo str_repeat("\t", $depth);
|
1006 |
+
echo "* closer was valid *".PHP_EOL;
|
1007 |
+
}
|
1008 |
+
} else {
|
1009 |
+
// The closer was not processed, so we need to
|
1010 |
+
// complete that token as well.
|
1011 |
+
$todo[] = $scopeCloser;
|
1012 |
+
}//end if
|
1013 |
+
|
1014 |
+
if ($validCloser === true) {
|
1015 |
+
foreach ($todo as $token) {
|
1016 |
+
$this->tokens[$token]['scope_condition'] = $stackPtr;
|
1017 |
+
$this->tokens[$token]['scope_opener'] = $opener;
|
1018 |
+
$this->tokens[$token]['scope_closer'] = $scopeCloser;
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
if ($this->scopeOpeners[$this->tokens[$stackPtr]['code']]['shared'] === true) {
|
1022 |
+
// As we are going back to where we started originally, restore
|
1023 |
+
// the ignore value back to its original value.
|
1024 |
+
$ignore = $originalIgnore;
|
1025 |
+
return $opener;
|
1026 |
+
} else if ($scopeCloser === $i
|
1027 |
+
&& isset($this->scopeOpeners[$tokenType]) === true
|
1028 |
+
) {
|
1029 |
+
// Unset scope_condition here or else the token will appear to have
|
1030 |
+
// already been processed, and it will be skipped. Normally we want that,
|
1031 |
+
// but in this case, the token is both a closer and an opener, so
|
1032 |
+
// it needs to act like an opener. This is also why we return the
|
1033 |
+
// token before this one; so the closer has a chance to be processed
|
1034 |
+
// a second time, but as an opener.
|
1035 |
+
unset($this->tokens[$scopeCloser]['scope_condition']);
|
1036 |
+
return ($i - 1);
|
1037 |
+
} else {
|
1038 |
+
return $i;
|
1039 |
+
}
|
1040 |
+
} else {
|
1041 |
+
continue;
|
1042 |
+
}//end if
|
1043 |
+
}//end if
|
1044 |
+
}//end if
|
1045 |
+
|
1046 |
+
// Is this an opening condition ?
|
1047 |
+
if (isset($this->scopeOpeners[$tokenType]) === true) {
|
1048 |
+
if ($opener === null) {
|
1049 |
+
if ($tokenType === T_USE) {
|
1050 |
+
// PHP use keywords are special because they can be
|
1051 |
+
// used as blocks but also inline in function definitions.
|
1052 |
+
// So if we find them nested inside another opener, just skip them.
|
1053 |
+
continue;
|
1054 |
+
}
|
1055 |
+
|
1056 |
+
if ($tokenType === T_FUNCTION
|
1057 |
+
&& $this->tokens[$stackPtr]['code'] !== T_FUNCTION
|
1058 |
+
) {
|
1059 |
+
// Probably a closure, so process it manually.
|
1060 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1061 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1062 |
+
echo str_repeat("\t", $depth);
|
1063 |
+
echo "=> Found function before scope opener for $stackPtr:$type, processing manually".PHP_EOL;
|
1064 |
+
}
|
1065 |
+
|
1066 |
+
if (isset($this->tokens[$i]['scope_closer']) === true) {
|
1067 |
+
// We've already processed this closure.
|
1068 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1069 |
+
echo str_repeat("\t", $depth);
|
1070 |
+
echo '* already processed, skipping *'.PHP_EOL;
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
$i = $this->tokens[$i]['scope_closer'];
|
1074 |
+
continue;
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
$i = self::recurseScopeMap($i, ($depth + 1), $ignore);
|
1078 |
+
continue;
|
1079 |
+
}//end if
|
1080 |
+
|
1081 |
+
if ($tokenType === T_CLASS) {
|
1082 |
+
// Probably an anonymous class inside another anonymous class,
|
1083 |
+
// so process it manually.
|
1084 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1085 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1086 |
+
echo str_repeat("\t", $depth);
|
1087 |
+
echo "=> Found class before scope opener for $stackPtr:$type, processing manually".PHP_EOL;
|
1088 |
+
}
|
1089 |
+
|
1090 |
+
if (isset($this->tokens[$i]['scope_closer']) === true) {
|
1091 |
+
// We've already processed this anon class.
|
1092 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1093 |
+
echo str_repeat("\t", $depth);
|
1094 |
+
echo '* already processed, skipping *'.PHP_EOL;
|
1095 |
+
}
|
1096 |
+
|
1097 |
+
$i = $this->tokens[$i]['scope_closer'];
|
1098 |
+
continue;
|
1099 |
+
}
|
1100 |
+
|
1101 |
+
$i = self::recurseScopeMap($i, ($depth + 1), $ignore);
|
1102 |
+
continue;
|
1103 |
+
}//end if
|
1104 |
+
|
1105 |
+
// Found another opening condition but still haven't
|
1106 |
+
// found our opener, so we are never going to find one.
|
1107 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1108 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1109 |
+
echo str_repeat("\t", $depth);
|
1110 |
+
echo "=> Found new opening condition before scope opener for $stackPtr:$type, ";
|
1111 |
+
}
|
1112 |
+
|
1113 |
+
if (($this->tokens[$stackPtr]['code'] === T_IF
|
1114 |
+
|| $this->tokens[$stackPtr]['code'] === T_ELSEIF
|
1115 |
+
|| $this->tokens[$stackPtr]['code'] === T_ELSE)
|
1116 |
+
&& ($this->tokens[$i]['code'] === T_ELSE
|
1117 |
+
|| $this->tokens[$i]['code'] === T_ELSEIF)
|
1118 |
+
) {
|
1119 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1120 |
+
echo "continuing".PHP_EOL;
|
1121 |
+
}
|
1122 |
+
|
1123 |
+
return ($i - 1);
|
1124 |
+
} else {
|
1125 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1126 |
+
echo "backtracking".PHP_EOL;
|
1127 |
+
}
|
1128 |
+
|
1129 |
+
return $stackPtr;
|
1130 |
+
}
|
1131 |
+
}//end if
|
1132 |
+
|
1133 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1134 |
+
echo str_repeat("\t", $depth);
|
1135 |
+
echo '* token is an opening condition *'.PHP_EOL;
|
1136 |
+
}
|
1137 |
+
|
1138 |
+
$isShared = ($this->scopeOpeners[$tokenType]['shared'] === true);
|
1139 |
+
|
1140 |
+
if (isset($this->tokens[$i]['scope_condition']) === true) {
|
1141 |
+
// We've been here before.
|
1142 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1143 |
+
echo str_repeat("\t", $depth);
|
1144 |
+
echo '* already processed, skipping *'.PHP_EOL;
|
1145 |
+
}
|
1146 |
+
|
1147 |
+
if ($isShared === false
|
1148 |
+
&& isset($this->tokens[$i]['scope_closer']) === true
|
1149 |
+
) {
|
1150 |
+
$i = $this->tokens[$i]['scope_closer'];
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
continue;
|
1154 |
+
} else if ($currType === $tokenType
|
1155 |
+
&& $isShared === false
|
1156 |
+
&& $opener === null
|
1157 |
+
) {
|
1158 |
+
// We haven't yet found our opener, but we have found another
|
1159 |
+
// scope opener which is the same type as us, and we don't
|
1160 |
+
// share openers, so we will never find one.
|
1161 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1162 |
+
echo str_repeat("\t", $depth);
|
1163 |
+
echo '* it was another token\'s opener, bailing *'.PHP_EOL;
|
1164 |
+
}
|
1165 |
+
|
1166 |
+
return $stackPtr;
|
1167 |
+
} else {
|
1168 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1169 |
+
echo str_repeat("\t", $depth);
|
1170 |
+
echo '* searching for opener *'.PHP_EOL;
|
1171 |
+
}
|
1172 |
+
|
1173 |
+
if (isset($this->scopeOpeners[$tokenType]['end'][T_CLOSE_CURLY_BRACKET]) === true) {
|
1174 |
+
$oldIgnore = $ignore;
|
1175 |
+
$ignore = 0;
|
1176 |
+
}
|
1177 |
+
|
1178 |
+
// PHP has a max nesting level for functions. Stop before we hit that limit
|
1179 |
+
// because too many loops means we've run into trouble anyway.
|
1180 |
+
if ($depth > 50) {
|
1181 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1182 |
+
echo str_repeat("\t", $depth);
|
1183 |
+
echo '* reached maximum nesting level; aborting *'.PHP_EOL;
|
1184 |
+
}
|
1185 |
+
|
1186 |
+
throw new RuntimeException('Maximum nesting level reached; file could not be processed');
|
1187 |
+
}
|
1188 |
+
|
1189 |
+
$oldDepth = $depth;
|
1190 |
+
if ($isShared === true
|
1191 |
+
&& isset($this->scopeOpeners[$tokenType]['with'][$currType]) === true
|
1192 |
+
) {
|
1193 |
+
// Don't allow the depth to increment because this is
|
1194 |
+
// possibly not a true nesting if we are sharing our closer.
|
1195 |
+
// This can happen, for example, when a SWITCH has a large
|
1196 |
+
// number of CASE statements with the same shared BREAK.
|
1197 |
+
$depth--;
|
1198 |
+
}
|
1199 |
+
|
1200 |
+
$i = self::recurseScopeMap($i, ($depth + 1), $ignore);
|
1201 |
+
$depth = $oldDepth;
|
1202 |
+
|
1203 |
+
if (isset($this->scopeOpeners[$tokenType]['end'][T_CLOSE_CURLY_BRACKET]) === true) {
|
1204 |
+
$ignore = $oldIgnore;
|
1205 |
+
}
|
1206 |
+
}//end if
|
1207 |
+
}//end if
|
1208 |
+
|
1209 |
+
if (isset($this->scopeOpeners[$currType]['start'][$tokenType]) === true
|
1210 |
+
&& $opener === null
|
1211 |
+
) {
|
1212 |
+
if ($tokenType === T_OPEN_CURLY_BRACKET) {
|
1213 |
+
if (isset($this->tokens[$stackPtr]['parenthesis_closer']) === true
|
1214 |
+
&& $i < $this->tokens[$stackPtr]['parenthesis_closer']
|
1215 |
+
) {
|
1216 |
+
// We found a curly brace inside the condition of the
|
1217 |
+
// current scope opener, so it must be a string offset.
|
1218 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1219 |
+
echo str_repeat("\t", $depth);
|
1220 |
+
echo '* ignoring curly brace inside condition *'.PHP_EOL;
|
1221 |
+
}
|
1222 |
+
|
1223 |
+
$ignore++;
|
1224 |
+
} else {
|
1225 |
+
// Make sure this is actually an opener and not a
|
1226 |
+
// string offset (e.g., $var{0}).
|
1227 |
+
for ($x = ($i - 1); $x > 0; $x--) {
|
1228 |
+
if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === true) {
|
1229 |
+
continue;
|
1230 |
+
} else {
|
1231 |
+
// If the first non-whitespace/comment token looks like this
|
1232 |
+
// brace is a string offset, or this brace is mid-way through
|
1233 |
+
// a new statement, it isn't a scope opener.
|
1234 |
+
$disallowed = Util\Tokens::$assignmentTokens;
|
1235 |
+
$disallowed += [
|
1236 |
+
T_DOLLAR => true,
|
1237 |
+
T_VARIABLE => true,
|
1238 |
+
T_OBJECT_OPERATOR => true,
|
1239 |
+
T_COMMA => true,
|
1240 |
+
T_OPEN_PARENTHESIS => true,
|
1241 |
+
];
|
1242 |
+
|
1243 |
+
if (isset($disallowed[$this->tokens[$x]['code']]) === true) {
|
1244 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1245 |
+
echo str_repeat("\t", $depth);
|
1246 |
+
echo '* ignoring curly brace *'.PHP_EOL;
|
1247 |
+
}
|
1248 |
+
|
1249 |
+
$ignore++;
|
1250 |
+
}
|
1251 |
+
|
1252 |
+
break;
|
1253 |
+
}//end if
|
1254 |
+
}//end for
|
1255 |
+
}//end if
|
1256 |
+
}//end if
|
1257 |
+
|
1258 |
+
if ($ignore === 0 || $tokenType !== T_OPEN_CURLY_BRACKET) {
|
1259 |
+
// We found the opening scope token for $currType.
|
1260 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1261 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1262 |
+
echo str_repeat("\t", $depth);
|
1263 |
+
echo "=> Found scope opener for $stackPtr:$type".PHP_EOL;
|
1264 |
+
}
|
1265 |
+
|
1266 |
+
$opener = $i;
|
1267 |
+
}
|
1268 |
+
} else if ($tokenType === T_OPEN_PARENTHESIS) {
|
1269 |
+
if (isset($this->tokens[$i]['parenthesis_owner']) === true) {
|
1270 |
+
$owner = $this->tokens[$i]['parenthesis_owner'];
|
1271 |
+
if (isset(Util\Tokens::$scopeOpeners[$this->tokens[$owner]['code']]) === true
|
1272 |
+
&& isset($this->tokens[$i]['parenthesis_closer']) === true
|
1273 |
+
) {
|
1274 |
+
// If we get into here, then we opened a parenthesis for
|
1275 |
+
// a scope (eg. an if or else if) so we need to update the
|
1276 |
+
// start of the line so that when we check to see
|
1277 |
+
// if the closing parenthesis is more than 3 lines away from
|
1278 |
+
// the statement, we check from the closing parenthesis.
|
1279 |
+
$startLine = $this->tokens[$this->tokens[$i]['parenthesis_closer']]['line'];
|
1280 |
+
}
|
1281 |
+
}
|
1282 |
+
} else if ($tokenType === T_OPEN_CURLY_BRACKET && $opener !== null) {
|
1283 |
+
// We opened something that we don't have a scope opener for.
|
1284 |
+
// Examples of this are curly brackets for string offsets etc.
|
1285 |
+
// We want to ignore this so that we don't have an invalid scope
|
1286 |
+
// map.
|
1287 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1288 |
+
echo str_repeat("\t", $depth);
|
1289 |
+
echo '* ignoring curly brace *'.PHP_EOL;
|
1290 |
+
}
|
1291 |
+
|
1292 |
+
$ignore++;
|
1293 |
+
} else if ($tokenType === T_CLOSE_CURLY_BRACKET && $ignore > 0) {
|
1294 |
+
// We found the end token for the opener we were ignoring.
|
1295 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1296 |
+
echo str_repeat("\t", $depth);
|
1297 |
+
echo '* finished ignoring curly brace *'.PHP_EOL;
|
1298 |
+
}
|
1299 |
+
|
1300 |
+
$ignore--;
|
1301 |
+
} else if ($opener === null
|
1302 |
+
&& isset($this->scopeOpeners[$currType]) === true
|
1303 |
+
) {
|
1304 |
+
// If we still haven't found the opener after 30 lines,
|
1305 |
+
// we're not going to find it, unless we know it requires
|
1306 |
+
// an opener (in which case we better keep looking) or the last
|
1307 |
+
// token was empty (in which case we'll just confirm there is
|
1308 |
+
// more code in this file and not just a big comment).
|
1309 |
+
if ($this->tokens[$i]['line'] >= ($startLine + 30)
|
1310 |
+
&& isset(Util\Tokens::$emptyTokens[$this->tokens[($i - 1)]['code']]) === false
|
1311 |
+
) {
|
1312 |
+
if ($this->scopeOpeners[$currType]['strict'] === true) {
|
1313 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1314 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1315 |
+
$lines = ($this->tokens[$i]['line'] - $startLine);
|
1316 |
+
echo str_repeat("\t", $depth);
|
1317 |
+
echo "=> Still looking for $stackPtr:$type scope opener after $lines lines".PHP_EOL;
|
1318 |
+
}
|
1319 |
+
} else {
|
1320 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1321 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1322 |
+
echo str_repeat("\t", $depth);
|
1323 |
+
echo "=> Couldn't find scope opener for $stackPtr:$type, bailing".PHP_EOL;
|
1324 |
+
}
|
1325 |
+
|
1326 |
+
return $stackPtr;
|
1327 |
+
}
|
1328 |
+
}
|
1329 |
+
} else if ($opener !== null
|
1330 |
+
&& $tokenType !== T_BREAK
|
1331 |
+
&& isset($this->endScopeTokens[$tokenType]) === true
|
1332 |
+
) {
|
1333 |
+
if (isset($this->tokens[$i]['scope_condition']) === false) {
|
1334 |
+
if ($ignore > 0) {
|
1335 |
+
// We found the end token for the opener we were ignoring.
|
1336 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1337 |
+
echo str_repeat("\t", $depth);
|
1338 |
+
echo '* finished ignoring curly brace *'.PHP_EOL;
|
1339 |
+
}
|
1340 |
+
|
1341 |
+
$ignore--;
|
1342 |
+
} else {
|
1343 |
+
// We found a token that closes the scope but it doesn't
|
1344 |
+
// have a condition, so it belongs to another token and
|
1345 |
+
// our token doesn't have a closer, so pretend this is
|
1346 |
+
// the closer.
|
1347 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1348 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1349 |
+
echo str_repeat("\t", $depth);
|
1350 |
+
echo "=> Found (unexpected) scope closer for $stackPtr:$type".PHP_EOL;
|
1351 |
+
}
|
1352 |
+
|
1353 |
+
foreach ([$stackPtr, $opener] as $token) {
|
1354 |
+
$this->tokens[$token]['scope_condition'] = $stackPtr;
|
1355 |
+
$this->tokens[$token]['scope_opener'] = $opener;
|
1356 |
+
$this->tokens[$token]['scope_closer'] = $i;
|
1357 |
+
}
|
1358 |
+
|
1359 |
+
return ($i - 1);
|
1360 |
+
}//end if
|
1361 |
+
}//end if
|
1362 |
+
}//end if
|
1363 |
+
}//end for
|
1364 |
+
|
1365 |
+
return $stackPtr;
|
1366 |
+
|
1367 |
+
}//end recurseScopeMap()
|
1368 |
+
|
1369 |
+
|
1370 |
+
/**
|
1371 |
+
* Constructs the level map.
|
1372 |
+
*
|
1373 |
+
* The level map adds a 'level' index to each token which indicates the
|
1374 |
+
* depth that a token within a set of scope blocks. It also adds a
|
1375 |
+
* 'conditions' index which is an array of the scope conditions that opened
|
1376 |
+
* each of the scopes - position 0 being the first scope opener.
|
1377 |
+
*
|
1378 |
+
* @return void
|
1379 |
+
*/
|
1380 |
+
private function createLevelMap()
|
1381 |
+
{
|
1382 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1383 |
+
echo "\t*** START LEVEL MAP ***".PHP_EOL;
|
1384 |
+
}
|
1385 |
+
|
1386 |
+
$this->numTokens = count($this->tokens);
|
1387 |
+
$level = 0;
|
1388 |
+
$conditions = [];
|
1389 |
+
$lastOpener = null;
|
1390 |
+
$openers = [];
|
1391 |
+
|
1392 |
+
for ($i = 0; $i < $this->numTokens; $i++) {
|
1393 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1394 |
+
$type = $this->tokens[$i]['type'];
|
1395 |
+
$line = $this->tokens[$i]['line'];
|
1396 |
+
$len = $this->tokens[$i]['length'];
|
1397 |
+
$col = $this->tokens[$i]['column'];
|
1398 |
+
|
1399 |
+
$content = Util\Common::prepareForOutput($this->tokens[$i]['content']);
|
1400 |
+
|
1401 |
+
echo str_repeat("\t", ($level + 1));
|
1402 |
+
echo "Process token $i on line $line [col:$col;len:$len;lvl:$level;";
|
1403 |
+
if (empty($conditions) !== true) {
|
1404 |
+
$condString = 'conds;';
|
1405 |
+
foreach ($conditions as $condition) {
|
1406 |
+
$condString .= Util\Tokens::tokenName($condition).',';
|
1407 |
+
}
|
1408 |
+
|
1409 |
+
echo rtrim($condString, ',').';';
|
1410 |
+
}
|
1411 |
+
|
1412 |
+
echo "]: $type => $content".PHP_EOL;
|
1413 |
+
}//end if
|
1414 |
+
|
1415 |
+
$this->tokens[$i]['level'] = $level;
|
1416 |
+
$this->tokens[$i]['conditions'] = $conditions;
|
1417 |
+
|
1418 |
+
if (isset($this->tokens[$i]['scope_condition']) === true) {
|
1419 |
+
// Check to see if this token opened the scope.
|
1420 |
+
if ($this->tokens[$i]['scope_opener'] === $i) {
|
1421 |
+
$stackPtr = $this->tokens[$i]['scope_condition'];
|
1422 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1423 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1424 |
+
echo str_repeat("\t", ($level + 1));
|
1425 |
+
echo "=> Found scope opener for $stackPtr:$type".PHP_EOL;
|
1426 |
+
}
|
1427 |
+
|
1428 |
+
$stackPtr = $this->tokens[$i]['scope_condition'];
|
1429 |
+
|
1430 |
+
// If we find a scope opener that has a shared closer,
|
1431 |
+
// then we need to go back over the condition map that we
|
1432 |
+
// just created and fix ourselves as we just added some
|
1433 |
+
// conditions where there was none. This happens for T_CASE
|
1434 |
+
// statements that are using the same break statement.
|
1435 |
+
if ($lastOpener !== null && $this->tokens[$lastOpener]['scope_closer'] === $this->tokens[$i]['scope_closer']) {
|
1436 |
+
// This opener shares its closer with the previous opener,
|
1437 |
+
// but we still need to check if the two openers share their
|
1438 |
+
// closer with each other directly (like CASE and DEFAULT)
|
1439 |
+
// or if they are just sharing because one doesn't have a
|
1440 |
+
// closer (like CASE with no BREAK using a SWITCHes closer).
|
1441 |
+
$thisType = $this->tokens[$this->tokens[$i]['scope_condition']]['code'];
|
1442 |
+
$opener = $this->tokens[$lastOpener]['scope_condition'];
|
1443 |
+
|
1444 |
+
$isShared = isset($this->scopeOpeners[$thisType]['with'][$this->tokens[$opener]['code']]);
|
1445 |
+
|
1446 |
+
reset($this->scopeOpeners[$thisType]['end']);
|
1447 |
+
reset($this->scopeOpeners[$this->tokens[$opener]['code']]['end']);
|
1448 |
+
$sameEnd = (current($this->scopeOpeners[$thisType]['end']) === current($this->scopeOpeners[$this->tokens[$opener]['code']]['end']));
|
1449 |
+
|
1450 |
+
if ($isShared === true && $sameEnd === true) {
|
1451 |
+
$badToken = $opener;
|
1452 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1453 |
+
$type = $this->tokens[$badToken]['type'];
|
1454 |
+
echo str_repeat("\t", ($level + 1));
|
1455 |
+
echo "* shared closer, cleaning up $badToken:$type *".PHP_EOL;
|
1456 |
+
}
|
1457 |
+
|
1458 |
+
for ($x = $this->tokens[$i]['scope_condition']; $x <= $i; $x++) {
|
1459 |
+
$oldConditions = $this->tokens[$x]['conditions'];
|
1460 |
+
$oldLevel = $this->tokens[$x]['level'];
|
1461 |
+
$this->tokens[$x]['level']--;
|
1462 |
+
unset($this->tokens[$x]['conditions'][$badToken]);
|
1463 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1464 |
+
$type = $this->tokens[$x]['type'];
|
1465 |
+
$oldConds = '';
|
1466 |
+
foreach ($oldConditions as $condition) {
|
1467 |
+
$oldConds .= Util\Tokens::tokenName($condition).',';
|
1468 |
+
}
|
1469 |
+
|
1470 |
+
$oldConds = rtrim($oldConds, ',');
|
1471 |
+
|
1472 |
+
$newConds = '';
|
1473 |
+
foreach ($this->tokens[$x]['conditions'] as $condition) {
|
1474 |
+
$newConds .= Util\Tokens::tokenName($condition).',';
|
1475 |
+
}
|
1476 |
+
|
1477 |
+
$newConds = rtrim($newConds, ',');
|
1478 |
+
|
1479 |
+
$newLevel = $this->tokens[$x]['level'];
|
1480 |
+
echo str_repeat("\t", ($level + 1));
|
1481 |
+
echo "* cleaned $x:$type *".PHP_EOL;
|
1482 |
+
echo str_repeat("\t", ($level + 2));
|
1483 |
+
echo "=> level changed from $oldLevel to $newLevel".PHP_EOL;
|
1484 |
+
echo str_repeat("\t", ($level + 2));
|
1485 |
+
echo "=> conditions changed from $oldConds to $newConds".PHP_EOL;
|
1486 |
+
}//end if
|
1487 |
+
}//end for
|
1488 |
+
|
1489 |
+
unset($conditions[$badToken]);
|
1490 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1491 |
+
$type = $this->tokens[$badToken]['type'];
|
1492 |
+
echo str_repeat("\t", ($level + 1));
|
1493 |
+
echo "* token $badToken:$type removed from conditions array *".PHP_EOL;
|
1494 |
+
}
|
1495 |
+
|
1496 |
+
unset($openers[$lastOpener]);
|
1497 |
+
|
1498 |
+
$level--;
|
1499 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1500 |
+
echo str_repeat("\t", ($level + 2));
|
1501 |
+
echo '* level decreased *'.PHP_EOL;
|
1502 |
+
}
|
1503 |
+
}//end if
|
1504 |
+
}//end if
|
1505 |
+
|
1506 |
+
$level++;
|
1507 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1508 |
+
echo str_repeat("\t", ($level + 1));
|
1509 |
+
echo '* level increased *'.PHP_EOL;
|
1510 |
+
}
|
1511 |
+
|
1512 |
+
$conditions[$stackPtr] = $this->tokens[$stackPtr]['code'];
|
1513 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1514 |
+
$type = $this->tokens[$stackPtr]['type'];
|
1515 |
+
echo str_repeat("\t", ($level + 1));
|
1516 |
+
echo "* token $stackPtr:$type added to conditions array *".PHP_EOL;
|
1517 |
+
}
|
1518 |
+
|
1519 |
+
$lastOpener = $this->tokens[$i]['scope_opener'];
|
1520 |
+
if ($lastOpener !== null) {
|
1521 |
+
$openers[$lastOpener] = $lastOpener;
|
1522 |
+
}
|
1523 |
+
} else if ($lastOpener !== null && $this->tokens[$lastOpener]['scope_closer'] === $i) {
|
1524 |
+
foreach (array_reverse($openers) as $opener) {
|
1525 |
+
if ($this->tokens[$opener]['scope_closer'] === $i) {
|
1526 |
+
$oldOpener = array_pop($openers);
|
1527 |
+
if (empty($openers) === false) {
|
1528 |
+
$lastOpener = array_pop($openers);
|
1529 |
+
$openers[$lastOpener] = $lastOpener;
|
1530 |
+
} else {
|
1531 |
+
$lastOpener = null;
|
1532 |
+
}
|
1533 |
+
|
1534 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1535 |
+
$type = $this->tokens[$oldOpener]['type'];
|
1536 |
+
echo str_repeat("\t", ($level + 1));
|
1537 |
+
echo "=> Found scope closer for $oldOpener:$type".PHP_EOL;
|
1538 |
+
}
|
1539 |
+
|
1540 |
+
$oldCondition = array_pop($conditions);
|
1541 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1542 |
+
echo str_repeat("\t", ($level + 1));
|
1543 |
+
echo '* token '.Util\Tokens::tokenName($oldCondition).' removed from conditions array *'.PHP_EOL;
|
1544 |
+
}
|
1545 |
+
|
1546 |
+
// Make sure this closer actually belongs to us.
|
1547 |
+
// Either the condition also has to think this is the
|
1548 |
+
// closer, or it has to allow sharing with us.
|
1549 |
+
$condition = $this->tokens[$this->tokens[$i]['scope_condition']]['code'];
|
1550 |
+
if ($condition !== $oldCondition) {
|
1551 |
+
if (isset($this->scopeOpeners[$oldCondition]['with'][$condition]) === false) {
|
1552 |
+
$badToken = $this->tokens[$oldOpener]['scope_condition'];
|
1553 |
+
|
1554 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1555 |
+
$type = Util\Tokens::tokenName($oldCondition);
|
1556 |
+
echo str_repeat("\t", ($level + 1));
|
1557 |
+
echo "* scope closer was bad, cleaning up $badToken:$type *".PHP_EOL;
|
1558 |
+
}
|
1559 |
+
|
1560 |
+
for ($x = ($oldOpener + 1); $x <= $i; $x++) {
|
1561 |
+
$oldConditions = $this->tokens[$x]['conditions'];
|
1562 |
+
$oldLevel = $this->tokens[$x]['level'];
|
1563 |
+
$this->tokens[$x]['level']--;
|
1564 |
+
unset($this->tokens[$x]['conditions'][$badToken]);
|
1565 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1566 |
+
$type = $this->tokens[$x]['type'];
|
1567 |
+
$oldConds = '';
|
1568 |
+
foreach ($oldConditions as $condition) {
|
1569 |
+
$oldConds .= Util\Tokens::tokenName($condition).',';
|
1570 |
+
}
|
1571 |
+
|
1572 |
+
$oldConds = rtrim($oldConds, ',');
|
1573 |
+
|
1574 |
+
$newConds = '';
|
1575 |
+
foreach ($this->tokens[$x]['conditions'] as $condition) {
|
1576 |
+
$newConds .= Util\Tokens::tokenName($condition).',';
|
1577 |
+
}
|
1578 |
+
|
1579 |
+
$newConds = rtrim($newConds, ',');
|
1580 |
+
|
1581 |
+
$newLevel = $this->tokens[$x]['level'];
|
1582 |
+
echo str_repeat("\t", ($level + 1));
|
1583 |
+
echo "* cleaned $x:$type *".PHP_EOL;
|
1584 |
+
echo str_repeat("\t", ($level + 2));
|
1585 |
+
echo "=> level changed from $oldLevel to $newLevel".PHP_EOL;
|
1586 |
+
echo str_repeat("\t", ($level + 2));
|
1587 |
+
echo "=> conditions changed from $oldConds to $newConds".PHP_EOL;
|
1588 |
+
}//end if
|
1589 |
+
}//end for
|
1590 |
+
}//end if
|
1591 |
+
}//end if
|
1592 |
+
|
1593 |
+
$level--;
|
1594 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1595 |
+
echo str_repeat("\t", ($level + 2));
|
1596 |
+
echo '* level decreased *'.PHP_EOL;
|
1597 |
+
}
|
1598 |
+
|
1599 |
+
$this->tokens[$i]['level'] = $level;
|
1600 |
+
$this->tokens[$i]['conditions'] = $conditions;
|
1601 |
+
}//end if
|
1602 |
+
}//end foreach
|
1603 |
+
}//end if
|
1604 |
+
}//end if
|
1605 |
+
}//end for
|
1606 |
+
|
1607 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1608 |
+
echo "\t*** END LEVEL MAP ***".PHP_EOL;
|
1609 |
+
}
|
1610 |
+
|
1611 |
+
}//end createLevelMap()
|
1612 |
+
|
1613 |
+
|
1614 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Util/Standards.php
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Util;
|
11 |
+
|
12 |
+
use PHP_CodeSniffer\Config;
|
13 |
+
|
14 |
+
class Standards {
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Get a list paths where standards are installed.
|
19 |
+
*
|
20 |
+
* @return array
|
21 |
+
*/
|
22 |
+
public static function getInstalledStandardPaths() {
|
23 |
+
return array();
|
24 |
+
|
25 |
+
}//end getInstalledStandardPaths()
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Get the details of all coding standards installed.
|
30 |
+
*
|
31 |
+
* Coding standards are directories located in the
|
32 |
+
* CodeSniffer/Standards directory. Valid coding standards
|
33 |
+
* include a Sniffs subdirectory.
|
34 |
+
*
|
35 |
+
* The details returned for each standard are:
|
36 |
+
* - path: the path to the coding standard's main directory
|
37 |
+
* - name: the name of the coding standard, as sourced from the ruleset.xml file
|
38 |
+
* - namespace: the namespace used by the coding standard, as sourced from the ruleset.xml file
|
39 |
+
*
|
40 |
+
* If you only need the paths to the installed standards,
|
41 |
+
* use getInstalledStandardPaths() instead as it performs less work to
|
42 |
+
* retrieve coding standard names.
|
43 |
+
*
|
44 |
+
* @param boolean $includeGeneric If true, the special "Generic"
|
45 |
+
* coding standard will be included
|
46 |
+
* if installed.
|
47 |
+
* @param string $standardsDir A specific directory to look for standards
|
48 |
+
* in. If not specified, PHP_CodeSniffer will
|
49 |
+
* look in its default locations.
|
50 |
+
*
|
51 |
+
* @return array
|
52 |
+
* @see getInstalledStandardPaths()
|
53 |
+
*/
|
54 |
+
public static function getInstalledStandardDetails(
|
55 |
+
$includeGeneric = false,
|
56 |
+
$standardsDir = ''
|
57 |
+
) {
|
58 |
+
return array();
|
59 |
+
|
60 |
+
}//end getInstalledStandardDetails()
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Get a list of all coding standards installed.
|
65 |
+
*
|
66 |
+
* Coding standards are directories located in the
|
67 |
+
* CodeSniffer/Standards directory. Valid coding standards
|
68 |
+
* include a Sniffs subdirectory.
|
69 |
+
*
|
70 |
+
* @param boolean $includeGeneric If true, the special "Generic"
|
71 |
+
* coding standard will be included
|
72 |
+
* if installed.
|
73 |
+
* @param string $standardsDir A specific directory to look for standards
|
74 |
+
* in. If not specified, PHP_CodeSniffer will
|
75 |
+
* look in its default locations.
|
76 |
+
*
|
77 |
+
* @return array
|
78 |
+
* @see isInstalledStandard()
|
79 |
+
*/
|
80 |
+
public static function getInstalledStandards(
|
81 |
+
$includeGeneric = false,
|
82 |
+
$standardsDir = ''
|
83 |
+
) {
|
84 |
+
|
85 |
+
return array();
|
86 |
+
|
87 |
+
}//end getInstalledStandards()
|
88 |
+
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Determine if a standard is installed.
|
92 |
+
*
|
93 |
+
* Coding standards are directories located in the
|
94 |
+
* CodeSniffer/Standards directory. Valid coding standards
|
95 |
+
* include a ruleset.xml file.
|
96 |
+
*
|
97 |
+
* @param string $standard The name of the coding standard.
|
98 |
+
*
|
99 |
+
* @return boolean
|
100 |
+
* @see getInstalledStandards()
|
101 |
+
*/
|
102 |
+
public static function isInstalledStandard( $standard ) {
|
103 |
+
return false;
|
104 |
+
|
105 |
+
}//end isInstalledStandard()
|
106 |
+
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Return the path of an installed coding standard.
|
110 |
+
*
|
111 |
+
* Coding standards are directories located in the
|
112 |
+
* CodeSniffer/Standards directory. Valid coding standards
|
113 |
+
* include a ruleset.xml file.
|
114 |
+
*
|
115 |
+
* @param string $standard The name of the coding standard.
|
116 |
+
*
|
117 |
+
* @return string|null
|
118 |
+
*/
|
119 |
+
public static function getInstalledStandardPath( $standard ) {
|
120 |
+
|
121 |
+
return null;
|
122 |
+
|
123 |
+
}//end getInstalledStandardPath()
|
124 |
+
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Prints out a list of installed coding standards.
|
128 |
+
*
|
129 |
+
* @return void
|
130 |
+
*/
|
131 |
+
public static function printInstalledStandards() {
|
132 |
+
|
133 |
+
|
134 |
+
}//end printInstalledStandards()
|
135 |
+
|
136 |
+
|
137 |
+
}//end class
|
vendor/php_codesniffer-3.4.0/src/Util/Tokens.php
ADDED
@@ -0,0 +1,644 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Stores weightings and groupings of tokens.
|
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/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace PHP_CodeSniffer\Util;
|
11 |
+
|
12 |
+
define('T_NONE', 'PHPCS_T_NONE');
|
13 |
+
define('T_OPEN_CURLY_BRACKET', 'PHPCS_T_OPEN_CURLY_BRACKET');
|
14 |
+
define('T_CLOSE_CURLY_BRACKET', 'PHPCS_T_CLOSE_CURLY_BRACKET');
|
15 |
+
define('T_OPEN_SQUARE_BRACKET', 'PHPCS_T_OPEN_SQUARE_BRACKET');
|
16 |
+
define('T_CLOSE_SQUARE_BRACKET', 'PHPCS_T_CLOSE_SQUARE_BRACKET');
|
17 |
+
define('T_OPEN_PARENTHESIS', 'PHPCS_T_OPEN_PARENTHESIS');
|
18 |
+
define('T_CLOSE_PARENTHESIS', 'PHPCS_T_CLOSE_PARENTHESIS');
|
19 |
+
define('T_COLON', 'PHPCS_T_COLON');
|
20 |
+
define('T_NULLABLE', 'PHPCS_T_NULLABLE');
|
21 |
+
define('T_STRING_CONCAT', 'PHPCS_T_STRING_CONCAT');
|
22 |
+
define('T_INLINE_THEN', 'PHPCS_T_INLINE_THEN');
|
23 |
+
define('T_INLINE_ELSE', 'PHPCS_T_INLINE_ELSE');
|
24 |
+
define('T_NULL', 'PHPCS_T_NULL');
|
25 |
+
define('T_FALSE', 'PHPCS_T_FALSE');
|
26 |
+
define('T_TRUE', 'PHPCS_T_TRUE');
|
27 |
+
define('T_SEMICOLON', 'PHPCS_T_SEMICOLON');
|
28 |
+
define('T_EQUAL', 'PHPCS_T_EQUAL');
|
29 |
+
define('T_MULTIPLY', 'PHPCS_T_MULTIPLY');
|
30 |
+
define('T_DIVIDE', 'PHPCS_T_DIVIDE');
|
31 |
+
define('T_PLUS', 'PHPCS_T_PLUS');
|
32 |
+
define('T_MINUS', 'PHPCS_T_MINUS');
|
33 |
+
define('T_MODULUS', 'PHPCS_T_MODULUS');
|
34 |
+
define('T_BITWISE_AND', 'PHPCS_T_BITWISE_AND');
|
35 |
+
define('T_BITWISE_OR', 'PHPCS_T_BITWISE_OR');
|
36 |
+
define('T_BITWISE_XOR', 'PHPCS_T_BITWISE_XOR');
|
37 |
+
define('T_BITWISE_NOT', 'PHPCS_T_BITWISE_NOT');
|
38 |
+
define('T_ARRAY_HINT', 'PHPCS_T_ARRAY_HINT');
|
39 |
+
define('T_GREATER_THAN', 'PHPCS_T_GREATER_THAN');
|
40 |
+
define('T_LESS_THAN', 'PHPCS_T_LESS_THAN');
|
41 |
+
define('T_BOOLEAN_NOT', 'PHPCS_T_BOOLEAN_NOT');
|
42 |
+
define('T_SELF', 'PHPCS_T_SELF');
|
43 |
+
define('T_PARENT', 'PHPCS_T_PARENT');
|
44 |
+
define('T_DOUBLE_QUOTED_STRING', 'PHPCS_T_DOUBLE_QUOTED_STRING');
|
45 |
+
define('T_COMMA', 'PHPCS_T_COMMA');
|
46 |
+
define('T_HEREDOC', 'PHPCS_T_HEREDOC');
|
47 |
+
define('T_PROTOTYPE', 'PHPCS_T_PROTOTYPE');
|
48 |
+
define('T_THIS', 'PHPCS_T_THIS');
|
49 |
+
define('T_REGULAR_EXPRESSION', 'PHPCS_T_REGULAR_EXPRESSION');
|
50 |
+
define('T_PROPERTY', 'PHPCS_T_PROPERTY');
|
51 |
+
define('T_LABEL', 'PHPCS_T_LABEL');
|
52 |
+
define('T_OBJECT', 'PHPCS_T_OBJECT');
|
53 |
+
define('T_CLOSE_OBJECT', 'PHPCS_T_CLOSE_OBJECT');
|
54 |
+
define('T_COLOUR', 'PHPCS_T_COLOUR');
|
55 |
+
define('T_HASH', 'PHPCS_T_HASH');
|
56 |
+
define('T_URL', 'PHPCS_T_URL');
|
57 |
+
define('T_STYLE', 'PHPCS_T_STYLE');
|
58 |
+
define('T_ASPERAND', 'PHPCS_T_ASPERAND');
|
59 |
+
define('T_DOLLAR', 'PHPCS_T_DOLLAR');
|
60 |
+
define('T_TYPEOF', 'PHPCS_T_TYPEOF');
|
61 |
+
define('T_CLOSURE', 'PHPCS_T_CLOSURE');
|
62 |
+
define('T_ANON_CLASS', 'PHPCS_T_ANON_CLASS');
|
63 |
+
define('T_BACKTICK', 'PHPCS_T_BACKTICK');
|
64 |
+
define('T_START_NOWDOC', 'PHPCS_T_START_NOWDOC');
|
65 |
+
define('T_NOWDOC', 'PHPCS_T_NOWDOC');
|
66 |
+
define('T_END_NOWDOC', 'PHPCS_T_END_NOWDOC');
|
67 |
+
define('T_OPEN_SHORT_ARRAY', 'PHPCS_T_OPEN_SHORT_ARRAY');
|
68 |
+
define('T_CLOSE_SHORT_ARRAY', 'PHPCS_T_CLOSE_SHORT_ARRAY');
|
69 |
+
define('T_GOTO_LABEL', 'PHPCS_T_GOTO_LABEL');
|
70 |
+
define('T_BINARY_CAST', 'PHPCS_T_BINARY_CAST');
|
71 |
+
define('T_EMBEDDED_PHP', 'PHPCS_T_EMBEDDED_PHP');
|
72 |
+
define('T_RETURN_TYPE', 'PHPCS_T_RETURN_TYPE');
|
73 |
+
define('T_OPEN_USE_GROUP', 'PHPCS_T_OPEN_USE_GROUP');
|
74 |
+
define('T_CLOSE_USE_GROUP', 'PHPCS_T_CLOSE_USE_GROUP');
|
75 |
+
define('T_ZSR', 'PHPCS_T_ZSR');
|
76 |
+
define('T_ZSR_EQUAL', 'PHPCS_T_ZSR_EQUAL');
|
77 |
+
|
78 |
+
// Some PHP 5.5 tokens, replicated for lower versions.
|
79 |
+
if (defined('T_FINALLY') === false) {
|
80 |
+
define('T_FINALLY', 'PHPCS_T_FINALLY');
|
81 |
+
}
|
82 |
+
|
83 |
+
if (defined('T_YIELD') === false) {
|
84 |
+
define('T_YIELD', 'PHPCS_T_YIELD');
|
85 |
+
}
|
86 |
+
|
87 |
+
// Some PHP 5.6 tokens, replicated for lower versions.
|
88 |
+
if (defined('T_ELLIPSIS') === false) {
|
89 |
+
define('T_ELLIPSIS', 'PHPCS_T_ELLIPSIS');
|
90 |
+
}
|
91 |
+
|
92 |
+
if (defined('T_POW') === false) {
|
93 |
+
define('T_POW', 'PHPCS_T_POW');
|
94 |
+
}
|
95 |
+
|
96 |
+
if (defined('T_POW_EQUAL') === false) {
|
97 |
+
define('T_POW_EQUAL', 'PHPCS_T_POW_EQUAL');
|
98 |
+
}
|
99 |
+
|
100 |
+
// Some PHP 7 tokens, replicated for lower versions.
|
101 |
+
if (defined('T_SPACESHIP') === false) {
|
102 |
+
define('T_SPACESHIP', 'PHPCS_T_SPACESHIP');
|
103 |
+
}
|
104 |
+
|
105 |
+
if (defined('T_COALESCE') === false) {
|
106 |
+
define('T_COALESCE', 'PHPCS_T_COALESCE');
|
107 |
+
}
|
108 |
+
|
109 |
+
if (defined('T_COALESCE_EQUAL') === false) {
|
110 |
+
define('T_COALESCE_EQUAL', 'PHPCS_T_COALESCE_EQUAL');
|
111 |
+
}
|
112 |
+
|
113 |
+
if (defined('T_YIELD_FROM') === false) {
|
114 |
+
define('T_YIELD_FROM', 'PHPCS_T_YIELD_FROM');
|
115 |
+
}
|
116 |
+
|
117 |
+
// Tokens used for parsing doc blocks.
|
118 |
+
define('T_DOC_COMMENT_STAR', 'PHPCS_T_DOC_COMMENT_STAR');
|
119 |
+
define('T_DOC_COMMENT_WHITESPACE', 'PHPCS_T_DOC_COMMENT_WHITESPACE');
|
120 |
+
define('T_DOC_COMMENT_TAG', 'PHPCS_T_DOC_COMMENT_TAG');
|
121 |
+
define('T_DOC_COMMENT_OPEN_TAG', 'PHPCS_T_DOC_COMMENT_OPEN_TAG');
|
122 |
+
define('T_DOC_COMMENT_CLOSE_TAG', 'PHPCS_T_DOC_COMMENT_CLOSE_TAG');
|
123 |
+
define('T_DOC_COMMENT_STRING', 'PHPCS_T_DOC_COMMENT_STRING');
|
124 |
+
|
125 |
+
// Tokens used for PHPCS instruction comments.
|
126 |
+
define('T_PHPCS_ENABLE', 'PHPCS_T_PHPCS_ENABLE');
|
127 |
+
define('T_PHPCS_DISABLE', 'PHPCS_T_PHPCS_DISABLE');
|
128 |
+
define('T_PHPCS_SET', 'PHPCS_T_PHPCS_SET');
|
129 |
+
define('T_PHPCS_IGNORE', 'PHPCS_T_PHPCS_IGNORE');
|
130 |
+
define('T_PHPCS_IGNORE_FILE', 'PHPCS_T_PHPCS_IGNORE_FILE');
|
131 |
+
|
132 |
+
final class Tokens
|
133 |
+
{
|
134 |
+
|
135 |
+
/**
|
136 |
+
* The token weightings.
|
137 |
+
*
|
138 |
+
* @var array<int, int>
|
139 |
+
*/
|
140 |
+
public static $weightings = [
|
141 |
+
T_CLASS => 1000,
|
142 |
+
T_INTERFACE => 1000,
|
143 |
+
T_TRAIT => 1000,
|
144 |
+
T_NAMESPACE => 1000,
|
145 |
+
T_FUNCTION => 100,
|
146 |
+
T_CLOSURE => 100,
|
147 |
+
|
148 |
+
/*
|
149 |
+
* Conditions.
|
150 |
+
*/
|
151 |
+
|
152 |
+
T_WHILE => 50,
|
153 |
+
T_FOR => 50,
|
154 |
+
T_FOREACH => 50,
|
155 |
+
T_IF => 50,
|
156 |
+
T_ELSE => 50,
|
157 |
+
T_ELSEIF => 50,
|
158 |
+
T_DO => 50,
|
159 |
+
T_TRY => 50,
|
160 |
+
T_CATCH => 50,
|
161 |
+
T_FINALLY => 50,
|
162 |
+
T_SWITCH => 50,
|
163 |
+
|
164 |
+
T_SELF => 25,
|
165 |
+
T_PARENT => 25,
|
166 |
+
|
167 |
+
/*
|
168 |
+
* Operators and arithmetic.
|
169 |
+
*/
|
170 |
+
|
171 |
+
T_BITWISE_AND => 8,
|
172 |
+
T_BITWISE_OR => 8,
|
173 |
+
T_BITWISE_XOR => 8,
|
174 |
+
|
175 |
+
T_MULTIPLY => 5,
|
176 |
+
T_DIVIDE => 5,
|
177 |
+
T_PLUS => 5,
|
178 |
+
T_MINUS => 5,
|
179 |
+
T_MODULUS => 5,
|
180 |
+
T_POW => 5,
|
181 |
+
T_SPACESHIP => 5,
|
182 |
+
T_COALESCE => 5,
|
183 |
+
T_COALESCE_EQUAL => 5,
|
184 |
+
|
185 |
+
T_SL => 5,
|
186 |
+
T_SR => 5,
|
187 |
+
T_SL_EQUAL => 5,
|
188 |
+
T_SR_EQUAL => 5,
|
189 |
+
|
190 |
+
T_EQUAL => 5,
|
191 |
+
T_AND_EQUAL => 5,
|
192 |
+
T_CONCAT_EQUAL => 5,
|
193 |
+
T_DIV_EQUAL => 5,
|
194 |
+
T_MINUS_EQUAL => 5,
|
195 |
+
T_MOD_EQUAL => 5,
|
196 |
+
T_MUL_EQUAL => 5,
|
197 |
+
T_OR_EQUAL => 5,
|
198 |
+
T_PLUS_EQUAL => 5,
|
199 |
+
T_XOR_EQUAL => 5,
|
200 |
+
|
201 |
+
T_BOOLEAN_AND => 5,
|
202 |
+
T_BOOLEAN_OR => 5,
|
203 |
+
|
204 |
+
/*
|
205 |
+
* Equality.
|
206 |
+
*/
|
207 |
+
|
208 |
+
T_IS_EQUAL => 5,
|
209 |
+
T_IS_NOT_EQUAL => 5,
|
210 |
+
T_IS_IDENTICAL => 5,
|
211 |
+
T_IS_NOT_IDENTICAL => 5,
|
212 |
+
T_IS_SMALLER_OR_EQUAL => 5,
|
213 |
+
T_IS_GREATER_OR_EQUAL => 5,
|
214 |
+
];
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Tokens that represent assignments.
|
218 |
+
*
|
219 |
+
* @var array<int, int>
|
220 |
+
*/
|
221 |
+
public static $assignmentTokens = [
|
222 |
+
T_EQUAL => T_EQUAL,
|
223 |
+
T_AND_EQUAL => T_AND_EQUAL,
|
224 |
+
T_OR_EQUAL => T_OR_EQUAL,
|
225 |
+
T_CONCAT_EQUAL => T_CONCAT_EQUAL,
|
226 |
+
T_DIV_EQUAL => T_DIV_EQUAL,
|
227 |
+
T_MINUS_EQUAL => T_MINUS_EQUAL,
|
228 |
+
T_POW_EQUAL => T_POW_EQUAL,
|
229 |
+
T_MOD_EQUAL => T_MOD_EQUAL,
|
230 |
+
T_MUL_EQUAL => T_MUL_EQUAL,
|
231 |
+
T_PLUS_EQUAL => T_PLUS_EQUAL,
|
232 |
+
T_XOR_EQUAL => T_XOR_EQUAL,
|
233 |
+
T_DOUBLE_ARROW => T_DOUBLE_ARROW,
|
234 |
+
T_SL_EQUAL => T_SL_EQUAL,
|
235 |
+
T_SR_EQUAL => T_SR_EQUAL,
|
236 |
+
T_COALESCE_EQUAL => T_COALESCE_EQUAL,
|
237 |
+
T_ZSR_EQUAL => T_ZSR_EQUAL,
|
238 |
+
];
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Tokens that represent equality comparisons.
|
242 |
+
*
|
243 |
+
* @var array<int, int>
|
244 |
+
*/
|
245 |
+
public static $equalityTokens = [
|
246 |
+
T_IS_EQUAL => T_IS_EQUAL,
|
247 |
+
T_IS_NOT_EQUAL => T_IS_NOT_EQUAL,
|
248 |
+
T_IS_IDENTICAL => T_IS_IDENTICAL,
|
249 |
+
T_IS_NOT_IDENTICAL => T_IS_NOT_IDENTICAL,
|
250 |
+
T_IS_SMALLER_OR_EQUAL => T_IS_SMALLER_OR_EQUAL,
|
251 |
+
T_IS_GREATER_OR_EQUAL => T_IS_GREATER_OR_EQUAL,
|
252 |
+
];
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Tokens that represent comparison operator.
|
256 |
+
*
|
257 |
+
* @var array<int, int>
|
258 |
+
*/
|
259 |
+
public static $comparisonTokens = [
|
260 |
+
T_IS_EQUAL => T_IS_EQUAL,
|
261 |
+
T_IS_IDENTICAL => T_IS_IDENTICAL,
|
262 |
+
T_IS_NOT_EQUAL => T_IS_NOT_EQUAL,
|
263 |
+
T_IS_NOT_IDENTICAL => T_IS_NOT_IDENTICAL,
|
264 |
+
T_LESS_THAN => T_LESS_THAN,
|
265 |
+
T_GREATER_THAN => T_GREATER_THAN,
|
266 |
+
T_IS_SMALLER_OR_EQUAL => T_IS_SMALLER_OR_EQUAL,
|
267 |
+
T_IS_GREATER_OR_EQUAL => T_IS_GREATER_OR_EQUAL,
|
268 |
+
T_SPACESHIP => T_SPACESHIP,
|
269 |
+
T_COALESCE => T_COALESCE,
|
270 |
+
];
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Tokens that represent arithmetic operators.
|
274 |
+
*
|
275 |
+
* @var array<int, int>
|
276 |
+
*/
|
277 |
+
public static $arithmeticTokens = [
|
278 |
+
T_PLUS => T_PLUS,
|
279 |
+
T_MINUS => T_MINUS,
|
280 |
+
T_MULTIPLY => T_MULTIPLY,
|
281 |
+
T_DIVIDE => T_DIVIDE,
|
282 |
+
T_MODULUS => T_MODULUS,
|
283 |
+
T_POW => T_POW,
|
284 |
+
];
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Tokens that perform operations.
|
288 |
+
*
|
289 |
+
* @var array<int, int>
|
290 |
+
*/
|
291 |
+
public static $operators = [
|
292 |
+
T_MINUS => T_MINUS,
|
293 |
+
T_PLUS => T_PLUS,
|
294 |
+
T_MULTIPLY => T_MULTIPLY,
|
295 |
+
T_DIVIDE => T_DIVIDE,
|
296 |
+
T_MODULUS => T_MODULUS,
|
297 |
+
T_POW => T_POW,
|
298 |
+
T_SPACESHIP => T_SPACESHIP,
|
299 |
+
T_COALESCE => T_COALESCE,
|
300 |
+
T_BITWISE_AND => T_BITWISE_AND,
|
301 |
+
T_BITWISE_OR => T_BITWISE_OR,
|
302 |
+
T_BITWISE_XOR => T_BITWISE_XOR,
|
303 |
+
T_SL => T_SL,
|
304 |
+
T_SR => T_SR,
|
305 |
+
];
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Tokens that perform boolean operations.
|
309 |
+
*
|
310 |
+
* @var array<int, int>
|
311 |
+
*/
|
312 |
+
public static $booleanOperators = [
|
313 |
+
T_BOOLEAN_AND => T_BOOLEAN_AND,
|
314 |
+
T_BOOLEAN_OR => T_BOOLEAN_OR,
|
315 |
+
T_LOGICAL_AND => T_LOGICAL_AND,
|
316 |
+
T_LOGICAL_OR => T_LOGICAL_OR,
|
317 |
+
T_LOGICAL_XOR => T_LOGICAL_XOR,
|
318 |
+
];
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Tokens that represent casting.
|
322 |
+
*
|
323 |
+
* @var array<int, int>
|
324 |
+
*/
|
325 |
+
public static $castTokens = [
|
326 |
+
T_INT_CAST => T_INT_CAST,
|
327 |
+
T_STRING_CAST => T_STRING_CAST,
|
328 |
+
T_DOUBLE_CAST => T_DOUBLE_CAST,
|
329 |
+
T_ARRAY_CAST => T_ARRAY_CAST,
|
330 |
+
T_BOOL_CAST => T_BOOL_CAST,
|
331 |
+
T_OBJECT_CAST => T_OBJECT_CAST,
|
332 |
+
T_UNSET_CAST => T_UNSET_CAST,
|
333 |
+
T_BINARY_CAST => T_BINARY_CAST,
|
334 |
+
];
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Token types that open parenthesis.
|
338 |
+
*
|
339 |
+
* @var array<int, int>
|
340 |
+
*/
|
341 |
+
public static $parenthesisOpeners = [
|
342 |
+
T_ARRAY => T_ARRAY,
|
343 |
+
T_FUNCTION => T_FUNCTION,
|
344 |
+
T_CLOSURE => T_CLOSURE,
|
345 |
+
T_WHILE => T_WHILE,
|
346 |
+
T_FOR => T_FOR,
|
347 |
+
T_FOREACH => T_FOREACH,
|
348 |
+
T_SWITCH => T_SWITCH,
|
349 |
+
T_IF => T_IF,
|
350 |
+
T_ELSEIF => T_ELSEIF,
|
351 |
+
T_CATCH => T_CATCH,
|
352 |
+
T_DECLARE => T_DECLARE,
|
353 |
+
];
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Tokens that are allowed to open scopes.
|
357 |
+
*
|
358 |
+
* @var array<int, int>
|
359 |
+
*/
|
360 |
+
public static $scopeOpeners = [
|
361 |
+
T_CLASS => T_CLASS,
|
362 |
+
T_ANON_CLASS => T_ANON_CLASS,
|
363 |
+
T_INTERFACE => T_INTERFACE,
|
364 |
+
T_TRAIT => T_TRAIT,
|
365 |
+
T_NAMESPACE => T_NAMESPACE,
|
366 |
+
T_FUNCTION => T_FUNCTION,
|
367 |
+
T_CLOSURE => T_CLOSURE,
|
368 |
+
T_IF => T_IF,
|
369 |
+
T_SWITCH => T_SWITCH,
|
370 |
+
T_CASE => T_CASE,
|
371 |
+
T_DECLARE => T_DECLARE,
|
372 |
+
T_DEFAULT => T_DEFAULT,
|
373 |
+
T_WHILE => T_WHILE,
|
374 |
+
T_ELSE => T_ELSE,
|
375 |
+
T_ELSEIF => T_ELSEIF,
|
376 |
+
T_FOR => T_FOR,
|
377 |
+
T_FOREACH => T_FOREACH,
|
378 |
+
T_DO => T_DO,
|
379 |
+
T_TRY => T_TRY,
|
380 |
+
T_CATCH => T_CATCH,
|
381 |
+
T_FINALLY => T_FINALLY,
|
382 |
+
T_PROPERTY => T_PROPERTY,
|
383 |
+
T_OBJECT => T_OBJECT,
|
384 |
+
T_USE => T_USE,
|
385 |
+
];
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Tokens that represent scope modifiers.
|
389 |
+
*
|
390 |
+
* @var array<int, int>
|
391 |
+
*/
|
392 |
+
public static $scopeModifiers = [
|
393 |
+
T_PRIVATE => T_PRIVATE,
|
394 |
+
T_PUBLIC => T_PUBLIC,
|
395 |
+
T_PROTECTED => T_PROTECTED,
|
396 |
+
];
|
397 |
+
|
398 |
+
/**
|
399 |
+
* Tokens that can prefix a method name
|
400 |
+
*
|
401 |
+
* @var array<int, int>
|
402 |
+
*/
|
403 |
+
public static $methodPrefixes = [
|
404 |
+
T_PRIVATE => T_PRIVATE,
|
405 |
+
T_PUBLIC => T_PUBLIC,
|
406 |
+
T_PROTECTED => T_PROTECTED,
|
407 |
+
T_ABSTRACT => T_ABSTRACT,
|
408 |
+
T_STATIC => T_STATIC,
|
409 |
+
T_FINAL => T_FINAL,
|
410 |
+
];
|
411 |
+
|
412 |
+
/**
|
413 |
+
* Tokens that open code blocks.
|
414 |
+
*
|
415 |
+
* @var array<int, int>
|
416 |
+
*/
|
417 |
+
public static $blockOpeners = [
|
418 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
419 |
+
T_OPEN_SQUARE_BRACKET => T_OPEN_SQUARE_BRACKET,
|
420 |
+
T_OPEN_PARENTHESIS => T_OPEN_PARENTHESIS,
|
421 |
+
T_OBJECT => T_OBJECT,
|
422 |
+
];
|
423 |
+
|
424 |
+
/**
|
425 |
+
* Tokens that don't represent code.
|
426 |
+
*
|
427 |
+
* @var array<int, int>
|
428 |
+
*/
|
429 |
+
public static $emptyTokens = [
|
430 |
+
T_WHITESPACE => T_WHITESPACE,
|
431 |
+
T_COMMENT => T_COMMENT,
|
432 |
+
T_DOC_COMMENT => T_DOC_COMMENT,
|
433 |
+
T_DOC_COMMENT_STAR => T_DOC_COMMENT_STAR,
|
434 |
+
T_DOC_COMMENT_WHITESPACE => T_DOC_COMMENT_WHITESPACE,
|
435 |
+
T_DOC_COMMENT_TAG => T_DOC_COMMENT_TAG,
|
436 |
+
T_DOC_COMMENT_OPEN_TAG => T_DOC_COMMENT_OPEN_TAG,
|
437 |
+
T_DOC_COMMENT_CLOSE_TAG => T_DOC_COMMENT_CLOSE_TAG,
|
438 |
+
T_DOC_COMMENT_STRING => T_DOC_COMMENT_STRING,
|
439 |
+
T_PHPCS_ENABLE => T_PHPCS_ENABLE,
|
440 |
+
T_PHPCS_DISABLE => T_PHPCS_DISABLE,
|
441 |
+
T_PHPCS_SET => T_PHPCS_SET,
|
442 |
+
T_PHPCS_IGNORE => T_PHPCS_IGNORE,
|
443 |
+
T_PHPCS_IGNORE_FILE => T_PHPCS_IGNORE_FILE,
|
444 |
+
];
|
445 |
+
|
446 |
+
/**
|
447 |
+
* Tokens that are comments.
|
448 |
+
*
|
449 |
+
* @var array<int, int>
|
450 |
+
*/
|
451 |
+
public static $commentTokens = [
|
452 |
+
T_COMMENT => T_COMMENT,
|
453 |
+
T_DOC_COMMENT => T_DOC_COMMENT,
|
454 |
+
T_DOC_COMMENT_STAR => T_DOC_COMMENT_STAR,
|
455 |
+
T_DOC_COMMENT_WHITESPACE => T_DOC_COMMENT_WHITESPACE,
|
456 |
+
T_DOC_COMMENT_TAG => T_DOC_COMMENT_TAG,
|
457 |
+
T_DOC_COMMENT_OPEN_TAG => T_DOC_COMMENT_OPEN_TAG,
|
458 |
+
T_DOC_COMMENT_CLOSE_TAG => T_DOC_COMMENT_CLOSE_TAG,
|
459 |
+
T_DOC_COMMENT_STRING => T_DOC_COMMENT_STRING,
|
460 |
+
T_PHPCS_ENABLE => T_PHPCS_ENABLE,
|
461 |
+
T_PHPCS_DISABLE => T_PHPCS_DISABLE,
|
462 |
+
T_PHPCS_SET => T_PHPCS_SET,
|
463 |
+
T_PHPCS_IGNORE => T_PHPCS_IGNORE,
|
464 |
+
T_PHPCS_IGNORE_FILE => T_PHPCS_IGNORE_FILE,
|
465 |
+
];
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Tokens that are comments containing PHPCS instructions.
|
469 |
+
*
|
470 |
+
* @var array<int, int>
|
471 |
+
*/
|
472 |
+
public static $phpcsCommentTokens = [
|
473 |
+
T_PHPCS_ENABLE => T_PHPCS_ENABLE,
|
474 |
+
T_PHPCS_DISABLE => T_PHPCS_DISABLE,
|
475 |
+
T_PHPCS_SET => T_PHPCS_SET,
|
476 |
+
T_PHPCS_IGNORE => T_PHPCS_IGNORE,
|
477 |
+
T_PHPCS_IGNORE_FILE => T_PHPCS_IGNORE_FILE,
|
478 |
+
];
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Tokens that represent strings.
|
482 |
+
*
|
483 |
+
* Note that T_STRINGS are NOT represented in this list.
|
484 |
+
*
|
485 |
+
* @var array<int, int>
|
486 |
+
*/
|
487 |
+
public static $stringTokens = [
|
488 |
+
T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING,
|
489 |
+
T_DOUBLE_QUOTED_STRING => T_DOUBLE_QUOTED_STRING,
|
490 |
+
];
|
491 |
+
|
492 |
+
/**
|
493 |
+
* Tokens that represent text strings.
|
494 |
+
*
|
495 |
+
* @var array<int, int>
|
496 |
+
*/
|
497 |
+
public static $textStringTokens = [
|
498 |
+
T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING,
|
499 |
+
T_DOUBLE_QUOTED_STRING => T_DOUBLE_QUOTED_STRING,
|
500 |
+
T_INLINE_HTML => T_INLINE_HTML,
|
501 |
+
T_HEREDOC => T_HEREDOC,
|
502 |
+
T_NOWDOC => T_NOWDOC,
|
503 |
+
];
|
504 |
+
|
505 |
+
/**
|
506 |
+
* Tokens that represent brackets and parenthesis.
|
507 |
+
*
|
508 |
+
* @var array<int, int>
|
509 |
+
*/
|
510 |
+
public static $bracketTokens = [
|
511 |
+
T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
|
512 |
+
T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
|
513 |
+
T_OPEN_SQUARE_BRACKET => T_OPEN_SQUARE_BRACKET,
|
514 |
+
T_CLOSE_SQUARE_BRACKET => T_CLOSE_SQUARE_BRACKET,
|
515 |
+
T_OPEN_PARENTHESIS => T_OPEN_PARENTHESIS,
|
516 |
+
T_CLOSE_PARENTHESIS => T_CLOSE_PARENTHESIS,
|
517 |
+
];
|
518 |
+
|
519 |
+
/**
|
520 |
+
* Tokens that include files.
|
521 |
+
*
|
522 |
+
* @var array<int, int>
|
523 |
+
*/
|
524 |
+
public static $includeTokens = [
|
525 |
+
T_REQUIRE_ONCE => T_REQUIRE_ONCE,
|
526 |
+
T_REQUIRE => T_REQUIRE,
|
527 |
+
T_INCLUDE_ONCE => T_INCLUDE_ONCE,
|
528 |
+
T_INCLUDE => T_INCLUDE,
|
529 |
+
];
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Tokens that make up a heredoc string.
|
533 |
+
*
|
534 |
+
* @var array<int, int>
|
535 |
+
*/
|
536 |
+
public static $heredocTokens = [
|
537 |
+
T_START_HEREDOC => T_START_HEREDOC,
|
538 |
+
T_END_HEREDOC => T_END_HEREDOC,
|
539 |
+
T_HEREDOC => T_HEREDOC,
|
540 |
+
T_START_NOWDOC => T_START_NOWDOC,
|
541 |
+
T_END_NOWDOC => T_END_NOWDOC,
|
542 |
+
T_NOWDOC => T_NOWDOC,
|
543 |
+
];
|
544 |
+
|
545 |
+
/**
|
546 |
+
* Tokens that represent the names of called functions.
|
547 |
+
*
|
548 |
+
* Mostly, these are just strings. But PHP tokenizes some language
|
549 |
+
* constructs and functions using their own tokens.
|
550 |
+
*
|
551 |
+
* @var array<int, int>
|
552 |
+
*/
|
553 |
+
public static $functionNameTokens = [
|
554 |
+
T_STRING => T_STRING,
|
555 |
+
T_EVAL => T_EVAL,
|
556 |
+
T_EXIT => T_EXIT,
|
557 |
+
T_INCLUDE => T_INCLUDE,
|
558 |
+
T_INCLUDE_ONCE => T_INCLUDE_ONCE,
|
559 |
+
T_REQUIRE => T_REQUIRE,
|
560 |
+
T_REQUIRE_ONCE => T_REQUIRE_ONCE,
|
561 |
+
T_ISSET => T_ISSET,
|
562 |
+
T_UNSET => T_UNSET,
|
563 |
+
T_EMPTY => T_EMPTY,
|
564 |
+
T_SELF => T_SELF,
|
565 |
+
T_STATIC => T_STATIC,
|
566 |
+
];
|
567 |
+
|
568 |
+
/**
|
569 |
+
* Tokens that open class and object scopes.
|
570 |
+
*
|
571 |
+
* @var array<int, int>
|
572 |
+
*/
|
573 |
+
public static $ooScopeTokens = [
|
574 |
+
T_CLASS => T_CLASS,
|
575 |
+
T_ANON_CLASS => T_ANON_CLASS,
|
576 |
+
T_INTERFACE => T_INTERFACE,
|
577 |
+
T_TRAIT => T_TRAIT,
|
578 |
+
];
|
579 |
+
|
580 |
+
|
581 |
+
/**
|
582 |
+
* Given a token, returns the name of the token.
|
583 |
+
*
|
584 |
+
* If passed an integer, the token name is sourced from PHP's token_name()
|
585 |
+
* function. If passed a string, it is assumed to be a PHPCS-supplied token
|
586 |
+
* that begins with PHPCS_T_, so the name is sourced from the token value itself.
|
587 |
+
*
|
588 |
+
* @param int|string $token The token to get the name for.
|
589 |
+
*
|
590 |
+
* @return string
|
591 |
+
*/
|
592 |
+
public static function tokenName($token)
|
593 |
+
{
|
594 |
+
if (is_string($token) === false) {
|
595 |
+
// PHP-supplied token name.
|
596 |
+
return token_name($token);
|
597 |
+
}
|
598 |
+
|
599 |
+
return substr($token, 6);
|
600 |
+
|
601 |
+
}//end tokenName()
|
602 |
+
|
603 |
+
|
604 |
+
/**
|
605 |
+
* Returns the highest weighted token type.
|
606 |
+
*
|
607 |
+
* Tokens are weighted by their approximate frequency of appearance in code
|
608 |
+
* - the less frequently they appear in the code, the higher the weighting.
|
609 |
+
* For example T_CLASS tokens appear very infrequently in a file, and
|
610 |
+
* therefore have a high weighting.
|
611 |
+
*
|
612 |
+
* Returns false if there are no weightings for any of the specified tokens.
|
613 |
+
*
|
614 |
+
* @param array<int, int> $tokens The token types to get the highest weighted
|
615 |
+
* type for.
|
616 |
+
*
|
617 |
+
* @return int The highest weighted token.
|
618 |
+
*/
|
619 |
+
public static function getHighestWeightedToken(array $tokens)
|
620 |
+
{
|
621 |
+
$highest = -1;
|
622 |
+
$highestType = false;
|
623 |
+
|
624 |
+
$weights = self::$weightings;
|
625 |
+
|
626 |
+
foreach ($tokens as $token) {
|
627 |
+
if (isset($weights[$token]) === true) {
|
628 |
+
$weight = $weights[$token];
|
629 |
+
} else {
|
630 |
+
$weight = 0;
|
631 |
+
}
|
632 |
+
|
633 |
+
if ($weight > $highest) {
|
634 |
+
$highest = $weight;
|
635 |
+
$highestType = $token;
|
636 |
+
}
|
637 |
+
}
|
638 |
+
|
639 |
+
return $highestType;
|
640 |
+
|
641 |
+
}//end getHighestWeightedToken()
|
642 |
+
|
643 |
+
|
644 |
+
}//end class
|
vendor/phpqrcode/qrvect.php
CHANGED
@@ -142,7 +142,7 @@
|
|
142 |
$vect = self::vectSVG($frame, $pixelPerPoint, $outerFrame, $back_color, $fore_color);
|
143 |
|
144 |
if ($filename === false) {
|
145 |
-
|
146 |
//header('Content-Disposition: attachment, filename="qrcode.svg"');
|
147 |
echo $vect;
|
148 |
} else {
|
142 |
$vect = self::vectSVG($frame, $pixelPerPoint, $outerFrame, $back_color, $fore_color);
|
143 |
|
144 |
if ($filename === false) {
|
145 |
+
//header("Content-Type: image/svg+xml");
|
146 |
//header('Content-Disposition: attachment, filename="qrcode.svg"');
|
147 |
echo $vect;
|
148 |
} else {
|
wp-defender.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Plugin Name: Defender
|
5 |
* Plugin URI: https://premium.wpmudev.org/project/wp-defender/
|
6 |
-
* Version: 2.1.
|
7 |
* Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
|
8 |
* Author: WPMU DEV
|
9 |
* Author URI: http://premium.wpmudev.org/
|
@@ -119,7 +119,7 @@ class WP_Defender_Free {
|
|
119 |
$this->global['bootstrap'] = new WD_Legacy_Activator( $this );
|
120 |
}
|
121 |
//for the new SUI
|
122 |
-
add_filter( 'admin_body_class', array( &$this, 'adminBodyClasses' ) );
|
123 |
do_action(
|
124 |
'wpmudev-recommended-plugins-register-notice',
|
125 |
plugin_basename( __FILE__ ), // Plugin basename
|
@@ -173,7 +173,7 @@ class WP_Defender_Free {
|
|
173 |
}
|
174 |
|
175 |
public function adminBodyClasses( $classes ) {
|
176 |
-
$classes .= ' sui-2-3-
|
177 |
|
178 |
return $classes;
|
179 |
}
|
3 |
/**
|
4 |
* Plugin Name: Defender
|
5 |
* Plugin URI: https://premium.wpmudev.org/project/wp-defender/
|
6 |
+
* Version: 2.1.4
|
7 |
* Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
|
8 |
* Author: WPMU DEV
|
9 |
* Author URI: http://premium.wpmudev.org/
|
119 |
$this->global['bootstrap'] = new WD_Legacy_Activator( $this );
|
120 |
}
|
121 |
//for the new SUI
|
122 |
+
add_filter( 'admin_body_class', array( &$this, 'adminBodyClasses' ), 20 );
|
123 |
do_action(
|
124 |
'wpmudev-recommended-plugins-register-notice',
|
125 |
plugin_basename( __FILE__ ), // Plugin basename
|
173 |
}
|
174 |
|
175 |
public function adminBodyClasses( $classes ) {
|
176 |
+
$classes .= ' sui-2-3-22 ';
|
177 |
|
178 |
return $classes;
|
179 |
}
|