PageRenderTime 55ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/qcodo/_core/qform/QFileUploader.class.php

https://github.com/apselico/qcodo
PHP | 270 lines | 174 code | 43 blank | 53 comment | 15 complexity | 0f56b132891a23f1fe8374749bedb7a8 MD5 | raw file
  1. <?php
  2. class QFileUploader extends QControl {
  3. protected $strJavaScripts = '_core/control_file.js';
  4. protected $blnIsBlockElement = true;
  5. protected $pxyRemoveFile;
  6. protected $pxyCancelUpload;
  7. protected $strFilePath;
  8. protected $strFileName;
  9. protected $intFileSize;
  10. protected $strMimeType;
  11. protected $strDownloadUrl;
  12. protected $strTemporaryUploadFolder = '/tmp';
  13. protected $strCssClass = 'fileUploader';
  14. protected $strFileUploadedCallbackMethod;
  15. protected $objFileUploadedCallbackObject;
  16. protected $strFileRemovedCallbackMethod;
  17. protected $objFileRemovedCallbackObject;
  18. /**
  19. * If this control needs to update itself from the $_POST data, the logic to do so
  20. * will be performed in this method.
  21. */
  22. public function ParsePostData() {}
  23. /**
  24. * If this control has validation rules, the logic to do so
  25. * will be performed in this method.
  26. * @return boolean
  27. */
  28. public function Validate() {
  29. $this->strValidationError = null;
  30. if ($this->blnRequired) {
  31. if (!$this->strFilePath) {
  32. if ($this->strName)
  33. $this->strValidationError = sprintf('%s is required', $this->strName);
  34. else
  35. $this->strValidationError = 'Required';
  36. return false;
  37. }
  38. }
  39. return true;
  40. }
  41. /**
  42. * Get the HTML for this Control.
  43. * @return string
  44. */
  45. public function GetControlHtml() {
  46. // Pull any Attributes
  47. $strAttributes = $this->GetAttributes();
  48. // Pull any styles
  49. if ($strStyle = $this->GetStyleAttributes())
  50. $strStyle = 'style="' . $strStyle . '"';
  51. // Return the HTML
  52. $strHtml = null;
  53. if (!$this->strFilePath) {
  54. $strHtml .= sprintf('<input type="button" class="button" id="%s_button" value="Browse"/>', $this->strControlId);
  55. $strHtml .= sprintf('<span id="%s_ospan"><iframe id="%s_iframe" scrolling="no" style="display: none;"></iframe></span>', $this->strControlId, $this->strControlId);
  56. $strHtml .= sprintf('<div class="progress" id="%s_progress" style="display: none;">', $this->strControlId);
  57. $strHtml .= sprintf('<div class="size" id="%s_size"><img src="%s/spinner_14.gif"/></div>', $this->strControlId, __IMAGE_ASSETS__);
  58. $strHtml .= '<div class="bar">';
  59. $strHtml .= sprintf('<div class="status" id="%s_status">Uploading...</div>', $this->strControlId);
  60. $strHtml .= sprintf('<div class="fill" id="%s_fill"></div>', $this->strControlId);
  61. $strHtml .= '</div>';
  62. $strHtml .= sprintf('<div class="cancel"><a href="#" %s>Cancel</a></div>', $this->pxyCancelUpload->RenderAsEvents(null, false));
  63. $strHtml .= '</div>';
  64. } else if ($this->strDownloadUrl) {
  65. $strHtml .= sprintf('<strong><a href="%s">%s</a></strong> (%s) &nbsp; <a href="#" %s>Remove</a>',
  66. $this->strDownloadUrl, $this->strFileName, QString::GetByteSize($this->intFileSize), $this->pxyRemoveFile->RenderAsEvents(null, false));
  67. } else {
  68. $strHtml .= sprintf('<strong>%s</strong> (%s) &nbsp; <a href="#" %s>Remove</a>',
  69. $this->strFileName, QString::GetByteSize($this->intFileSize), $this->pxyRemoveFile->RenderAsEvents(null, false));
  70. }
  71. return sprintf('<div id="%s" %s%s>%s</div>', $this->strControlId, $strAttributes, $strStyle, $strHtml);
  72. }
  73. public function GetEndScript() {
  74. $strToReturn = parent::GetEndScript();
  75. $strUniqueHash = substr(md5(microtime() . rand(0, 1000000)), 4, 16);
  76. if (($this->blnVisible) && (!$this->strFilePath)) {
  77. $strToReturn .= sprintf('qc.regFUP("%s", "%s", "%s"); ',
  78. $this->strControlId, QApplication::$RequestUri, $strUniqueHash
  79. );
  80. }
  81. return $strToReturn;
  82. }
  83. /**
  84. * Constructor for this control
  85. * @param mixed $objParentObject Parent QForm or QControl that is responsible for rendering this control
  86. * @param string $strControlId optional control ID
  87. */
  88. public function __construct($objParentObject, $strControlId = null) {
  89. try {
  90. parent::__construct($objParentObject, $strControlId);
  91. } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
  92. $this->AddAction(new QFileUploadedEvent(), new QAjaxControlAction($this, 'HandleFileUploaded'));
  93. $this->pxyRemoveFile = new QControlProxy($this);
  94. $this->pxyRemoveFile->AddAction(new QClickEvent(), new QAjaxControlAction($this, 'HandleFileRemoved'));
  95. $this->pxyRemoveFile->AddAction(new QClickEvent(), new QTerminateAction());
  96. $this->pxyCancelUpload = new QControlProxy($this);
  97. $this->pxyCancelUpload->AddAction(new QClickEvent(), new QAjaxControlAction($this, 'HandleFileCancelled'));
  98. $this->pxyCancelUpload->AddAction(new QClickEvent(), new QTerminateAction());
  99. }
  100. /**
  101. * Used internally by Qcodo to handle the javascript-based post call to update form and control
  102. * state when a file has been uploaded. This will also make a call to any FileUploadedCallback if one was set.
  103. * @param string $strFormId
  104. * @param string $strControlId
  105. * @param string $strParameter
  106. * @return void
  107. */
  108. public function HandleFileUploaded($strFormId, $strControlId, $strParameter) {
  109. $this->strValidationError = null;
  110. $this->strFilePath = $_FILES[$this->strControlId . '_ctlflc']['tmp_name'];
  111. $this->strFileName = $_FILES[$this->strControlId . '_ctlflc']['name'];
  112. $this->intFileSize = $_FILES[$this->strControlId . '_ctlflc']['size'];
  113. $this->strMimeType = $_FILES[$this->strControlId . '_ctlflc']['type'];
  114. // Save the File in a slightly more permanent temporary location
  115. $strTempFilePath = $this->strTemporaryUploadFolder . '/' . basename($this->strFilePath) . rand(1000, 9999);
  116. copy($this->strFilePath, $strTempFilePath);
  117. $this->strFilePath = $strTempFilePath;
  118. $this->Refresh();
  119. if ($this->strFileUploadedCallbackMethod) call_user_func_array(
  120. array($this->objFileUploadedCallbackObject, $this->strFileUploadedCallbackMethod),
  121. array($this->objForm->FormId, $this->strControlId, $this->strActionParameter));
  122. }
  123. /**
  124. * Used internally by Qcodo to handle the javascript-based post call to update form and control
  125. * state when a file has been removed. This will also make a call to any FileRemovedCallback if one was set.
  126. * @param string $strFormId
  127. * @param string $strControlId
  128. * @param string $strParameter
  129. * @return void
  130. */
  131. public function HandleFileRemoved($strFormId, $strControlId, $strParameter) {
  132. $this->strFilePath = null;
  133. $this->strFileName = null;
  134. $this->intFileSize = null;
  135. $this->strMimeType = null;
  136. $this->strDownloadUrl = null;
  137. $this->Refresh();
  138. if ($this->strFileRemovedCallbackMethod) call_user_func_array(
  139. array($this->objFileRemovedCallbackObject, $this->strFileRemovedCallbackMethod),
  140. array($this->objForm->FormId, $this->strControlId, $this->strActionParameter));
  141. }
  142. public function HandleFileCancelled($strFormId, $strControlId, $strParameter) {
  143. $this->strFilePath = null;
  144. $this->strFileName = null;
  145. $this->intFileSize = null;
  146. $this->strMimeType = null;
  147. $this->strDownloadUrl = null;
  148. $this->Refresh();
  149. }
  150. public function SetFileUploadedCallback($objCallbackObject, $strCallbackMethod) {
  151. $this->objFileUploadedCallbackObject = $objCallbackObject;
  152. $this->strFileUploadedCallbackMethod = $strCallbackMethod;
  153. }
  154. public function SetFileRemovedCallback($objCallbackObject, $strCallbackMethod) {
  155. $this->objFileRemovedCallbackObject = $objCallbackObject;
  156. $this->strFileRemovedCallbackMethod = $strCallbackMethod;
  157. }
  158. /**
  159. * Used to remove a previously-set file to this FileUploader control
  160. * @return void
  161. */
  162. public function RemoveFile() {
  163. $this->HandleFileRemoved(null, null, null);
  164. }
  165. // For any HTML code that needs to be rendered at the END of the QForm when this control is INITIALLY rendered.
  166. // public function GetEndHtml() {
  167. // $strToReturn = parent::GetEndHtml();
  168. // return $strToReturn;
  169. // }
  170. /////////////////////////
  171. // Public Properties: GET
  172. /////////////////////////
  173. public function __get($strName) {
  174. switch ($strName) {
  175. case 'FilePath': return $this->strFilePath;
  176. case 'FileName': return $this->strFileName;
  177. case 'FileSize': return $this->intFileSize;
  178. case 'MimeType': return $this->strMimeType;
  179. case 'TemporaryUploadFolder': return $this->strTemporaryUploadFolder;
  180. case 'DownloadUrl': return $this->strDownloadUrl;
  181. default:
  182. try {
  183. return parent::__get($strName);
  184. } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
  185. }
  186. }
  187. /////////////////////////
  188. // Public Properties: SET
  189. /////////////////////////
  190. public function __set($strName, $mixValue) {
  191. $this->blnModified = true;
  192. switch ($strName) {
  193. case 'FilePath':
  194. try {
  195. $strFile = QType::Cast($mixValue, QType::String);
  196. } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
  197. if (!is_file($strFile))
  198. throw new QCallerException('File does not exist: ' . $strFile);
  199. $strNewFilePath = $this->strTemporaryUploadFolder . '/' . md5(microtime());
  200. copy($strFile, $strNewFilePath);
  201. $this->intFileSize = filesize($strNewFilePath);
  202. $this->strFilePath = $strNewFilePath;
  203. return $strFile;
  204. case 'FileName':
  205. try {
  206. return ($this->strFileName = QType::Cast($mixValue, QType::String));
  207. } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
  208. case 'TemporaryUploadFolder':
  209. try {
  210. return ($this->strTemporaryUploadFolder = QType::Cast($mixValue, QType::String));
  211. } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
  212. case 'DownloadUrl':
  213. try {
  214. return ($this->strDownloadUrl = QType::Cast($mixValue, QType::String));
  215. } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
  216. default:
  217. try {
  218. return (parent::__set($strName, $mixValue));
  219. } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
  220. }
  221. }
  222. }
  223. class QFileUploadedEvent extends QEvent {
  224. const EventName = 'onfileuploaded';
  225. protected $strJavaScriptEvent = 'onfileuploaded';
  226. }
  227. ?>