PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.1.3
Adminify – White Label, Admin Menu Editor, Login Customizer v4.1.3
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
adminify / Inc / Admin / Frames / Init.php

Init.php in Adminify – White Label, Admin Menu Editor, Login Customizer 4.1.3, at Inc/Admin/Frames/Init.php

242 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPAdminify\Inc\Admin\Frames;
4
5 // no direct access allowed
6 if (!defined('ABSPATH')) {
7 exit;
8 }
9 /**
10 * WP Adminify
11 * Init Class
12 *
13 * @author Jewel Theme <support@jeweltheme.com>
14 */
15
16 if (!class_exists('Init')) {
17 class Init
18 {
19 public static $instance;
20 public $admin;
21 public $frame;
22
23 public static function instance()
24 {
25 if (is_null(self::$instance)) {
26 self::$instance = new self();
27 }
28 return self::$instance;
29 }
30
31 public function __construct()
32 {
33
34 if ( ! $this->is_allowed() ) {
35 if ( is_iframe() ) {
36 $actual_link = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
37 Frames::custom_plugin_change_reload($actual_link);
38 }
39 return;
40 }
41
42 if ( is_iframe() ) {
43 $this->frame = new Frames();
44 } else {
45 $this->admin = new Admin();
46 }
47
48 }
49
50 /**
51 * Get the relative admin path without subdirectory prefix
52 * Handles root, subdirectory, subdomain, and multisite installations
53 *
54 * @return string Normalized path (e.g., /wp-admin/edit.php)
55 */
56 private function get_normalized_admin_path() {
57 $php_self = $_SERVER['PHP_SELF'] ?? '';
58
59 // Method 1: Use WordPress native function to get subdirectory path
60 // site_url() returns full URL including subdirectory
61 // e.g., https://example.com/blog or https://example.com
62 $site_url_path = wp_parse_url( site_url(), PHP_URL_PATH );
63
64 // Remove subdirectory prefix if exists
65 if ( ! empty( $site_url_path ) && $site_url_path !== '/' ) {
66 // Ensure path starts with subdirectory
67 if ( strpos( $php_self, $site_url_path ) === 0 ) {
68 $php_self = substr( $php_self, strlen( $site_url_path ) );
69 }
70 }
71
72 // Ensure path starts with /
73 if ( empty( $php_self ) || $php_self[0] !== '/' ) {
74 $php_self = '/' . $php_self;
75 }
76
77 return $php_self;
78 }
79
80 /**
81 * Check if current path matches the blocked URL pattern
82 * Supports exact match and ends-with matching for subdirectory compatibility
83 *
84 * @param string $blocked_url The URL pattern to check against
85 * @return bool True if current path matches the blocked URL
86 */
87 private function matches_blocked_url( $blocked_url ) {
88 $current_path = $this->get_normalized_admin_path();
89
90 // Exact match (normalized)
91 if ( $current_path === $blocked_url ) {
92 return true;
93 }
94
95 // Fallback: ends-with check for edge cases
96 // e.g., /wp-admin/customize.php should match even if normalization fails
97 if ( $this->url_ends_with( $_SERVER['PHP_SELF'] ?? '', $blocked_url ) ) {
98 return true;
99 }
100
101 return false;
102 }
103
104 /**
105 * Check if a URL ends with a specific path
106 * Useful for subdirectory WordPress installs
107 *
108 * @param string $url Full URL or path to check
109 * @param string $ending The ending pattern to match
110 * @return bool
111 */
112 private function url_ends_with( $url, $ending ) {
113 $ending_length = strlen( $ending );
114 if ( $ending_length === 0 ) {
115 return true;
116 }
117 return substr( $url, -$ending_length ) === $ending;
118 }
119
120 /**
121 * Get WordPress installation context for debugging
122 *
123 * @return array Installation details
124 */
125 public function get_install_context() {
126 return [
127 'is_multisite' => is_multisite(),
128 'is_subdomain' => defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL,
129 'site_url' => site_url(),
130 'home_url' => home_url(),
131 'admin_url' => admin_url(),
132 'subdirectory' => wp_parse_url( site_url(), PHP_URL_PATH ) ?: '/',
133 'php_self' => $_SERVER['PHP_SELF'] ?? '',
134 'normalized_path' => $this->get_normalized_admin_path(),
135 ];
136 }
137
138 public function is_allowed() {
139
140 $not_allowed_urls = Admin::get_not_allowed_urls();
141
142 foreach ( $not_allowed_urls as $url_object ) {
143 if ( is_string( $url_object ) ) {
144
145 $is_allowed = true; // Scoped Default allowed
146 // Use normalized path matching for subdirectory compatibility
147 if ( $this->matches_blocked_url( $url_object ) ) {
148 $is_allowed = false; // not allowed
149 }
150
151 } else {
152
153 $is_allowed = false; // Scoped Default not allowed
154
155 // Use normalized path matching for subdirectory compatibility
156 if ( $url_object['url'] !== '*' && ! $this->matches_blocked_url( $url_object['url'] ) ) {
157 $is_allowed = true; // allowed
158 }
159
160 if ( ! $is_allowed && array_key_exists( 'query_params', $url_object ) ) {
161 if ( ! $this->check_query_params( $url_object['query_params'] ) ) {
162 $is_allowed = true; // allowed
163 }
164 }
165
166 if ( ! $is_allowed && array_key_exists( 'post_type', $url_object ) ) {
167 if ( ! $this->check_post_type( $url_object['post_type'] ) ) {
168 $is_allowed = true; // allowed
169 }
170 }
171
172 }
173
174 if ( ! $is_allowed ) {
175 return $is_allowed;
176 }
177
178 }
179
180 return true;
181
182 }
183
184 function check_query_params($query_params) {
185 // Pattern 1: Both keys and their values should check in $_GET
186 if (array_keys($query_params) === $query_params) {
187 foreach ($query_params as $key => $value) {
188 if (!isset($_GET[$key]) || $_GET[$key] != $value) {
189 return false; // Key doesn't exist or the value doesn't match
190 }
191 }
192 return true; // All keys and values match
193 }
194
195 // Pattern 2: Check for only keys in $_GET, no need to check their values
196 if (array_values($query_params) === $query_params) {
197 foreach ($query_params as $param) {
198 if ( substr($param, -1) === '!' ) {
199 $param = substr($param, 0, -1);
200 if ( isset($_GET[$param]) ) return false; // The key exists in $_GET
201 } else {
202 if ( ! isset($_GET[$param]) ) return false; // The key doesn't exist in $_GET
203 }
204
205 }
206 return true; // All keys exist
207 }
208
209 // Pattern 3: A mix of key existence and key-value matching
210 foreach ($query_params as $key => $value) {
211 if (is_numeric($key)) {
212 // For numeric keys, we're checking only existence (Pattern 1 behavior)
213 if ( substr($value, -1) === '!' ) {
214 $value = substr($value, 0, -1);
215 if ( isset($_GET[$value]) ) return false; // The key exists in $_GET
216 } else {
217 if ( ! isset($_GET[$value]) ) return false; // The key doesn't exist in $_GET
218 }
219 } else {
220 // For associative keys, we check for both key and value (Pattern 2 behavior)
221 if (!isset($_GET[$key]) || $_GET[$key] != $value) {
222 return false; // Key doesn't exist or value doesn't match
223 }
224 }
225 }
226
227 return true; // All conditions are met
228 }
229
230 function check_post_type($post_types) {
231 if ( isset( $_GET['post_type'] ) ) {
232 return in_array( $_GET['post_type'], $post_types );
233 } else if ( isset( $_GET['post'] ) ) {
234 return in_array( get_post_type( $_GET['post'] ), $post_types );
235 }
236 return in_array( 'post', $post_types );
237 }
238
239 }
240
241 }
242