Ejemplo n.º 1
0
	/**
	 * @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;
 }