00001 <?php
00016 class XFormsInputProcessor extends SObject {
00017
00018 protected $parent;
00019 protected $namePrefix = "shodor_xforms_";
00020 protected $validator;
00021 protected $selectCount;
00022
00032 public function __construct ($parent) {
00033 $this->parent = $parent;
00034 $this->validator = new StandardValidator();
00035 }
00036
00037
00038
00039
00040
00041
00042
00071 public function processInput ( $xform ) {
00072 $this->selectCount = array();
00073 if (SConfig::getOption('xforms.pictcha') === true) {
00074
00075 $p = new Pictcha();
00076 if (!($p->getValidPictcha($_POST['series_a'], $_POST['pictcha_a'],
00077 $_POST['series_b'], $_POST['pictcha_b']))) {
00078 $this->parent->setErrorCode("pictcha", 114);
00079 }
00080 }
00081
00082 if ($this->parent->getOption('token')) {
00083
00084 if (!isset($_POST['xformtoken'])
00085 || $_POST['xformtoken'] != sha1(session_id() . 'hasdfhv894h3gpvub')) {
00086 $this->parent->setErrorCode("token", 135);
00087 }
00088 }
00089
00090
00091 $traversedXML = $this->traverseXml($xform->model->instance);
00092 $this->parent->setModel("<xforms> <model><instance>" . $traversedXML
00093 . "</instance></model> </xforms>");
00094
00095
00096 return (count($this->parent->getErrorCount()) == 0);
00097 }
00098
00118 protected function traverseXml ($model) {
00119 $returnString = "";
00120 $tagsDone = array();
00121
00122 foreach($model->children() as $tag=>$child) {
00123 if (!in_array($tag, $tagsDone)) {
00124 array_push($tagsDone, $tag);
00125
00126
00127 $index = $this->namePrefix . $tag;
00128 $tagItemCount = $this->parent->getItemCount($tag);
00129
00130
00131 $required = $this->isRequired($child);
00132
00133
00134 if ($tagItemCount == 1) {
00135 if (isset($_POST[$index]) && !isset($_FILES[$index])) {
00136 $returnString .= $this->createDefaultXML($child, $index, $tag);
00137 } elseif(isset($_FILES[$index])) {
00138 $returnString .= $this->createFileXML($child, $index, $tag);
00139 }
00140
00141 elseif(isset($_POST[$index . "_0"])) {
00142 $returnString .= "<$tag>";
00143 $returnString .= $this->checkSetInput($child, $index . "_0", $tag);
00144 $returnString .= "</$tag>";
00145 }
00146 else {
00147
00148 if ($required)
00149 { $this->parent->setErrorCode($tag, 90); }
00150 }
00151
00152
00153 } else {
00154 if ($tagItemCount > 1) {
00155 $anyItemSet = false;
00156 for ( $i = 0; $i < $tagItemCount; $i++ ) {
00157 $numberedIndex = $index . "_" . $i;
00158 if (isset($_POST[$numberedIndex])) {
00159 $returnString .= "<$tag>";
00160 $returnString .= $this->checkSetInput($child, $numberedIndex, $tag);
00161 $returnString .= "</$tag>";
00162 $anyItemSet = true;
00163 }
00164 }
00165
00166 if ($required && !$anyItemSet){
00167 $this->parent->setErrorCode($tag, 90);
00168 }
00169
00170 if (!$anyItemSet){
00171 $returnString .= "<$tag />";
00172 }
00173 }
00174 }
00175
00176
00177 if (count($child->children()) > 0) {
00178 $temp = $this->traverseXml($child);
00179 if ($temp != "") { $returnString .= "<$tag>" . $temp . "</$tag>"; }
00180 }
00181 }
00182 }
00183 return $returnString;
00184 }
00185
00203 protected function checkSetInput ($child, $index, $tag) {
00204
00205
00206
00207
00208 # get the expected type of the node
00209 $type = $this->resolveType($child);
00210
00211 # is the element required by the model?
00212 $required = $this->isRequired($child);
00213
00214 $errorCode = 0;
00215 $input = "";
00216
00217
00218
00219
00220
00221 # set error codes based on whether the field is filled in /
00222 # filled in wrong / required, etc.
00223
00224
00225
00226
00227
00228 # We first check to see if there is a file upload
00229 # if a file is expected and the files array for that ref is set
00230 if(isset($_FILES[$index])) {
00231 # get the temp name of the file and the mime type
00232 $input = $_FILES[$index]['tmp_name'];
00233 $mime = $_FILES[$index]['type'];
00234 if ($mime == '') {
00235 $mime = 'text/plain';
00236 }
00237 # validate the file input
00238 $errorCode = $this->validateFile($input, $type, $mime);
00239 }
00240
00241
00242
00243
00244
00245 # Next we check to see if the POST array has an index for our ref
00246 # if it does have the index set, we process the input
00247 else if (isset($_POST[$index]) && $_POST[$index] != "") {
00248
00249 # relay the post index into the var $input
00250 $input = $_POST[$index];
00251
00252 # if the type is not XMl, clean the entites out
00253 if ($type != "xml" && $type != "mixedxml"){
00254 $input = XFormsFunctions::contentToXML($input);
00255 }
00256
00257 # the textlist type treats values on newlines as separate value instances (like a
00258 # multiple select). We want to create an XML tag to wrap each individual value from each
00259 # line.
00260 if ($type == 'textlist') {
00261 $input = trim($input);
00262 $input = str_replace('
00263 ', '\n', $input);
00264 # Split the lines into an array
00265 $lines = explode('\n', $input);
00266 $linesOut = array();
00267 # Trim each line, and if it's not blank, add it to the output lines
00268 foreach($lines as $l) {
00269 $l = trim($l);
00270 if ($l != '')
00271 $linesOut []= $l;
00272 }
00273 # Implode the output lines to make new tags for each line
00274 # (fit inside the enclosing outside lines)
00275 $input = implode("</$tag><$tag>", $linesOut);
00276 }
00277
00278 # set an error code if the validateInput function
00279 # returns an error for our input given its type
00280 $errorCode = $this->validateInput($input, $type);
00281
00282 # if the POST array does not have our index set, and if that
00283 # index (ref) is required in the XForm, then throw the
00284 # "required input" error code 90
00285 } else {
00286 $errorCode = ($required) ? 90 : 0;
00287 }
00288
00289
00290
00291
00292
00293 # evaluate the error codes - if there is no error,
00294 # return the input content to be placed in the XML model
00295 if ($errorCode == 0) {
00296 # no error - return the input
00297 return $input;
00298
00299 # if there IS and error, don't return the content,
00300 # and set an error code on the node.
00301 } else {
00302 # error - set error code
00303 $this->parent->setErrorCode($tag, $errorCode);
00304 }
00305 }
00306
00315 protected function getGlobArray($index) {
00316 if(isset($_POST[$index])) {
00317 $globArray = 'post';
00318 } elseif(isset($_FILES[$index])) {
00319 $globArray = 'files';
00320 } else {
00321 return false;
00322 }
00323 return $globArray;
00324 }
00325
00340 protected function createDefaultXML($child, $index, $tag) {
00341 $returnString = "<$tag>";
00342 $returnString .= $this->checkSetInput($child, $index, $tag);
00343 $returnString .= "</$tag>";
00344 return $returnString;
00345 }
00346
00358 protected function createFileXML($child, $index, $tag) {
00359 $mediaType = $_FILES[$index]['type'];
00360 $name = $this->fixExtension($_FILES[$index]['name'], $mediaType);
00361 $size = $_FILES[$index]['size'];
00362 $returnString = <<<END_OUTPUT
00363 <$tag filename="$name" mediatype="$mediaType" size="$size">
00364 END_OUTPUT;
00365 $returnString .= $this->checkSetInput($child, $index, $tag);
00366 $returnString .= "</$tag>";
00367 return $returnString;
00368 }
00369
00381 protected function resolveType ( $child ) {
00382 return (isset($child['type'])) ? $child['type'] : "";
00383 }
00384
00396 protected function validateInput ( $input, $type ) {
00397 return $this->validator->validateInput($input, $type);
00398 }
00399
00412 protected function validateFile ($input, $type, $mime) {
00413 return $this->validator->validateFile($input, $type, $mime);
00414 }
00415
00426 protected function fixExtension($input, $mime) {
00427 return $this->validator->fixExtension($input, $mime);
00428 }
00429
00442 public function isRequired ($child) {
00443 return (isset($child['required']) && ($child['required'] == "true()"));
00444 }
00445 }
00446 ?>