| @@ -10,17 +10,18 @@ | ||
| 10 | 10 | class StandaloneFormView |
| 11 | 11 | { |
| 12 | 12 | public static function preview() |
| 13 | 13 | { |
| 14 | - if (!current_user_can('manage_options')) { | |
| 14 | + if (!(current_user_can('manage_options') || current_user_can('manage_bitform'))) { | |
| 15 | 15 | auth_redirect(); |
| 16 | 16 | return; |
| 17 | 17 | } |
| 18 | - $requestUri = $_SERVER['REQUEST_URI']; | |
| 19 | - $uri = explode('/', $requestUri); | |
| 20 | - | |
| 21 | - if (is_array($uri) && count($uri) > 0) { | |
| 22 | - $formID = $uri[count($uri) - 1]; | |
| 18 | + // $requestUri = isset($_SERVER['REQUEST_URI']) ? wp_unslash($_SERVER['REQUEST_URI']) : ''; | |
| 19 | + // ('Request URI: ' . $requestUri); | |
| 20 | + // $uri = explode('/', rtrim($requestUri, '/')); | |
| 21 | + // Read-only: form ID from query string for view dispatch. No state mutation. | |
| 22 | + $formID = isset($_REQUEST['bitform-form-view']) && is_scalar($_REQUEST['bitform-form-view']) ? intval(sanitize_text_field(wp_unslash($_REQUEST['bitform-form-view']))) : null; | |
| 23 | + if (!is_array($formID) && is_numeric($formID)) { | |
| 23 | 24 | $attr = ['form_id' => $formID, 'form_preview' => true]; |
| 24 | 25 | |
| 25 | 26 | $frontendFormHandler = new FrontendFormHandler(); |
| 26 | 27 | $formViewObject = $frontendFormHandler->handleFrontendRenderRequest($attr); |
| @@ -30,60 +31,83 @@ | ||
| 30 | 31 | } |
| 31 | 32 | $formHTML = $formViewObject->html; |
| 32 | 33 | $font = $formViewObject->font; |
| 33 | 34 | $bfGlobals = $formViewObject->bfGlobals; |
| 35 | + $configTag = isset($formViewObject->configTag) ? $formViewObject->configTag : ''; | |
| 36 | + $formContent = isset($formViewObject->formContent) ? $formViewObject->formContent : null; | |
| 34 | 37 | |
| 35 | 38 | set_transient('bitform_form_preview', true); |
| 36 | 39 | $frontendFormHandler->generateJs($formID); |
| 37 | 40 | $title = 'BitForm Preview page'; |
| 38 | - Render::view('views/preview-page', compact('formID', 'title', 'formHTML', 'font', 'bfGlobals')); | |
| 41 | + Render::view('views/preview-page', compact('formID', 'title', 'formHTML', 'font', 'bfGlobals', 'configTag', 'formContent')); | |
| 39 | 42 | } |
| 40 | 43 | } |
| 41 | 44 | |
| 42 | 45 | private static function getCustomUrlFormId() |
| 43 | 46 | { |
| 44 | - $currentUrl = get_site_url() . $_SERVER['REQUEST_URI']; | |
| 47 | + $urlMap = get_transient('bitform_standalone_url_map'); | |
| 48 | + if (false === $urlMap) { | |
| 49 | + $urlMap = self::buildStandaloneUrlMap(); | |
| 50 | + set_transient('bitform_standalone_url_map', $urlMap, DAY_IN_SECONDS); | |
| 51 | + } | |
| 52 | + | |
| 53 | + if (empty($urlMap)) { | |
| 54 | + return null; | |
| 55 | + } | |
| 56 | + | |
| 57 | + $currentUrl = get_site_url() . (isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : ''); | |
| 45 | 58 | $parsedCurrentUrl = wp_parse_url($currentUrl); |
| 59 | + | |
| 60 | + foreach ($urlMap as $formID => $customUrlSlug) { | |
| 61 | + $customUrl = get_site_url() . '/' . $customUrlSlug; | |
| 62 | + $parsedCustomUrl = wp_parse_url($customUrl); | |
| 63 | + $pathMatched = isset($parsedCustomUrl['path']) && $parsedCustomUrl['path'] === ($parsedCurrentUrl['path'] ?? ''); | |
| 64 | + if (!$pathMatched) { | |
| 65 | + continue; | |
| 66 | + } | |
| 67 | + if (!isset($parsedCustomUrl['query'])) { | |
| 68 | + return $formID; | |
| 69 | + } | |
| 70 | + parse_str($parsedCustomUrl['query'], $parsedCustomQueries); | |
| 71 | + parse_str($parsedCurrentUrl['query'] ?? '', $parsedCurrentQueries); | |
| 72 | + if (empty(array_diff_assoc($parsedCustomQueries, $parsedCurrentQueries))) { | |
| 73 | + return $formID; | |
| 74 | + } | |
| 75 | + } | |
| 76 | + | |
| 77 | + return null; | |
| 78 | + } | |
| 79 | + | |
| 80 | + private static function buildStandaloneUrlMap() | |
| 81 | + { | |
| 46 | 82 | $formModel = new FormModel(); |
| 47 | - $forms = $formModel->get( | |
| 48 | - ['id', 'form_content'] | |
| 49 | - ); | |
| 50 | - | |
| 51 | - if (!is_wp_error($forms)) { | |
| 52 | - foreach ($forms as $form) { | |
| 53 | - $formID = $form->id; | |
| 54 | - $formContent = json_decode($form->form_content); | |
| 55 | - $isStandaloneActive = !empty($formContent->formInfo->standaloneSettings->active); | |
| 56 | - if ($isStandaloneActive) { | |
| 57 | - $standaloneSettings = $formContent->formInfo->standaloneSettings; | |
| 58 | - $hasCustomUrl = !empty($standaloneSettings->customUrl); | |
| 59 | - if (!$hasCustomUrl) { | |
| 60 | - continue; | |
| 61 | - } | |
| 62 | - $customUrl = get_site_url() . '/' . $standaloneSettings->customUrl; | |
| 63 | - $parsedCustomUrl = wp_parse_url($customUrl); | |
| 64 | - $pathMatched = $parsedCustomUrl['path'] === $parsedCurrentUrl['path']; | |
| 65 | - if (!$pathMatched) { | |
| 66 | - continue; | |
| 67 | - } | |
| 68 | - if (!isset($parsedCustomUrl['query'])) { | |
| 69 | - return $formID; | |
| 70 | - } | |
| 71 | - parse_str($parsedCustomUrl['query'], $parsedCustomQueries); | |
| 72 | - parse_str($parsedCurrentUrl['query'], $parsedCurrentQueries); | |
| 73 | - $diff = array_diff_assoc($parsedCustomQueries, $parsedCurrentQueries); | |
| 74 | - if (empty($diff)) { | |
| 75 | - return $formID; | |
| 76 | - } | |
| 77 | - } | |
| 83 | + $forms = $formModel->get(['id', 'form_content']); | |
| 84 | + $urlMap = []; | |
| 85 | + if (is_wp_error($forms) || !is_array($forms)) { | |
| 86 | + return $urlMap; | |
| 87 | + } | |
| 88 | + foreach ($forms as $form) { | |
| 89 | + $formContent = json_decode($form->form_content); | |
| 90 | + if (empty($formContent->formInfo->standaloneSettings->active)) { | |
| 91 | + continue; | |
| 78 | 92 | } |
| 93 | + $standaloneSettings = $formContent->formInfo->standaloneSettings; | |
| 94 | + if (empty($standaloneSettings->customUrl)) { | |
| 95 | + continue; | |
| 96 | + } | |
| 97 | + $urlMap[$form->id] = $standaloneSettings->customUrl; | |
| 79 | 98 | } |
| 99 | + return $urlMap; | |
| 80 | 100 | } |
| 81 | 101 | |
| 82 | 102 | public static function standaloneFormView() |
| 83 | 103 | { |
| 104 | + if (is_admin()) { | |
| 105 | + return; | |
| 106 | + } | |
| 107 | + // Read-only: form ID from query string for standalone view dispatch. No state mutation. | |
| 84 | 108 | $hasBitFormParam = isset($_GET['bit-form']); |
| 85 | - $formID = isset($_GET['bit-form']) ? $_GET['bit-form'] : ''; | |
| 109 | + $formID = isset($_GET['bit-form']) ? sanitize_text_field(wp_unslash($_GET['bit-form'])) : ''; | |
| 86 | 110 | |
| 87 | 111 | if (empty($formID)) { |
| 88 | 112 | $formID = self::getCustomUrlFormId(); |
| 89 | 113 | } |
| @@ -94,9 +118,9 @@ | ||
| 94 | 118 | |
| 95 | 119 | $formID = intval($formID); |
| 96 | 120 | $attr = ['form_id' => $formID, 'form_preview' => true]; |
| 97 | 121 | |
| 98 | - $FormManager = new FormManager($formID); | |
| 122 | + $FormManager = FormManager::getInstance($formID); | |
| 99 | 123 | $formContent = $FormManager->getFormContent(); |
| 100 | 124 | if (empty($formContent->formInfo->standaloneSettings->active)) { |
| 101 | 125 | return; |
| 102 | 126 | } |
| @@ -112,13 +136,15 @@ | ||
| 112 | 136 | |
| 113 | 137 | $formHTML = $formViewObject->html; |
| 114 | 138 | $font = $formViewObject->font; |
| 115 | 139 | $bfGlobals = $formViewObject->bfGlobals; |
| 140 | + $configTag = isset($formViewObject->configTag) ? $formViewObject->configTag : ''; | |
| 141 | + $formContent = isset($formViewObject->formContent) ? $formViewObject->formContent : null; | |
| 116 | 142 | |
| 117 | 143 | set_transient('bitform_form_preview', true); |
| 118 | 144 | $frontendFormHandler->generateJs($formID); |
| 119 | 145 | $title = !empty($standaloneSettings->pageTitle) ? $standaloneSettings->pageTitle : 'Bit Form'; |
| 120 | - Render::view('views/standalone-form', compact('formID', 'title', 'formHTML', 'font', 'bfGlobals')); | |
| 146 | + Render::view('views/standalone-form', compact('formID', 'title', 'formHTML', 'font', 'bfGlobals', 'configTag', 'formContent')); | |
| 121 | 147 | |
| 122 | 148 | exit(200); |
| 123 | 149 | } |
| 124 | 150 | } |