PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.0.2.5
Adminify – White Label, Admin Menu Editor, Login Customizer v4.0.2.5
4.3.1 4.3.0 4.2.26 4.2.25 4.2.24 4.2.23 4.2.22 4.2.21 4.2.20 4.2.19 4.2.18 4.2.17 4.2.16 4.2.15 4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.1.17 All 164 releases
← All changes | Inc/Admin/Frames/Init.php +25 -139 4.2.94.0.2.5 View file →
@@ -1,10 +1,8 @@
1 1 <?php
2 2
3 -namespace PXLBSAdminify\Inc\Admin\Frames;
3 +namespace WPAdminify\Inc\Admin\Frames;
4 4
5 -use PXLBSAdminify\Inc\Utils;
6 -
7 5 // no direct access allowed
8 6 if (!defined('ABSPATH')) {
9 7 exit;
10 8 }
@@ -33,19 +31,15 @@
33 31 public function __construct()
34 32 {
35 33
36 34 if ( ! $this->is_allowed() ) {
37 - if ( Utils::is_iframe() ) {
38 - $http_host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : '';
39 - $request_uri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : '';
40 - $scheme = empty($_SERVER['HTTPS']) ? 'http' : 'https';
41 - $actual_link = $scheme . '://' . $http_host . $request_uri;
42 - Frames::custom_plugin_change_reload($actual_link);
35 + if ( is_iframe() ) {
36 + Frames::custom_plugin_change_reload();
43 37 }
44 38 return;
45 39 }
46 40
47 - if ( Utils::is_iframe() ) {
41 + if ( is_iframe() ) {
48 42 $this->frame = new Frames();
49 43 } else {
50 44 $this->admin = new Admin();
51 45 }
@@ -51,136 +45,36 @@
51 45 }
52 46
53 47 }
54 48
55 - /**
56 - * Get the relative admin path without subdirectory prefix
57 - * Handles root, subdirectory, subdomain, and multisite installations
58 - *
59 - * @return string Normalized path (e.g., /wp-admin/edit.php)
60 - */
61 - private function get_normalized_admin_path() {
62 - $php_self = isset($_SERVER['PHP_SELF']) ? sanitize_text_field(wp_unslash($_SERVER['PHP_SELF'])) : '';
63 -
64 - // Method 1: Use WordPress native function to get subdirectory path
65 - // site_url() returns full URL including subdirectory
66 - // e.g., https://example.com/blog or https://example.com
67 - $site_url_path = wp_parse_url( site_url(), PHP_URL_PATH );
68 -
69 - // Remove subdirectory prefix if exists
70 - if ( ! empty( $site_url_path ) && $site_url_path !== '/' ) {
71 - // Ensure path starts with subdirectory
72 - if ( strpos( $php_self, $site_url_path ) === 0 ) {
73 - $php_self = substr( $php_self, strlen( $site_url_path ) );
74 - }
75 - }
76 -
77 - // Ensure path starts with /
78 - if ( empty( $php_self ) || $php_self[0] !== '/' ) {
79 - $php_self = '/' . $php_self;
80 - }
81 -
82 - return $php_self;
83 - }
84 -
85 - /**
86 - * Check if current path matches the blocked URL pattern
87 - * Supports exact match and ends-with matching for subdirectory compatibility
88 - *
89 - * @param string $blocked_url The URL pattern to check against
90 - * @return bool True if current path matches the blocked URL
91 - */
92 - private function matches_blocked_url( $blocked_url ) {
93 - $current_path = $this->get_normalized_admin_path();
94 -
95 - // Exact match (normalized)
96 - if ( $current_path === $blocked_url ) {
97 - return true;
98 - }
99 -
100 - // Fallback: ends-with check for edge cases
101 - // e.g., /wp-admin/customize.php should match even if normalization fails
102 - $php_self = isset($_SERVER['PHP_SELF']) ? sanitize_text_field(wp_unslash($_SERVER['PHP_SELF'])) : '';
103 - if ( $this->url_ends_with( $php_self, $blocked_url ) ) {
104 - return true;
105 - }
106 -
107 - return false;
108 - }
109 -
110 - /**
111 - * Check if a URL ends with a specific path
112 - * Useful for subdirectory WordPress installs
113 - *
114 - * @param string $url Full URL or path to check
115 - * @param string $ending The ending pattern to match
116 - * @return bool
117 - */
118 - private function url_ends_with( $url, $ending ) {
119 - $ending_length = strlen( $ending );
120 - if ( $ending_length === 0 ) {
121 - return true;
122 - }
123 - return substr( $url, -$ending_length ) === $ending;
124 - }
125 -
126 - /**
127 - * Get WordPress installation context for debugging
128 - *
129 - * @return array Installation details
130 - */
131 - public function get_install_context() {
132 - return [
133 - 'is_multisite' => is_multisite(),
134 - 'is_subdomain' => defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL,
135 - 'site_url' => site_url(),
136 - 'home_url' => home_url(),
137 - 'admin_url' => admin_url(),
138 - 'subdirectory' => wp_parse_url( site_url(), PHP_URL_PATH ) ?: '/',
139 - 'php_self' => isset($_SERVER['PHP_SELF']) ? sanitize_text_field(wp_unslash($_SERVER['PHP_SELF'])) : '',
140 - 'normalized_path' => $this->get_normalized_admin_path(),
141 - ];
142 - }
143 -
144 49 public function is_allowed() {
145 50
146 51 $not_allowed_urls = Admin::get_not_allowed_urls();
147 52
148 53 foreach ( $not_allowed_urls as $url_object ) {
54 +
149 55 if ( is_string( $url_object ) ) {
150 56
151 57 $is_allowed = true; // Scoped Default allowed
152 - // Use normalized path matching for subdirectory compatibility
153 - if ( $this->matches_blocked_url( $url_object ) ) {
154 - $is_allowed = false; // not allowed
155 - }
58 + if ( $url_object === $_SERVER['PHP_SELF'] ) $is_allowed = false; // not allowed
156 59
157 60 } else {
158 61
159 62 $is_allowed = false; // Scoped Default not allowed
160 63
161 - // Use normalized path matching for subdirectory compatibility
162 - if ( $url_object['url'] !== '*' && ! $this->matches_blocked_url( $url_object['url'] ) ) {
163 - $is_allowed = true; // allowed
164 - }
64 + if ( $url_object['url'] !== '*' && $url_object['url'] !== $_SERVER['PHP_SELF'] ) $is_allowed = true; // allowed
165 65
166 66 if ( ! $is_allowed && array_key_exists( 'query_params', $url_object ) ) {
167 - if ( ! $this->check_query_params( $url_object['query_params'] ) ) {
168 - $is_allowed = true; // allowed
169 - }
67 + if ( ! $this->check_query_params( $url_object['query_params'] ) ) $is_allowed = true; // allowed
170 68 }
171 69
172 70 if ( ! $is_allowed && array_key_exists( 'post_type', $url_object ) ) {
173 - if ( ! $this->check_post_type( $url_object['post_type'] ) ) {
174 - $is_allowed = true; // allowed
175 - }
71 + if ( ! $this->check_post_type( $url_object['post_type'] ) ) $is_allowed = true; // allowed
176 72 }
177 73
178 74 }
179 75
180 - if ( ! $is_allowed ) {
181 - return $is_allowed;
182 - }
76 + if ( ! $is_allowed ) return $is_allowed;
183 77
184 78 }
185 79
186 80 return true;
@@ -187,28 +81,17 @@
187 81
188 82 }
189 83
190 84 function check_query_params($query_params) {
191 - // Pattern 1: Both keys and their values should check in $_GET
192 - if (array_keys($query_params) === $query_params) {
193 - foreach ($query_params as $key => $value) {
194 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
195 - if (!isset($_GET[$key]) || sanitize_text_field(wp_unslash($_GET[$key])) != $value) {
196 - return false; // Key doesn't exist or the value doesn't match
197 - }
198 - }
199 - return true; // All keys and values match
200 - }
201 85
202 - // Pattern 2: Check for only keys in $_GET, no need to check their values
86 + // Pattern 1: Check for only keys in $_GET, no need to check their values
203 87 if (array_values($query_params) === $query_params) {
204 88 foreach ($query_params as $param) {
89 +
205 90 if ( substr($param, -1) === '!' ) {
206 91 $param = substr($param, 0, -1);
207 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
208 92 if ( isset($_GET[$param]) ) return false; // The key exists in $_GET
209 93 } else {
210 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
211 94 if ( ! isset($_GET[$param]) ) return false; // The key doesn't exist in $_GET
212 95 }
213 96
214 97 }
@@ -214,8 +97,18 @@
214 97 }
215 98 return true; // All keys exist
216 99 }
217 100
101 + // Pattern 2: Both keys and their values should check in $_GET
102 + if (array_keys($query_params) === $query_params) {
103 + foreach ($query_params as $key => $value) {
104 + if (!isset($_GET[$key]) || $_GET[$key] != $value) {
105 + return false; // Key doesn't exist or the value doesn't match
106 + }
107 + }
108 + return true; // All keys and values match
109 + }
110 +
218 111 // Pattern 3: A mix of key existence and key-value matching
219 112 foreach ($query_params as $key => $value) {
220 113 if (is_numeric($key)) {
221 114 // For numeric keys, we're checking only existence (Pattern 1 behavior)
@@ -220,18 +113,15 @@
220 113 if (is_numeric($key)) {
221 114 // For numeric keys, we're checking only existence (Pattern 1 behavior)
222 115 if ( substr($value, -1) === '!' ) {
223 116 $value = substr($value, 0, -1);
224 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
225 117 if ( isset($_GET[$value]) ) return false; // The key exists in $_GET
226 118 } else {
227 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
228 119 if ( ! isset($_GET[$value]) ) return false; // The key doesn't exist in $_GET
229 120 }
230 121 } else {
231 122 // For associative keys, we check for both key and value (Pattern 2 behavior)
232 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
233 - if (!isset($_GET[$key]) || sanitize_text_field(wp_unslash($_GET[$key])) != $value) {
123 + if (!isset($_GET[$key]) || $_GET[$key] != $value) {
234 124 return false; // Key doesn't exist or value doesn't match
235 125 }
236 126 }
237 127 }
@@ -239,16 +129,12 @@
239 129 return true; // All conditions are met
240 130 }
241 131
242 132 function check_post_type($post_types) {
243 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
244 133 if ( isset( $_GET['post_type'] ) ) {
245 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
246 - return in_array( sanitize_text_field( wp_unslash( $_GET['post_type'] ) ), $post_types );
247 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
134 + return in_array( $_GET['post_type'], $post_types );
248 135 } else if ( isset( $_GET['post'] ) ) {
249 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
250 - return in_array( get_post_type( absint( wp_unslash( $_GET['post'] ) ) ), $post_types );
136 + return in_array( get_post_type( $_GET['post'] ), $post_types );
251 137 }
252 138 return in_array( 'post', $post_types );
253 139 }
254 140