| @@ -1,35 +1,150 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace BitCode\BitForm\Frontend; |
| 4 | 4 | |
| 5 | +use BitCode\BitForm\Core\Database\FormModel; | |
| 6 | +use BitCode\BitForm\Core\Form\FormManager; | |
| 5 | 7 | use BitCode\BitForm\Core\Util\Render; |
| 6 | 8 | use BitCode\BitForm\Frontend\Form\FrontendFormHandler; |
| 7 | 9 | |
| 8 | -class StandaloneFormView { | |
| 9 | - public static function preview() { | |
| 10 | - $requestUri = $_SERVER['REQUEST_URI']; | |
| 11 | - $uri = explode('/', $requestUri); | |
| 10 | +class StandaloneFormView | |
| 11 | +{ | |
| 12 | + public static function preview() | |
| 13 | + { | |
| 14 | + if (!(current_user_can('manage_options') || current_user_can('manage_bitform'))) { | |
| 15 | + auth_redirect(); | |
| 16 | + return; | |
| 17 | + } | |
| 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)) { | |
| 24 | + $attr = ['form_id' => $formID, 'form_preview' => true]; | |
| 12 | 25 | |
| 13 | - if (is_array($uri) && count($uri) > 0) { | |
| 14 | - $formID = $uri[count($uri) - 1]; | |
| 15 | - | |
| 16 | 26 | $frontendFormHandler = new FrontendFormHandler(); |
| 17 | - $formViewObject = $frontendFormHandler->handleFrontendRenderRequest($formID, true); | |
| 27 | + $formViewObject = $frontendFormHandler->handleFrontendRenderRequest($attr); | |
| 18 | 28 | if ('string' === gettype($formViewObject)) { |
| 19 | 29 | Render::view('views/form-not-found'); |
| 20 | 30 | exit; |
| 21 | 31 | } |
| 22 | - | |
| 23 | 32 | $formHTML = $formViewObject->html; |
| 24 | 33 | $font = $formViewObject->font; |
| 25 | 34 | $bfGlobals = $formViewObject->bfGlobals; |
| 35 | + $configTag = isset($formViewObject->configTag) ? $formViewObject->configTag : ''; | |
| 36 | + $formContent = isset($formViewObject->formContent) ? $formViewObject->formContent : null; | |
| 26 | 37 | |
| 27 | - if (defined('BITAPPS_DEV') && BITAPPS_DEV) { | |
| 28 | - set_transient('bitform_form_preview', true); | |
| 29 | - $frontendFormHandler->generateJs($formID); | |
| 30 | - $title = 'BitForm Preview page'; | |
| 31 | - Render::view('views/preview-page', compact('formID', 'title', 'formHTML', 'font', 'bfGlobals')); | |
| 38 | + set_transient('bitform_form_preview', true); | |
| 39 | + $frontendFormHandler->generateJs($formID); | |
| 40 | + $title = 'BitForm Preview page'; | |
| 41 | + Render::view('views/preview-page', compact('formID', 'title', 'formHTML', 'font', 'bfGlobals', 'configTag', 'formContent')); | |
| 42 | + } | |
| 43 | + } | |
| 44 | + | |
| 45 | + private static function getCustomUrlFormId() | |
| 46 | + { | |
| 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'])) : ''); | |
| 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; | |
| 32 | 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 | + } | |
| 33 | 75 | } |
| 76 | + | |
| 77 | + return null; | |
| 78 | + } | |
| 79 | + | |
| 80 | + private static function buildStandaloneUrlMap() | |
| 81 | + { | |
| 82 | + $formModel = new FormModel(); | |
| 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; | |
| 92 | + } | |
| 93 | + $standaloneSettings = $formContent->formInfo->standaloneSettings; | |
| 94 | + if (empty($standaloneSettings->customUrl)) { | |
| 95 | + continue; | |
| 96 | + } | |
| 97 | + $urlMap[$form->id] = $standaloneSettings->customUrl; | |
| 98 | + } | |
| 99 | + return $urlMap; | |
| 100 | + } | |
| 101 | + | |
| 102 | + public static function standaloneFormView() | |
| 103 | + { | |
| 104 | + if (is_admin()) { | |
| 105 | + return; | |
| 106 | + } | |
| 107 | + // Read-only: form ID from query string for standalone view dispatch. No state mutation. | |
| 108 | + $hasBitFormParam = isset($_GET['bit-form']); | |
| 109 | + $formID = isset($_GET['bit-form']) ? sanitize_text_field(wp_unslash($_GET['bit-form'])) : ''; | |
| 110 | + | |
| 111 | + if (empty($formID)) { | |
| 112 | + $formID = self::getCustomUrlFormId(); | |
| 113 | + } | |
| 114 | + | |
| 115 | + if (empty($formID)) { | |
| 116 | + return ''; | |
| 117 | + } | |
| 118 | + | |
| 119 | + $formID = intval($formID); | |
| 120 | + $attr = ['form_id' => $formID, 'form_preview' => true]; | |
| 121 | + | |
| 122 | + $FormManager = FormManager::getInstance($formID); | |
| 123 | + $formContent = $FormManager->getFormContent(); | |
| 124 | + if (empty($formContent->formInfo->standaloneSettings->active)) { | |
| 125 | + return; | |
| 126 | + } | |
| 127 | + | |
| 128 | + $standaloneSettings = $formContent->formInfo->standaloneSettings; | |
| 129 | + | |
| 130 | + $frontendFormHandler = new FrontendFormHandler(); | |
| 131 | + $formViewObject = $frontendFormHandler->handleFrontendRenderRequest($attr); | |
| 132 | + if ('string' === gettype($formViewObject)) { | |
| 133 | + Render::view('views/form-not-found'); | |
| 134 | + exit; | |
| 135 | + } | |
| 136 | + | |
| 137 | + $formHTML = $formViewObject->html; | |
| 138 | + $font = $formViewObject->font; | |
| 139 | + $bfGlobals = $formViewObject->bfGlobals; | |
| 140 | + $configTag = isset($formViewObject->configTag) ? $formViewObject->configTag : ''; | |
| 141 | + $formContent = isset($formViewObject->formContent) ? $formViewObject->formContent : null; | |
| 142 | + | |
| 143 | + set_transient('bitform_form_preview', true); | |
| 144 | + $frontendFormHandler->generateJs($formID); | |
| 145 | + $title = !empty($standaloneSettings->pageTitle) ? $standaloneSettings->pageTitle : 'Bit Form'; | |
| 146 | + Render::view('views/standalone-form', compact('formID', 'title', 'formHTML', 'font', 'bfGlobals', 'configTag', 'formContent')); | |
| 147 | + | |
| 148 | + exit(200); | |
| 34 | 149 | } |
| 35 | 150 | } |