| @@ -43,11 +43,17 @@ | ||
| 43 | 43 | do_action("ws_plugin__s2member_before_css", get_defined_vars()); |
| 44 | 44 | |
| 45 | 45 | if(!empty($_GET["ws_plugin__s2member_css"])) |
| 46 | 46 | { |
| 47 | + //260912.0522 A page-local WordPress fallback can carry the signed activation miss that caused recovery, avoiding a separate report request. | |
| 48 | + //260912.0522 This carrier is compatibility-only for already-cached first-v260909 pages; the current monitor reports Late assets without injecting fallback assets. | |
| 49 | + c_ws_plugin__s2member_utils_assets::record_asset_runtime_recovery_suspicion(); | |
| 50 | + | |
| 47 | 51 | status_header(200); // 200 OK status header. |
| 48 | 52 | |
| 49 | 53 | header("Content-Type: text/css; charset=UTF-8"); |
| 54 | + //260904.2255 Expose which dynamic loader produced this response for diagnostics. | |
| 55 | + header("X-s2Member-Loader: ".((defined('_WS_PLUGIN__S2MEMBER_ONLY')) ? "s2member-o" : "wordpress")); //260910.0724 Keep that diagnostic identity aligned with the actual endpoint: `s2member-o` maps to s2member-o.php and `wordpress` means the full WordPress route. | |
| 50 | 56 | header("Expires: ".gmdate("D, d M Y H:i:s", strtotime("+1 week"))." GMT"); |
| 51 | 57 | header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); |
| 52 | 58 | header("Cache-Control: max-age=604800"); |
| 53 | 59 | header("Pragma: public"); |
| @@ -56,14 +62,17 @@ | ||
| 56 | 62 | |
| 57 | 63 | $u = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]; |
| 58 | 64 | $i = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]."/src/images"; |
| 59 | 65 | |
| 60 | - ob_start("c_ws_plugin__s2member_utils_css::compress_css"); | |
| 66 | + ob_start("c_ws_plugin__s2member_utils_assets::compress_css"); | |
| 61 | 67 | |
| 62 | 68 | include_once dirname(dirname(__FILE__))."/s2member.css"; |
| 63 | 69 | |
| 64 | 70 | do_action("ws_plugin__s2member_during_css", get_defined_vars()); |
| 65 | 71 | |
| 72 | + //260912.0522 Append the activation-tag snippet after successful dynamic CSS so real pages can confirm that the expected styles became active. | |
| 73 | + echo c_ws_plugin__s2member_utils_assets::dynamic_activation_tag_snippet('css'); | |
| 74 | + | |
| 66 | 75 | exit(); // Clean exit. |
| 67 | 76 | } |
| 68 | 77 | do_action("ws_plugin__s2member_after_css", get_defined_vars()); |
| 69 | 78 | } |
| @@ -85,11 +94,17 @@ | ||
| 85 | 94 | do_action("ws_plugin__s2member_before_js_w_globals", get_defined_vars()); |
| 86 | 95 | |
| 87 | 96 | if(!empty($_GET["ws_plugin__s2member_js_w_globals"])) |
| 88 | 97 | { |
| 98 | + //260912.0522 A page-local WordPress fallback can carry the signed activation miss that caused recovery, avoiding a separate report request. | |
| 99 | + //260912.0522 This carrier is compatibility-only for already-cached first-v260909 pages; the current monitor reports Late assets without injecting fallback assets. | |
| 100 | + c_ws_plugin__s2member_utils_assets::record_asset_runtime_recovery_suspicion(); | |
| 101 | + | |
| 89 | 102 | status_header(200); // 200 OK status header. |
| 90 | 103 | |
| 91 | 104 | header("Content-Type: application/x-javascript; charset=UTF-8"); |
| 105 | + //260904.2255 Expose which dynamic loader produced this response for diagnostics. | |
| 106 | + header("X-s2Member-Loader: ".((defined('_WS_PLUGIN__S2MEMBER_ONLY')) ? "s2member-o" : "wordpress")); //260910.0724 Keep that diagnostic identity aligned with the actual endpoint: `s2member-o` maps to s2member-o.php and `wordpress` means the full WordPress route. | |
| 92 | 107 | header("Expires: ".gmdate("D, d M Y H:i:s", strtotime("+1 week"))." GMT"); |
| 93 | 108 | header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); |
| 94 | 109 | header("Cache-Control: max-age=604800"); |
| 95 | 110 | header("Pragma: public"); |
| @@ -185,23 +200,11 @@ | ||
| 185 | 200 | |
| 186 | 201 | echo "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON1 = '".c_ws_plugin__s2member_utils_strings::esc_js_sq(S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON1)."',"; |
| 187 | 202 | echo "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS1 = '".c_ws_plugin__s2member_utils_strings::esc_js_sq(S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS1)."';"; |
| 188 | 203 | |
| 189 | - } else { // Expose only what is needed by the s2Member application itself; for the current user. | |
| 190 | - echo "var S2MEMBER_CURRENT_USER_IS_LOGGED_IN = ".((S2MEMBER_CURRENT_USER_IS_LOGGED_IN) ? "true" : "false").","; | |
| 191 | - echo "S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER = ".((S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER) ? "true" : "false").","; | |
| 204 | + } else // Expose only what is needed by the s2Member application itself; for the current user. | |
| 205 | + echo self::current_user_js_globals(); | |
| 192 | 206 | |
| 193 | - echo "S2MEMBER_CURRENT_USER_FIRST_NAME = '".c_ws_plugin__s2member_utils_strings::esc_js_sq(S2MEMBER_CURRENT_USER_FIRST_NAME)."',"; | |
| 194 | - echo "S2MEMBER_CURRENT_USER_LAST_NAME = '".c_ws_plugin__s2member_utils_strings::esc_js_sq(S2MEMBER_CURRENT_USER_LAST_NAME)."',"; | |
| 195 | - | |
| 196 | - echo "S2MEMBER_CURRENT_USER_LOGIN = '".c_ws_plugin__s2member_utils_strings::esc_js_sq(S2MEMBER_CURRENT_USER_LOGIN)."',"; | |
| 197 | - echo "S2MEMBER_CURRENT_USER_EMAIL = '".c_ws_plugin__s2member_utils_strings::esc_js_sq(S2MEMBER_CURRENT_USER_EMAIL)."',"; | |
| 198 | - | |
| 199 | - echo "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED = ".S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED.","; | |
| 200 | - echo "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED = ".((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? "true" : "false").","; | |
| 201 | - echo "S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY = ".S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY.","; | |
| 202 | - echo "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS = ".S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS.";"; | |
| 203 | - } | |
| 204 | 207 | $u = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]; |
| 205 | 208 | $i = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]."/src/images"; |
| 206 | 209 | |
| 207 | 210 | echo "\n"; // Add a line break before inclusion. |
| @@ -208,10 +211,83 @@ | ||
| 208 | 211 | include_once dirname(dirname(__FILE__))."/s2member.min.js"; |
| 209 | 212 | |
| 210 | 213 | do_action("ws_plugin__s2member_during_js_w_globals", get_defined_vars()); |
| 211 | 214 | |
| 215 | + //260912.0522 Append the activation-tag snippet after successful dynamic JavaScript so real pages can confirm that the expected script became active. | |
| 216 | + echo c_ws_plugin__s2member_utils_assets::dynamic_activation_tag_snippet('js'); | |
| 217 | + | |
| 212 | 218 | exit(); // Clean exit. |
| 213 | 219 | } |
| 214 | 220 | do_action("ws_plugin__s2member_after_js_w_globals", get_defined_vars()); |
| 221 | + } | |
| 222 | + | |
| 223 | + /** | |
| 224 | + * Returns the current-user JavaScript globals required by s2Member's frontend application. | |
| 225 | + * | |
| 226 | + * @package s2Member\CSS_JS | |
| 227 | + * @since 260903.0437 | |
| 228 | + * | |
| 229 | + * @param bool $for_inline Escape HTML-closing sequences for safe inline-script output. | |
| 230 | + * @return string JavaScript variable declarations. | |
| 231 | + */ | |
| 232 | + public static function current_user_js_globals($for_inline = FALSE) | |
| 233 | + { | |
| 234 | + $required_constants = array( | |
| 235 | + 'S2MEMBER_CURRENT_USER_IS_LOGGED_IN', 'S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER', 'S2MEMBER_CURRENT_USER_FIRST_NAME', 'S2MEMBER_CURRENT_USER_LAST_NAME', | |
| 236 | + 'S2MEMBER_CURRENT_USER_LOGIN', 'S2MEMBER_CURRENT_USER_EMAIL', 'S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED', 'S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED', | |
| 237 | + 'S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY', 'S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS', | |
| 238 | + ); | |
| 239 | + $constants_ready = TRUE; | |
| 240 | + foreach($required_constants as $constant) | |
| 241 | + if(!defined($constant)) | |
| 242 | + { | |
| 243 | + $constants_ready = FALSE; | |
| 244 | + break; | |
| 245 | + } | |
| 246 | + | |
| 247 | + if($constants_ready) | |
| 248 | + { | |
| 249 | + $is_logged_in = (bool)S2MEMBER_CURRENT_USER_IS_LOGGED_IN; | |
| 250 | + $is_member = (bool)S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER; | |
| 251 | + $first_name = (string)S2MEMBER_CURRENT_USER_FIRST_NAME; | |
| 252 | + $last_name = (string)S2MEMBER_CURRENT_USER_LAST_NAME; | |
| 253 | + $login = (string)S2MEMBER_CURRENT_USER_LOGIN; | |
| 254 | + $email = (string)S2MEMBER_CURRENT_USER_EMAIL; | |
| 255 | + $downloads_allowed = (int)S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED; | |
| 256 | + $downloads_unlimited = (bool)S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED; | |
| 257 | + $downloads_currently = (int)S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY; | |
| 258 | + $downloads_allowed_days = (int)S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS; | |
| 259 | + } | |
| 260 | + else | |
| 261 | + { | |
| 262 | + //260913.0036 Another plugin may print login-page scripts before s2Member's normal init-priority constants setup; derive only the values this inline JavaScript needs without changing initialization order. | |
| 263 | + $user = (is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID)) ? $user : FALSE; | |
| 264 | + $level = c_ws_plugin__s2member_user_access::user_access_level($user); | |
| 265 | + $downloads = c_ws_plugin__s2member_files::user_downloads($user); | |
| 266 | + $is_logged_in = (bool)$user; | |
| 267 | + $is_member = (bool)($user && $level >= 1); | |
| 268 | + $first_name = ($user) ? (string)$user->first_name : ''; | |
| 269 | + $last_name = ($user) ? (string)$user->last_name : ''; | |
| 270 | + $login = ($user) ? (string)$user->user_login : ''; | |
| 271 | + $email = ($user) ? (string)$user->user_email : ''; | |
| 272 | + $downloads_allowed = (!empty($downloads['allowed'])) ? (int)$downloads['allowed'] : 0; | |
| 273 | + $downloads_unlimited = $downloads_allowed >= 999999999; | |
| 274 | + $downloads_currently = (!empty($downloads['currently'])) ? (int)$downloads['currently'] : 0; | |
| 275 | + $downloads_allowed_days = (!empty($downloads['allowed_days'])) ? (int)$downloads['allowed_days'] : 0; | |
| 276 | + } | |
| 277 | + | |
| 278 | + $g = "var S2MEMBER_CURRENT_USER_IS_LOGGED_IN = ".(($is_logged_in) ? "true" : "false").","; | |
| 279 | + $g .= "S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER = ".(($is_member) ? "true" : "false").","; | |
| 280 | + $g .= "S2MEMBER_CURRENT_USER_FIRST_NAME = '".c_ws_plugin__s2member_utils_strings::esc_js_sq($first_name)."',"; | |
| 281 | + $g .= "S2MEMBER_CURRENT_USER_LAST_NAME = '".c_ws_plugin__s2member_utils_strings::esc_js_sq($last_name)."',"; | |
| 282 | + $g .= "S2MEMBER_CURRENT_USER_LOGIN = '".c_ws_plugin__s2member_utils_strings::esc_js_sq($login)."',"; | |
| 283 | + $g .= "S2MEMBER_CURRENT_USER_EMAIL = '".c_ws_plugin__s2member_utils_strings::esc_js_sq($email)."',"; | |
| 284 | + $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED = ".$downloads_allowed.","; | |
| 285 | + $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED = ".(($downloads_unlimited) ? "true" : "false").","; | |
| 286 | + $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY = ".$downloads_currently.","; | |
| 287 | + $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS = ".$downloads_allowed_days.";"; | |
| 288 | + | |
| 289 | + //260903.0437 Inline data is HTML, not an external JS response; neutralize any user-controlled closing-script sequence before WordPress prints it. | |
| 290 | + return ($for_inline) ? str_ireplace('</', '<\/', $g) : $g; | |
| 215 | 291 | } |
| 216 | 292 | } |
| 217 | 293 | } |