/** * @param mixed $value * * @return bool */ public function setValue($value) { if ($this->get('required') && !$value) { $this->_error = $this->get('label') . ' is required.'; return false; } // _link_ allows users to paste in a URL for a given file. This is then copied locally as normal. // In order to detect this, I need to look for the presence of a protocol indicator and this element needs // to have allowlink set. if($this->get('allowlink') && strpos($value, '_link_://') === 0){ $n = $this->get('name'); $value = substr($value, 9); // Source $f = new \Core\Filestore\Backends\FileRemote($value); if(!$f->exists()){ $this->_error = 'Remote file does not seem to exist'; return false; } // Destination $nf = \Core\Filestore\Factory::File($this->get('basedir') . '/' . $f->getBaseFilename()); // do NOT copy the contents over until the accept check has been ran! // Now that I have a file object, (in the temp filesystem still), I should validate the filetype // to see if the developer wanted a strict "accept" type to be requested. // If present, I'll have something to run through and see if the file matches. // I need the destination now because I need to full filename if an extension is requested in the accept. if($this->get('accept')){ $acceptcheck = \Core\check_file_mimetype($this->get('accept'), $f->getMimetype(), $nf->getExtension()); // Now that all the mimetypes have run through, I can see if one matched. if($acceptcheck != ''){ $this->_error = $acceptcheck; return false; } } // Now all the checks should be completed and I can safely copy the file away from the temporary filesystem. $f->copyTo($nf); $value = $nf->getFilename(false); } elseif(($this->get('browsable') || $this->get('browseable')) && strpos($value, '_browse_://public') === 0){ $n = $this->get('name'); $value = substr($value, 11); // Source $f = \Core\Filestore\Factory::File($value); if(!$f->exists()){ $this->_error = 'File does not seem to exist'; return false; } // Now that I have a file object, I still need to validate that this file was what the user was supposed to select. // If present, I'll have something to run through and see if the file matches. if($this->get('accept')){ $acceptcheck = \Core\check_file_mimetype($this->get('accept'), $f->getMimetype(), $f->getExtension()); // Now that all the mimetypes have run through, I can see if one matched. if($acceptcheck != ''){ $this->_error = $acceptcheck; return false; } } } elseif ($value == '_upload_') { $n = $this->get('name'); // Because PHP will have different sources depending if the name has [] in it... if (strpos($n, '][') !== false) { // This is a 2+ nested array value. preg_match_all('#\[([^\]]*)\]#', $n, $matches); $p1 = substr($n, 0, strpos($n, '[')); $src =& $_FILES[$p1]; $in = array( 'name' => $src['name'], 'type' => $src['type'], 'tmp_name' => $src['tmp_name'], 'error' => $src['error'], 'size' => $src['size'], ); foreach($matches[1] as $next){ $in['name'] =& $in['name'][$next]; $in['type'] =& $in['type'][$next]; $in['tmp_name'] =& $in['tmp_name'][$next]; $in['error'] =& $in['error'][$next]; $in['size'] =& $in['size'][$next]; } } elseif (strpos($n, '[') !== false) { // This is a single array value. $p1 = substr($n, 0, strpos($n, '[')); $p2 = substr($n, strpos($n, '[') + 1, -1); if (!isset($_FILES[$p1])) { $this->_error = 'No file uploaded for ' . $this->get('label'); return false; } $in = array( 'name' => $_FILES[$p1]['name'][$p2], 'type' => $_FILES[$p1]['type'][$p2], 'tmp_name' => $_FILES[$p1]['tmp_name'][$p2], 'error' => $_FILES[$p1]['error'][$p2], 'size' => $_FILES[$p1]['size'][$p2], ); } else { $in =& $_FILES[$n]; } if (!isset($in)) { $this->_error = 'No file uploaded for ' . $this->get('label'); return false; } else { $error = \Core\translate_upload_error($in['error']); if($error != ''){ $this->_error = $error; return false; } // Source $f = \Core\Filestore\Factory::File($in['tmp_name']); // Destination // Make sure the filename is sanitized. // Also, limit the new filename to 40 characters. $newbasename = substr(\Core\str_to_url($in['name'], true), 0, 40); $nf = \Core\Filestore\Factory::File($this->get('basedir') . '/' . $newbasename); // do NOT copy the contents over until the accept check has been ran! // Now that I have a file object, (in the temp filesystem still), I should validate the filetype // to see if the developer wanted a strict "accept" type to be requested. // If present, I'll have something to run through and see if the file matches. // I need the destination now because I need to full filename if an extension is requested in the accept. if($this->get('accept')){ $acceptcheck = \Core\check_file_mimetype($this->get('accept'), $f->getMimetype(), $nf->getExtension()); // Now that all the mimetypes have run through, I can see if one matched. if($acceptcheck != ''){ $this->_error = $acceptcheck; return false; } } // Now all the checks should be completed and I can safely copy the file away from the temporary filesystem. $f->copyTo($nf); $value = $nf->getFilename(false); } } $this->_attributes['value'] = $value; return true; }
/** * Handle the entire upload as a standard multitype POST * @return array */ private function _doPost() { $info = array(); if (sizeof($_FILES) == 1) { // $upload will be the current index of FILES, which should contain all the uploaded files, // in an associative array as typical with FILES. $upload = current($_FILES); } if ($upload && is_array($upload['tmp_name'])) { // param_name is an array identifier like "files[]", // $_FILES is a multi-dimensional array: foreach ($upload['tmp_name'] as $index => $value) { // Source $f = \Core\Filestore\Factory::File($upload['tmp_name'][$index]); // Destination // Make sure the filename is sanitized. $newbasename = \Core\str_to_url(urldecode($upload['name'][$index]), true); $nf = \Core\Filestore\Factory::File($this->_formelement->get('basedir') . $newbasename); // This is the object that is returned in the json array. // It needs to contain something. $file = array('name' => '', 'size' => $f->getFilesize(), 'type' => $f->getMimetype(), 'url' => '', 'thumbnail_url' => '', 'error' => ''); // do NOT copy the contents over until the accept check has been ran! // Now that I have a file object, (in the temp filesystem still), I should validate the filetype // to see if the developer wanted a strict "accept" type to be requested. // If present, I'll have something to run through and see if the file matches. // I need the destination now because I need to full filename if an extension is requested in the accept. if ($this->_formelement->get('accept')) { $acceptcheck = \Core\check_file_mimetype($this->_formelement->get('accept'), $f->getMimetype(), $nf->getExtension()); // Now that all the mimetypes have run through, I can see if one matched. if ($acceptcheck != '') { $file['error'] = $acceptcheck; $info[] = $file; continue; // skip to the next file upload. } } // Now all the checks should be completed and I can safely copy the file away from the temporary filesystem. $f->copyTo($nf); // And now all the file's attributes will be visible. $file['name'] = $nf->getBaseFilename(); $file['url'] = $nf->getURL(); $file['thumbnail_url'] = $nf->getPreviewURL('50x50'); $info[] = $file; } } elseif ($upload || isset($_SERVER['HTTP_X_FILE_NAME'])) { // param_name is a single object identifier like "file", // $_FILES is a one-dimensional array: $info[] = $this->handle_file_upload(isset($upload['tmp_name']) ? $upload['tmp_name'] : null, isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : (isset($upload['name']) ? $upload['name'] : null), isset($_SERVER['HTTP_X_FILE_SIZE']) ? $_SERVER['HTTP_X_FILE_SIZE'] : (isset($upload['size']) ? $upload['size'] : null), isset($_SERVER['HTTP_X_FILE_TYPE']) ? $_SERVER['HTTP_X_FILE_TYPE'] : (isset($upload['type']) ? $upload['type'] : null), isset($upload['error']) ? $upload['error'] : null); } return $info; }