1<?php 2/** 3 * Class for <input type="file" /> elements 4 * 5 * PHP version 5 6 * 7 * LICENSE 8 * 9 * This source file is subject to BSD 3-Clause License that is bundled 10 * with this package in the file LICENSE and available at the URL 11 * https://raw.githubusercontent.com/pear/HTML_QuickForm2/trunk/docs/LICENSE 12 * 13 * @category HTML 14 * @package HTML_QuickForm2 15 * @author Alexey Borzov <avb@php.net> 16 * @author Bertrand Mansion <golgote@mamasam.com> 17 * @copyright 2006-2021 Alexey Borzov <avb@php.net>, Bertrand Mansion <golgote@mamasam.com> 18 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License 19 * @link https://pear.php.net/package/HTML_QuickForm2 20 */ 21 22/** 23 * Base class for <input> elements 24 */ 25require_once 'HTML/QuickForm2/Element/Input.php'; 26 27/** 28 * Class for <input type="file" /> elements 29 * 30 * @category HTML 31 * @package HTML_QuickForm2 32 * @author Alexey Borzov <avb@php.net> 33 * @author Bertrand Mansion <golgote@mamasam.com> 34 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License 35 * @version Release: 2.2.2 36 * @link https://pear.php.net/package/HTML_QuickForm2 37 */ 38class HTML_QuickForm2_Element_InputFile extends HTML_QuickForm2_Element_Input 39{ 40 /** 41 * Language to display error messages in 42 * @var string 43 */ 44 protected $language = null; 45 46 /** 47 * Information on uploaded file, from submit data source 48 * @var array 49 */ 50 protected $value = null; 51 52 protected $attributes = ['type' => 'file']; 53 54 /** 55 * Message provider for upload error messages 56 * @var callback|HTML_QuickForm2_MessageProvider 57 */ 58 protected $messageProvider; 59 60 /** 61 * Class constructor 62 * 63 * Possible keys in $data array are: 64 * - 'messageProvider': an instance of a class implementing 65 * HTML_QuickForm2_MessageProvider interface, this will be used to get 66 * localized error messages. Default will be used if not given. 67 * - 'language': language to display error messages in, will be passed to 68 * message provider. 69 * 70 * @param string $name Element name 71 * @param string|array $attributes Attributes (either a string or an array) 72 * @param array $data Data used to set up error messages for PHP's 73 * file upload errors. 74 */ 75 public function __construct($name = null, $attributes = null, array $data = []) 76 { 77 if (isset($data['messageProvider'])) { 78 if (!is_callable($data['messageProvider']) 79 && !$data['messageProvider'] instanceof HTML_QuickForm2_MessageProvider 80 ) { 81 throw new HTML_QuickForm2_InvalidArgumentException( 82 "messageProvider: expecting a callback or an implementation" 83 . " of HTML_QuickForm2_MessageProvider" 84 ); 85 } 86 $this->messageProvider = $data['messageProvider']; 87 88 } else { 89 HTML_QuickForm2_Loader::loadClass('HTML_QuickForm2_MessageProvider_Default'); 90 $this->messageProvider = HTML_QuickForm2_MessageProvider_Default::getInstance(); 91 } 92 if (isset($data['language'])) { 93 $this->language = $data['language']; 94 } 95 unset($data['messageProvider'], $data['language']); 96 parent::__construct($name, $attributes, $data); 97 } 98 99 100 /** 101 * File upload elements cannot be frozen 102 * 103 * To properly "freeze" a file upload element one has to store the uploaded 104 * file somewhere and store the file info in session. This is way outside 105 * the scope of this class. 106 * 107 * @param bool $freeze Whether element should be frozen or editable. This 108 * parameter is ignored in case of file uploads 109 * 110 * @return bool Always returns false 111 */ 112 public function toggleFrozen($freeze = null) 113 { 114 return false; 115 } 116 117 /** 118 * Returns the information on uploaded file 119 * 120 * @return array|null 121 */ 122 public function getRawValue() 123 { 124 return $this->value; 125 } 126 127 /** 128 * Alias of getRawValue(), InputFile elements do not allow filters 129 * 130 * @return array|null 131 */ 132 public function getValue() 133 { 134 return $this->getRawValue(); 135 } 136 137 /** 138 * File upload's value cannot be set here 139 * 140 * @param mixed $value Value for file element, this parameter is ignored 141 * 142 * @return $this 143 */ 144 public function setValue($value) 145 { 146 return $this; 147 } 148 149 protected function updateValue() 150 { 151 // request #16807: file uploads should not be added to forms with 152 // method="get", enctype should be set to multipart/form-data 153 // we cannot do this in setContainer() as the element may be added to 154 // e.g. a group first and then the group may be added to a form 155 $container = $this->getContainer(); 156 while (!empty($container)) { 157 if ($container instanceof HTML_QuickForm2) { 158 if ('get' == $container->getAttribute('method')) { 159 throw new HTML_QuickForm2_InvalidArgumentException( 160 'File upload elements can only be added to forms with post submit method' 161 ); 162 } 163 if ('multipart/form-data' != $container->getAttribute('enctype')) { 164 $container->setAttribute('enctype', 'multipart/form-data'); 165 } 166 break; 167 } 168 $container = $container->getContainer(); 169 } 170 171 foreach ($this->getDataSources() as $ds) { 172 if ($ds instanceof HTML_QuickForm2_DataSource_Submit) { 173 $value = $ds->getUpload($this->getName()); 174 if (null !== $value) { 175 $this->value = $value; 176 return; 177 } 178 } 179 } 180 $this->value = null; 181 } 182 183 /** 184 * Performs the server-side validation 185 * 186 * Before the Rules added to the element kick in, the element checks the 187 * error code added to the $_FILES array by PHP. If the code isn't 188 * UPLOAD_ERR_OK or UPLOAD_ERR_NO_FILE then a built-in error message will be 189 * displayed and no further validation will take place. 190 * 191 * @return boolean Whether the element is valid 192 */ 193 protected function validate() 194 { 195 if (strlen($this->error)) { 196 return false; 197 } 198 if (isset($this->value['error']) 199 && !in_array($this->value['error'], [UPLOAD_ERR_OK, UPLOAD_ERR_NO_FILE]) 200 ) { 201 $errorMessage = $this->messageProvider instanceof HTML_QuickForm2_MessageProvider 202 ? $this->messageProvider->get(['file', $this->value['error']], $this->language) 203 : call_user_func($this->messageProvider, ['file', $this->value['error']], $this->language); 204 if (UPLOAD_ERR_INI_SIZE == $this->value['error']) { 205 $iniSize = ini_get('upload_max_filesize'); 206 $size = intval($iniSize); 207 switch (strtoupper(substr($iniSize, -1))) { 208 case 'G': $size *= 1024; 209 case 'M': $size *= 1024; 210 case 'K': $size *= 1024; 211 } 212 213 } elseif (UPLOAD_ERR_FORM_SIZE == $this->value['error']) { 214 foreach ($this->getDataSources() as $ds) { 215 if ($ds instanceof HTML_QuickForm2_DataSource_Submit) { 216 $size = intval($ds->getValue('MAX_FILE_SIZE')); 217 break; 218 } 219 } 220 } 221 $this->error = isset($size)? sprintf($errorMessage, $size): $errorMessage; 222 return false; 223 } 224 return parent::validate(); 225 } 226 227 public function addFilter($callback, array $options = []) 228 { 229 throw new HTML_QuickForm2_Exception( 230 'InputFile elements do not support filters' 231 ); 232 } 233 234 public function addRecursiveFilter($callback, array $options = []) 235 { 236 throw new HTML_QuickForm2_Exception( 237 'InputFile elements do not support filters' 238 ); 239 } 240} 241?> 242