PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/bizproc/lib/basetype/file.php

https://gitlab.com/alexprowars/bitrix
PHP | 487 lines | 329 code | 60 blank | 98 comment | 46 complexity | 52a28ce48505dcd29eee5a80d98bae7a MD5 | raw file
  1. <?php
  2. namespace Bitrix\Bizproc\BaseType;
  3. use Bitrix\Main;
  4. use Bitrix\Bizproc\FieldType;
  5. use Bitrix\Main\Localization\Loc;
  6. Loc::loadMessages(__FILE__);
  7. /**
  8. * Class File
  9. * @package Bitrix\Bizproc\BaseType
  10. */
  11. class File extends Base
  12. {
  13. /**
  14. * @return string
  15. */
  16. public static function getType()
  17. {
  18. return FieldType::FILE;
  19. }
  20. /**
  21. * Get formats list.
  22. * @return array
  23. */
  24. public static function getFormats()
  25. {
  26. $formats = parent::getFormats();
  27. $formats['src'] = [
  28. 'callable' => 'formatValueSrc',
  29. 'separator' => ', ',
  30. ];
  31. $formats['publink'] = [
  32. 'callable' => 'formatValuePublicLink',
  33. 'separator' => ', ',
  34. ];
  35. $formats['shortlink'] = [
  36. 'callable' => 'formatValueShortLink',
  37. 'separator' => ', ',
  38. ];
  39. $formats['name'] = [
  40. 'callable' => 'formatValueName',
  41. 'separator' => ', ',
  42. ];
  43. return $formats;
  44. }
  45. /**
  46. * Normalize single value.
  47. *
  48. * @param FieldType $fieldType Document field type.
  49. * @param mixed $value Field value.
  50. * @return mixed Normalized value
  51. */
  52. public static function toSingleValue(FieldType $fieldType, $value)
  53. {
  54. if (is_array($value))
  55. {
  56. if (\CBPHelper::isAssociativeArray($value))
  57. {
  58. $value = array_keys($value);
  59. }
  60. reset($value);
  61. $value = current($value);
  62. }
  63. return $value;
  64. }
  65. /**
  66. * @param FieldType $fieldType
  67. * @param $value
  68. * @return string
  69. */
  70. protected static function formatValuePrintable(FieldType $fieldType, $value)
  71. {
  72. $value = (int) $value;
  73. $iterator = \CFile::getByID($value);
  74. if ($file = $iterator->fetch())
  75. {
  76. return '[url=/bitrix/tools/bizproc_show_file.php?f='.urlencode($file['FILE_NAME']).'&hash='
  77. .md5($file['FILE_NAME'])
  78. .'&i='.$value.'&h='.md5($file['SUBDIR']).']'
  79. .htmlspecialcharsbx($file['ORIGINAL_NAME'])
  80. .'[/url]';
  81. }
  82. return '';
  83. }
  84. /**
  85. * @param FieldType $fieldType
  86. * @param $value
  87. * @return string
  88. */
  89. protected static function formatValueSrc(FieldType $fieldType, $value)
  90. {
  91. $value = (int) $value;
  92. $file = \CFile::getFileArray($value);
  93. if ($file && $file['SRC'])
  94. {
  95. return $file['SRC'];
  96. }
  97. return '';
  98. }
  99. /**
  100. * @param FieldType $fieldType
  101. * @param $value
  102. * @return string
  103. */
  104. protected static function formatValueName(FieldType $fieldType, $value)
  105. {
  106. $value = (int) $value;
  107. $file = \CFile::getFileArray($value);
  108. if ($file && ($file['ORIGINAL_NAME'] || $file['FILE_NAME']))
  109. {
  110. return $file['ORIGINAL_NAME'] ?: $file['FILE_NAME'];
  111. }
  112. return '';
  113. }
  114. /**
  115. * @param FieldType $fieldType
  116. * @param $value
  117. * @return string
  118. */
  119. protected static function formatValuePublicLink(FieldType $fieldType, $value)
  120. {
  121. $fileId = (int) $value;
  122. if ($fileId)
  123. {
  124. return \Bitrix\Bizproc\Controller\File::getPublicLink($fileId);
  125. }
  126. return '';
  127. }
  128. /**
  129. * @param FieldType $fieldType
  130. * @param $value
  131. * @return string
  132. */
  133. protected static function formatValueShortLink(FieldType $fieldType, $value)
  134. {
  135. $pubLink = static::formatValuePublicLink($fieldType, $value);
  136. if ($pubLink)
  137. {
  138. return Main\Engine\UrlManager::getInstance()->getHostUrl().\CBXShortUri::getShortUri($pubLink);
  139. }
  140. return '';
  141. }
  142. /**
  143. * @param FieldType $fieldType Document field type.
  144. * @param mixed $value Field value.
  145. * @param string $toTypeClass Type class name.
  146. * @return null
  147. */
  148. public static function convertTo(FieldType $fieldType, $value, $toTypeClass)
  149. {
  150. /** @var Base $toTypeClass */
  151. $type = $toTypeClass::getType();
  152. switch ($type)
  153. {
  154. case FieldType::FILE:
  155. $value = (int) $value;
  156. break;
  157. default:
  158. $value = null;
  159. }
  160. return $value;
  161. }
  162. /**
  163. * Return conversion map for current type.
  164. * @return array Map.
  165. */
  166. public static function getConversionMap()
  167. {
  168. return [
  169. [
  170. FieldType::FILE
  171. ]
  172. ];
  173. }
  174. /**
  175. * @param FieldType $fieldType Document field type.
  176. * @param mixed $value Field value.
  177. * @param string $toTypeClass Type class name.
  178. * @return array
  179. */
  180. public static function convertValueMultiple(FieldType $fieldType, $value, $toTypeClass)
  181. {
  182. $value = (array) $value;
  183. if (\CBPHelper::isAssociativeArray($value))
  184. {
  185. $value = array_keys($value);
  186. }
  187. return parent::convertValueMultiple($fieldType, $value, $toTypeClass);
  188. }
  189. /**
  190. * @param int $renderMode Control render mode.
  191. * @return bool
  192. */
  193. public static function canRenderControl($renderMode)
  194. {
  195. return true;
  196. }
  197. /**
  198. * @param FieldType $fieldType
  199. * @param array $field
  200. * @param mixed $value
  201. * @param bool $allowSelection
  202. * @param int $renderMode
  203. * @return string
  204. */
  205. protected static function renderControl(FieldType $fieldType, array $field, $value, $allowSelection, $renderMode)
  206. {
  207. if ($renderMode & FieldType::RENDER_MODE_DESIGNER)
  208. {
  209. return '';
  210. }
  211. $classNameHtml = htmlspecialcharsbx(static::generateControlClassName($fieldType, $field));
  212. $idHtml = htmlspecialcharsbx(static::generateControlId($field));
  213. $nameHtml = htmlspecialcharsbx(static::generateControlName($field));
  214. if ($renderMode & FieldType::RENDER_MODE_PUBLIC)
  215. {
  216. $msg = htmlspecialcharsbx(Loc::getMessage('BPDT_FILE_CHOOSE_FILE'));
  217. $onchange = 'this.nextSibling.textContent = BX.Bizproc.FieldType.File.parseLabel(this.value);';
  218. $onchange = htmlspecialcharsbx($onchange);
  219. return <<<HTML
  220. <div class="{$classNameHtml}">
  221. <span>
  222. <span class="webform-small-button">{$msg}</span>
  223. </span>
  224. <input type="file" id="{$idHtml}" name="{$nameHtml}" onchange="{$onchange}">
  225. <span class="bizproc-type-control-file-label"></span>
  226. </div>
  227. HTML;
  228. }
  229. return '<input type="file" class="'.$classNameHtml.'" id="'.$idHtml.'" name="'.$nameHtml.'">';
  230. }
  231. /**
  232. * @param FieldType $fieldType
  233. * @param array $field
  234. * @param mixed $value
  235. * @param bool $allowSelection
  236. * @param int $renderMode
  237. * @return string
  238. */
  239. public static function renderControlSingle(FieldType $fieldType, array $field, $value, $allowSelection, $renderMode)
  240. {
  241. if ($allowSelection && $renderMode & FieldType::RENDER_MODE_PUBLIC)
  242. {
  243. return self::renderPublicSelectableControlSingle($fieldType, $field, $value);
  244. }
  245. if ($renderMode & FieldType::RENDER_MODE_MOBILE)
  246. {
  247. return self::renderMobileControl($fieldType, $field, $value);
  248. }
  249. return parent::renderControlSingle($fieldType, $field, $value, $allowSelection, $renderMode);
  250. }
  251. /**
  252. * @param FieldType $fieldType Document field type.
  253. * @param array $field Form field.
  254. * @param mixed $value Field value.
  255. * @param bool $allowSelection Allow selection flag.
  256. * @param int $renderMode Control render mode.
  257. * @return string
  258. */
  259. public static function renderControlMultiple(FieldType $fieldType, array $field, $value, $allowSelection, $renderMode)
  260. {
  261. if ($renderMode & FieldType::RENDER_MODE_DESIGNER && !$allowSelection)
  262. {
  263. return '';
  264. }
  265. if ($allowSelection && $renderMode & FieldType::RENDER_MODE_PUBLIC)
  266. {
  267. return self::renderPublicSelectableControlMultiple($fieldType, $field, $value);
  268. }
  269. if ($renderMode & FieldType::RENDER_MODE_MOBILE)
  270. {
  271. return self::renderMobileControl($fieldType, $field, $value);
  272. }
  273. if ($renderMode & FieldType::RENDER_MODE_DESIGNER)
  274. {
  275. if (!is_array($value) || is_array($value) && \CBPHelper::isAssociativeArray($value))
  276. {
  277. $value = [$value];
  278. }
  279. // need to show at least one control
  280. if (empty($value))
  281. {
  282. $value[] = null;
  283. }
  284. $controls = [];
  285. foreach ($value as $k => $v)
  286. {
  287. $singleField = $field;
  288. $singleField['Index'] = $k;
  289. $controls[] = parent::renderControlSingle($fieldType, $singleField, $v, $allowSelection, $renderMode);
  290. }
  291. return static::wrapCloneableControls($controls, static::generateControlName($field));
  292. }
  293. return parent::renderControlMultiple($fieldType, $field, $value, $allowSelection, $renderMode);
  294. }
  295. private static function renderPublicSelectableControlSingle(FieldType $fieldType, array $field, $value)
  296. {
  297. $name = static::generateControlName($field);
  298. $className = static::generateControlClassName($fieldType, $field);
  299. $className = str_replace('file', 'file-selectable', $className);
  300. return sprintf(
  301. '<input type="text" class="%s" name="%s" value="%s" placeholder="%s" data-role="inline-selector-target" data-selector-type="file" data-property="%s"/>',
  302. htmlspecialcharsbx($className),
  303. htmlspecialcharsbx($name),
  304. htmlspecialcharsbx((string)$value),
  305. htmlspecialcharsbx($fieldType->getDescription()),
  306. htmlspecialcharsbx(Main\Web\Json::encode($fieldType->getProperty()))
  307. );
  308. }
  309. private static function renderPublicSelectableControlMultiple(FieldType $fieldType, array $field, $value)
  310. {
  311. if (!is_array($value) || is_array($value) && \CBPHelper::isAssociativeArray($value))
  312. {
  313. $value = [$value];
  314. }
  315. // need to show at least one control
  316. if (empty($value))
  317. {
  318. $value[] = null;
  319. }
  320. $controls = [];
  321. foreach ($value as $k => $v)
  322. {
  323. $singleField = $field;
  324. $singleField['Index'] = $k;
  325. $controls[] = static::renderPublicSelectableControlSingle(
  326. $fieldType,
  327. $singleField,
  328. $v
  329. );
  330. }
  331. return static::renderPublicMultipleWrapper($fieldType, $field, $controls);
  332. }
  333. private static function renderMobileControl(FieldType $fieldType, array $field, $value)
  334. {
  335. /** @var \CMain */
  336. global $APPLICATION;
  337. ob_start();
  338. $APPLICATION->IncludeComponent(
  339. 'bitrix:main.file.input',
  340. 'mobile',
  341. [
  342. 'MODULE_ID' => 'bizproc',
  343. 'CONTROL_ID' => static::generateControlId($field),
  344. 'ALLOW_UPLOAD' => 'A',
  345. 'INPUT_NAME' => static::generateControlName($field),
  346. 'INPUT_VALUE' => $value,
  347. 'MULTIPLE' => $fieldType->isMultiple() ? 'Y' : 'N'
  348. ]
  349. );
  350. return ob_get_clean();
  351. }
  352. /**
  353. * @param FieldType $fieldType
  354. * @param array $field
  355. * @param array $request
  356. * @return null|int
  357. */
  358. protected static function extractValue(FieldType $fieldType, array $field, array $request)
  359. {
  360. $value = parent::extractValue($fieldType, $field, $request);
  361. if (is_array($value) && !empty($value['name']) && !empty($value['tmp_name']))
  362. {
  363. if (!is_uploaded_file($value['tmp_name']))
  364. {
  365. $value = null;
  366. static::addError([
  367. 'code' => 'ErrorValue',
  368. 'message' => Loc::getMessage('BPDT_FILE_SECURITY_ERROR'),
  369. 'parameter' => static::generateControlName($field),
  370. ]);
  371. }
  372. else
  373. {
  374. if (!array_key_exists('MODULE_ID', $value) || $value['MODULE_ID'] == '')
  375. $value['MODULE_ID'] = 'bizproc';
  376. $value = \CFile::saveFile($value, 'bizproc_wf');
  377. if (!$value)
  378. {
  379. $value = null;
  380. static::addError([
  381. 'code' => 'ErrorValue',
  382. 'message' => Loc::getMessage('BPDT_FILE_INVALID'),
  383. 'parameter' => static::generateControlName($field),
  384. ]);
  385. }
  386. }
  387. }
  388. elseif (\CBPActivity::isExpression($value))
  389. {
  390. //It`s OK
  391. }
  392. elseif (is_numeric($value) && defined('BX_MOBILE'))
  393. {
  394. $file = \CFile::getById($value)->fetch();
  395. if (!$file || $file['MODULE_ID'] !== 'bizproc')
  396. {
  397. $value = null;
  398. }
  399. }
  400. else
  401. {
  402. $value = null;
  403. }
  404. return $value;
  405. }
  406. public static function externalizeValue(FieldType $fieldType, $context, $value)
  407. {
  408. if ($context === 'rest' && is_numeric($value))
  409. {
  410. return \CRestUtil::GetFile($value);
  411. }
  412. return parent::externalizeValue($fieldType, $context, $value);
  413. }
  414. public static function internalizeValue(FieldType $fieldType, $context, $value)
  415. {
  416. if ($context === 'rest')
  417. {
  418. $fileFields = \CRestUtil::saveFile($value);
  419. if ($fileFields)
  420. {
  421. $fileFields['MODULE_ID'] = 'bizproc';
  422. return (int) \CFile::saveFile($fileFields, 'bizproc_rest');
  423. }
  424. }
  425. return parent::internalizeValue($fieldType, $context, $value);
  426. }
  427. }