[ 'class' => '', ], 'submit_button' => [ 'class' => 'btn btn-secondary', ], ]; public $submit_button_config = []; public $control_label_config = ['class' => 'col-sm-2']; public $input_config = ['class' => 'col-sm-3']; public $textarea_config = ['class' => 'col-sm-10']; public function __construct($form_name) { $this->form_name = $form_name; $this->succ_href = UOJContext::requestURI(); $this->handle = function (&$vdata) { }; $this->run_at_server_handler["check-{$this->form_name}"] = function () { die(json_encode($this->validateAtServer())); }; $this->run_at_server_handler["submit-{$this->form_name}"] = function () { if ($this->no_submit) { UOJResponse::page404(); } foreach ($this->data as $field) { if (!isset($field['no_val']) && !isset($_POST[$field['name']])) { UOJResponse::message('The form is incomplete.'); } } if (UOJContext::requestMethod() == 'POST') { $len = UOJContext::contentLength(); if ($len === null) { UOJResponse::page403(); } elseif ($len > $this->max_post_size) { UOJResponse::message('The form is too large.'); } } crsf_defend(); $errors = $this->validateAtServer(); if ($errors) { $err_str = ''; foreach ($errors as $name => $err) { $esc_err = htmlspecialchars($err); $err_str .= "$name: $esc_err
"; } UOJResponse::message($err_str); } $fun = $this->handle; $fun($this->vdata); if ($this->succ_href !== 'none') { redirectTo($this->succ_href); } die(); }; } public function setAjaxSubmit($js) { $GLOBALS['REQUIRE_LIB']['jquery.form'] = ''; $this->ajax_submit_js = $js; } public function add($name, $html, $validator_php, $validator_js) { $this->main_html .= $html; $this->data[] = array( 'name' => $name, 'validator_php' => $validator_php, 'validator_js' => $validator_js ); } public function appendHTML($html) { $this->main_html .= $html; } public function addNoVal($name, $html) { $this->main_html .= $html; $this->data[] = array( 'name' => $name, 'validator_js' => 'always_ok', 'no_val' => '' ); } public function addHidden($name, $default_value, $validator_php, $validator_js) { $default_value = HTML::escape($default_value); $html = << EOD; $this->add($name, $html, $validator_php, $validator_js); } public function printHTML() { $form_entype_str = $this->is_big ? ' enctype="multipart/form-data"' : ''; echo '
'; echo HTML::hiddenToken(); echo $this->main_html; if (!$this->no_submit) { if (!isset($this->submit_button_config['align'])) { $this->submit_button_config['align'] = 'center'; } if (!isset($this->submit_button_config['text'])) { $this->submit_button_config['text'] = UOJLocale::get('submit'); } if (!isset($this->submit_button_config['class_str'])) { $this->submit_button_config['class_str'] = 'btn btn-secondary'; } if ($this->submit_button_config['align'] == 'offset') { echo '
'; echo '
'; } else { echo '
'; } if ($this->back_href !== null) { echo '
'; } echo HTML::tag('button', [ 'type' => 'submit', 'id' => "button-submit-{$this->form_name}", 'name' => "submit-{$this->form_name}", 'value' => $this->form_name, 'class' => $this->submit_button_config['class_str'] ], $this->submit_button_config['text']); if ($this->back_href !== null) { echo HTML::tag('a', [ 'class' => 'btn btn-secondary', 'href' => $this->back_href ], '返回'); } if ($this->back_href !== null) { echo '
'; } if ($this->submit_button_config['align'] == 'offset') { echo '
'; } echo '
'; } echo ''; if ($this->no_submit) { return; } echo << $(document).ready(function() { EOD; if ($this->ctrl_enter_submit) { echo <<form_name}').keydown(function(e) { if (e.keyCode == 13 && e.ctrlKey) { $('#button-submit-{$this->form_name}').click(); } }); EOD; } echo <<form_name}').submit(function(e) { var ok = true; EOD; $need_ajax = false; if ($this->extra_validator) { $need_ajax = true; } foreach ($this->data as $field) { if ($field['validator_js'] != null) { if ($field['validator_js'] != 'always_ok') { echo <<data as $field) { if ($field['validator_js'] == null) { echo <<form_name}'] = ""; $.ajax({ url : '{$_SERVER['REQUEST_URI']}', type : 'POST', dataType : 'json', async : false, data : post_data, success : function(data) { EOD; foreach ($this->data as $field) { if ($field['validator_js'] == null) { echo <<data as $field) { if ($field['validator_js'] != 'always_ok') { echo <<submit_button_config['smart_confirm'])) { $this->submit_button_config['confirm_text'] = '你真的要' . $this->submit_button_config['text'] . '吗?'; } if (isset($this->submit_button_config['confirm_text'])) { echo <<submit_button_config['confirm_text']}')) { ok = false; } EOD; } if ($this->has_file) { echo << {$this->max_file_size_mb} * 1024 * 1024) { $('#div-' + $(this).attr('name')).addClass('has-validation has-error'); $('#div-' + $(this).attr('name')).addClass('is-invalid'); $('#input-' + $(this).attr('name')).addClass('is-invalid'); $('#help-' + $(this).attr('name')).text('文件大小不能超过{$this->max_file_size_mb}M'); ok = false; } else { $('#div-' + $(this).attr('name')).removeClass('has-validation has-error'); $('#div-' + $(this).attr('name')).removeClass('is-invalid'); $('#input-' + $(this).attr('name')).removeClass('is-invalid'); $('#help-' + $(this).attr('name')).text(''); } } }); EOD; } if ($this->ajax_submit_js !== null) { echo <<form_name}', value: '{$this->form_name}', type: 'submit'}); }, success : {$this->ajax_submit_js} }); } EOD; } else { echo << EOD; } private function validateAtServer() { $errors = array(); if ($this->extra_validator) { $fun = $this->extra_validator; $err = $fun(); if ($err) { $errors['extra'] = $err; } } foreach ($this->data as $field) { if (!isset($field['no_val']) && isset($_POST[$field['name']])) { $fun = $field['validator_php']; $ret = $fun($_POST[$field['name']], $this->vdata, $field['name']); if (is_array($ret) && isset($ret['error'])) { $err = $ret['error']; } else { $err = $ret; } if ($err) { $errors[$field['name']] = $err; } if (is_array($ret) && isset($ret['store'])) { $this->vdata[$field['name']] = $ret['store']; } } } return $errors; } public function runAtServer() { foreach ($this->run_at_server_handler as $type => $handler) { if (isset($_POST[$type])) { $handler(); } } } }