| @@ -1262,8 +1262,29 @@ | ||
| 1262 | 1262 | global $wp_version; |
| 1263 | 1263 | return version_compare( $wp_version, $version, $operator ); |
| 1264 | 1264 | } |
| 1265 | 1265 | |
| 1266 | + /** | |
| 1267 | + * Shared guard for features that only work below WordPress 7.1. | |
| 1268 | + * | |
| 1269 | + * 7.1 rewrote the block editor chrome and absorbed features Adminify used to | |
| 1270 | + * provide, so several settings became either inert or actively harmful there. | |
| 1271 | + * Rather than repeat the version literal at each of them, they all gate on this | |
| 1272 | + * one call, so the boundary moves in a single place. | |
| 1273 | + * | |
| 1274 | + * Features behind this guard: | |
| 1275 | + * - `gutenberg_editor_logo`: painted over `.edit-post-fullscreen-mode-close`, | |
| 1276 | + * a class the rebuilt icon-only close button no longer carries. | |
| 1277 | + * - `media_attachments.media_ininite_scroll`: the Media Library grid scrolls | |
| 1278 | + * infinitely by default from 7.1, with a per-user opt-out. Forcing the | |
| 1279 | + * `media_library_infinite_scrolling` filter overrides that preference. | |
| 1280 | + * | |
| 1281 | + * @return bool True on WordPress older than 7.1. | |
| 1282 | + */ | |
| 1283 | + public static function is_wp_below_7_1() { | |
| 1284 | + return self::check_wp_version( '<', '7.1' ); | |
| 1285 | + } | |
| 1286 | + | |
| 1266 | 1287 | public static function help_urls($module_name = '', $docs = '', $youtube = '', $facebook_grp = '', $support = '') |
| 1267 | 1288 | { |
| 1268 | 1289 | $help_content = ''; |
| 1269 | 1290 | |
| @@ -1312,8 +1333,79 @@ | ||
| 1312 | 1333 | // $isIframe = isset($_SERVER["HTTP_SEC_FETCH_DEST"]) && strtolower($_SERVER["HTTP_SEC_FETCH_DEST"]) === "iframe"; |
| 1313 | 1334 | // if ( $isIframe ) return true; |
| 1314 | 1335 | // if ( isset($_GET['adminify-iframe']) ) return true; |
| 1315 | 1336 | // return false; |
| 1337 | + } | |
| 1338 | + | |
| 1339 | + /** | |
| 1340 | + * Whether the request carries Fetch Metadata headers at all. | |
| 1341 | + * | |
| 1342 | + * `Sec-Fetch-*` is attached by the browser below the Service Worker layer, so | |
| 1343 | + * installs served through a Service Worker - WordPress Playground, offline | |
| 1344 | + * setups - never pass it to PHP. Older browsers do not send it either. When it | |
| 1345 | + * is missing, is_iframe() cannot tell an iframe request from a top-level one | |
| 1346 | + * and the client has to settle it instead. | |
| 1347 | + * | |
| 1348 | + * @return bool | |
| 1349 | + */ | |
| 1350 | + public static function has_fetch_metadata() | |
| 1351 | + { | |
| 1352 | + return isset( $_SERVER['HTTP_SEC_FETCH_DEST'] ) | |
| 1353 | + || isset( $_SERVER['HTTP_SEC_FETCH_MODE'] ) | |
| 1354 | + || isset( $_SERVER['HTTP_SEC_FETCH_SITE'] ); | |
| 1355 | + } | |
| 1356 | + | |
| 1357 | + /** | |
| 1358 | + * Whether this is a plain GET request. | |
| 1359 | + * | |
| 1360 | + * @return bool | |
| 1361 | + */ | |
| 1362 | + public static function is_get_request() | |
| 1363 | + { | |
| 1364 | + $method = isset( $_SERVER['REQUEST_METHOD'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) ) : 'GET'; | |
| 1365 | + | |
| 1366 | + return 'GET' === $method || 'HEAD' === $method; | |
| 1367 | + } | |
| 1368 | + | |
| 1369 | + /** | |
| 1370 | + * Whether the current request renders a full admin page. | |
| 1371 | + * | |
| 1372 | + * Endpoints like async-upload.php run through wp-admin/admin.php (so `admin_init` | |
| 1373 | + * fires) but answer with a raw payload - an attachment ID, JSON, an HTML fragment. | |
| 1374 | + * Printing the Admin UI frame into those responses corrupts them: the media uploader | |
| 1375 | + * on media-new.php reads the response as an attachment ID and gives up when it is not | |
| 1376 | + * numeric. `wp_doing_ajax()` does not catch these: async-upload.php only defines | |
| 1377 | + * DOING_AJAX for the `upload-attachment` action, which media-new.php does not send. | |
| 1378 | + * | |
| 1379 | + * @return bool | |
| 1380 | + */ | |
| 1381 | + public static function is_admin_page_request() | |
| 1382 | + { | |
| 1383 | + if ( wp_doing_ajax() || wp_doing_cron() || wp_is_json_request() ) { | |
| 1384 | + return false; | |
| 1385 | + } | |
| 1386 | + | |
| 1387 | + if ( ( defined('REST_REQUEST') && REST_REQUEST ) || ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) || ( defined('WP_CLI') && WP_CLI ) ) { | |
| 1388 | + return false; | |
| 1389 | + } | |
| 1390 | + | |
| 1391 | + $pagenow = isset($GLOBALS['pagenow']) ? $GLOBALS['pagenow'] : ''; | |
| 1392 | + | |
| 1393 | + if ( empty($pagenow) && isset($_SERVER['PHP_SELF']) ) { | |
| 1394 | + $pagenow = basename( sanitize_text_field( wp_unslash($_SERVER['PHP_SELF']) ) ); | |
| 1395 | + } | |
| 1396 | + | |
| 1397 | + $raw_response_endpoints = [ | |
| 1398 | + 'admin-ajax.php', | |
| 1399 | + 'admin-post.php', | |
| 1400 | + 'async-upload.php', | |
| 1401 | + 'load-scripts.php', | |
| 1402 | + 'load-styles.php', | |
| 1403 | + 'ms-files.php', | |
| 1404 | + 'wp-cron.php', | |
| 1405 | + ]; | |
| 1406 | + | |
| 1407 | + return ! in_array( $pagenow, $raw_response_endpoints, true ); | |
| 1316 | 1408 | } |
| 1317 | 1409 | |
| 1318 | 1410 | /** |
| 1319 | 1411 | * Load a template file. |