00001 <?php
00002 Load::models('formvalidations');
00003
00004
00005
00006
00007
00008
00009
00010 class FormHandler {
00011
00012
00013
00014 const TOKEN_POLICY_UNIQUE = 1;
00015
00016
00017
00018 const TOKEN_POLICY_NONE = 0;
00019
00020
00021
00022 const TOKEN_POLICY_REUSE = 2;
00023
00024
00025
00026
00027
00028
00029 const TOKEN_POLICY_REUSE_ACROSS_REQUESTS = 3;
00030
00031
00032
00033
00034 private $name = '';
00035
00036
00037
00038
00039 private $url = null;
00040
00041
00042
00043
00044 private $token_policy = true;
00045
00046
00047
00048
00049
00050
00051
00052
00053 public function __construct($name, $path = '', $token_policy = self::TOKEN_POLICY_UNIQUE) {
00054
00055 if ($token_policy === false) {
00056 $token_policy = self::TOKEN_POLICY_NONE;
00057 }
00058 else if ($token_policy === true) {
00059 $token_policy = self::TOKEN_POLICY_UNIQUE;
00060 }
00061
00062 $this->name = $name;
00063 $this->token_policy = $token_policy;
00064 $this->url = Url::current();
00065 if (!empty($path)) {
00066 $this->url->set_path($path);
00067 }
00068 }
00069
00070
00071
00072
00073
00074
00075
00076 public function prepare_view($view, $data = false) {
00077 $token = $this->create_token();
00078
00079 $token_html = '';
00080 if ($token) {
00081 $token_html .= html::input('hidden', Config::get_value(Config::FORMVALIDATION_FIELD_NAME), array('value' => $token));
00082 $token_html .= html::input('hidden', Config::get_value(Config::FORMVALIDATION_HANDLER_NAME), array('value' => $this->name));
00083
00084 }
00085 $view->assign('form_validation', $token_html);
00086
00087 if (!empty($data)) {
00088 $this->set_form_data_on_view((array)$data,$view);
00089 }
00090
00091 $form_data = $this->restore_post_data();
00092 $this->set_form_data_on_view($form_data, $view);
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 private function set_form_data_on_view($form_data, $view) {
00104 $form_data_clean = Arr::force($view->retrieve('form_data'), false);
00105 if (is_array($form_data)) {
00106 foreach($form_data as $key => $value) {
00107 if ($key != Config::get_value(Config::FORMVALIDATION_FIELD_NAME) && $key != Config::get_value(Config::FORMVALIDATION_HANDLER_NAME)) {
00108 $form_data_clean[$key] = $value;
00109 }
00110 }
00111 }
00112 $view->assign('form_data', $form_data_clean);
00113 }
00114
00115
00116
00117
00118 private function create_token() {
00119 $token = '';
00120 switch($this->token_policy) {
00121 case self::TOKEN_POLICY_NONE:
00122 break;
00123 case self::TOKEN_POLICY_REUSE:
00124 $token = FormValidations::create_or_reuse_token($this->name);
00125 break;
00126 case self::TOKEN_POLICY_REUSE_ACROSS_REQUESTS:
00127 $token = FormValidations::create_or_reuse_token_across_requests($this->name);
00128 break;
00129 default:
00130 $token = FormValidations::create_token($this->name);
00131 break;
00132 }
00133
00134 return $token;
00135 }
00136
00137
00138
00139
00140
00141
00142 public function validate($data = false) {
00143 if ($data === false) {
00144 $data = $_POST;
00145 }
00146 $ret = new Status();
00147 $success = true;
00148 if ($this->token_policy != self::TOKEN_POLICY_NONE) {
00149 $token = Arr::get_item($data, Config::get_value(Config::FORMVALIDATION_FIELD_NAME), '');
00150
00151 $success = $success && ($this->name == Arr::get_item($data, Config::get_value(Config::FORMVALIDATION_HANDLER_NAME), ''));
00152 $success = $success && FormValidations::validate_token($this->name, $token);
00153 }
00154 if ($success == false) {
00155 $ret->append(tr('Form verification token is too old. Please try again.', 'core'));
00156 }
00157 return $ret;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 public function finish($status, $success_message = '') {
00167 $params = array(
00168 'name' => $this->name,
00169 'status' => $status
00170 );
00171 EventSource::Instance()->invoke_event_no_result('form_finished', $params);
00172
00173 if ($status->is_error()) {
00174 $this->error($status);
00175 }
00176 else {
00177 $msg = ($status->is_empty()) ? $success_message : $status->to_string(Status::OUTPUT_PLAIN);
00178 $this->success($msg);
00179 }
00180 }
00181
00182
00183
00184
00185
00186
00187 public function success($message) {
00188 History::go_to(0, $message);
00189 exit;
00190 }
00191
00192
00193
00194
00195
00196
00197 public function error($status) {
00198 if (!($status instanceof Status)) {
00199 $status = new Status($status);
00200 }
00201 $this->fix_post_history($status);
00202 exit;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 public function fix_post_history($status = null) {
00214 $this->store_post_data();
00215 if ($status) {
00216 $status->persist();
00217 }
00218 $this->url->redirect();
00219 exit;
00220 }
00221
00222
00223
00224
00225 private function store_post_data() {
00226 Session::push('form_data', $_POST);
00227 }
00228
00229
00230
00231
00232 private function restore_post_data() {
00233 return Session::pull('form_data');
00234 }
00235 }
00236