PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/translate/lib/controller/asset/grabber.php

https://gitlab.com/alexprowars/bitrix
PHP | 381 lines | 271 code | 47 blank | 63 comment | 19 complexity | 80f6d1836b3015fc7b3488db5c948565 MD5 | raw file
  1. <?php
  2. namespace Bitrix\Translate\Controller\Asset;
  3. use Bitrix\Main;
  4. use Bitrix\Main\Error;
  5. use Bitrix\Main\Localization\Loc;
  6. use Bitrix\Translate;
  7. class Grabber
  8. extends Translate\Controller\Controller
  9. implements Translate\Controller\IProcessParameters
  10. {
  11. use Translate\Controller\ProcessParams;
  12. const START_PATH = '/bitrix/modules';
  13. const SETTING_ID = 'TRANSLATE_LANGPACK';
  14. const ACTION_COLLECT = 'collect';
  15. const ACTION_PACK = 'pack';
  16. const ACTION_DOWNLOAD = 'download';
  17. const ACTION_UPLOAD = 'upload';
  18. const ACTION_EXTRACT = 'extract';
  19. const ACTION_APPLY = 'apply';
  20. const ACTION_APPLY_PUBLIC = 'apply_public';
  21. const ACTION_FINALIZE = 'finalize';
  22. const ACTION_PURGE = 'purge';
  23. const ACTION_CANCEL = 'cancel';
  24. const ACTION_CLEAR = 'clear';
  25. /** @var string */
  26. private $archiveFilePath;
  27. /** @var string */
  28. private $archiveFileType;
  29. /**
  30. * Configures actions.
  31. *
  32. * @return array
  33. */
  34. public function configureActions()
  35. {
  36. $configureActions = parent::configureActions();
  37. $permission = new Translate\Controller\CheckPermission(Translate\Permission::WRITE);
  38. $permissionSource = new Translate\Controller\CheckPermission(Translate\Permission::SOURCE);
  39. $configureActions[self::ACTION_COLLECT] = array(
  40. 'class' => Translate\Controller\Asset\Collect::class,
  41. '+prefilters' => array(
  42. $permission
  43. ),
  44. );
  45. $configureActions[self::ACTION_EXTRACT] = array(
  46. 'class' => Translate\Controller\Asset\Extract::class,
  47. '+prefilters' => array(
  48. $permission,
  49. $permissionSource
  50. ),
  51. );
  52. $configureActions[self::ACTION_APPLY] = array(
  53. 'class' => Translate\Controller\Asset\Apply::class,
  54. '+prefilters' => array(
  55. $permission,
  56. $permissionSource
  57. ),
  58. );
  59. $configureActions[self::ACTION_APPLY_PUBLIC] = array(
  60. 'class' => Translate\Controller\Asset\ApplyPublic::class,
  61. '+prefilters' => array(
  62. $permission,
  63. $permissionSource
  64. ),
  65. );
  66. $configureActions[self::ACTION_PACK] = array(
  67. 'class' => Translate\Controller\Asset\Pack::class,
  68. '+prefilters' => array(
  69. $permission
  70. ),
  71. );
  72. $configureActions[self::ACTION_UPLOAD] = array(
  73. '+prefilters' => array(
  74. $permission
  75. ),
  76. );
  77. $configureActions[self::ACTION_DOWNLOAD] = array(
  78. '-prefilters' => array(
  79. Main\Engine\ActionFilter\Csrf::class,
  80. ),
  81. '+prefilters' => array(
  82. $permission
  83. ),
  84. );
  85. $configureActions[self::ACTION_PURGE] = array(
  86. '+prefilters' => array(
  87. $permission
  88. ),
  89. );
  90. $configureActions[self::ACTION_CANCEL] = array(
  91. '+prefilters' => array(
  92. $permission
  93. ),
  94. );
  95. $configureActions[self::ACTION_CLEAR] = array(
  96. '+prefilters' => array(
  97. $permission
  98. ),
  99. );
  100. $configureActions[self::ACTION_FINALIZE] = array(
  101. '+prefilters' => array(
  102. $permission
  103. ),
  104. );
  105. return $configureActions;
  106. }
  107. /**
  108. * Initializes controller.
  109. *
  110. * @return void
  111. */
  112. protected function init()
  113. {
  114. parent::init();
  115. $this->keepField(['archiveFilePath', 'archiveFileType']);
  116. }
  117. /**
  118. * Handles uploaded file.
  119. *
  120. * @return array
  121. */
  122. public function uploadAction()
  123. {
  124. $result = array();
  125. $success = false;
  126. if (
  127. isset($_FILES, $_FILES['tarFile'], $_FILES['tarFile']['tmp_name']) &&
  128. ($_FILES['tarFile']['error'] == UPLOAD_ERR_OK) &&
  129. file_exists($_FILES['tarFile']['tmp_name'])
  130. )
  131. {
  132. if (
  133. (filesize($_FILES['tarFile']['tmp_name']) > 0) &&
  134. (
  135. mb_substr($_FILES['tarFile']['name'], -7) === '.tar.gz' ||
  136. mb_substr($_FILES['tarFile']['name'], -4) === '.tar'
  137. )
  138. )
  139. {
  140. if (mb_substr($_FILES['tarFile']['name'], -7) === '.tar.gz')
  141. {
  142. $suffix = '.tar.gz';
  143. }
  144. else
  145. {
  146. $suffix = '.tar';
  147. }
  148. if ($this->moveUploadedFile($_FILES['tarFile'], $suffix))
  149. {
  150. $this->saveProgressParameters();
  151. $success = ($this->hasErrors() === false);
  152. }
  153. }
  154. else
  155. {
  156. $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_TARFILE_EXTENTION')));
  157. }
  158. }
  159. else
  160. {
  161. if ($_FILES['tarFile']['error'] == UPLOAD_ERR_INI_SIZE)
  162. {
  163. $this->addError(
  164. new Main\Error(Loc::getMessage('TR_ERROR_UPLOAD_SIZE', [
  165. '#SIZE#' => \CFile::FormatSize(self::getMaxUploadSize())
  166. ]))
  167. );
  168. }
  169. else
  170. {
  171. $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_TARFILE')));
  172. }
  173. }
  174. if ($success)
  175. {
  176. $result['SUMMARY'] = Loc::getMessage('TR_IMPORT_UPLOAD_OK');
  177. }
  178. $result['STATUS'] = Translate\Controller\STATUS_COMPLETED;
  179. return $result;
  180. }
  181. /**
  182. * Moves uploaded csv file into bxtmp folder.
  183. *
  184. * @param array $postedFile Uploaded file data from $_FILES.
  185. * @param string $suffix Append file name with suffix.
  186. * @param int $timeToLive Time to live in hours.
  187. *
  188. * @return boolean
  189. */
  190. private function moveUploadedFile($postedFile, $suffix = '.tar', $timeToLive = 3)
  191. {
  192. if (
  193. isset($postedFile['tmp_name']) &&
  194. file_exists($postedFile['tmp_name'])
  195. )
  196. {
  197. /** @var Translate\IO\File $tmpFile */
  198. $tmpFile = Translate\IO\File::generateTemporalFile('translate', $suffix, $timeToLive);
  199. if (@copy($postedFile['tmp_name'], $tmpFile->getPhysicalPath()))
  200. {
  201. $this->archiveFileType = $suffix;
  202. $this->archiveFilePath = $tmpFile->getPhysicalPath();
  203. return true;
  204. }
  205. }
  206. $this->addError(new Main\Error(Loc::getMessage('TR_IMPORT_EMPTY_FILE_ERROR')));
  207. return false;
  208. }
  209. /**
  210. * Deletes temporal folder and files.
  211. *
  212. * @return array
  213. */
  214. public function finalizeAction()
  215. {
  216. $settings = $this->getProgressParameters();
  217. // delete tmp files
  218. if (!empty($settings['tmpFolderPath']))
  219. {
  220. $tempLanguageDir = new Translate\IO\Directory($settings['tmpFolderPath']);
  221. if ($tempLanguageDir->isExists())
  222. {
  223. if ($tempLanguageDir->delete() !== true)
  224. {
  225. $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_DELETE_TEMP_FOLDER')));
  226. }
  227. }
  228. }
  229. return array(
  230. 'STATUS' => Translate\Controller\STATUS_COMPLETED
  231. );
  232. }
  233. /**
  234. * Deletes generated file.
  235. *
  236. * @return array
  237. */
  238. public function clearAction()
  239. {
  240. return $this->purgeAction();
  241. }
  242. /**
  243. * Deletes generated file.
  244. *
  245. * @return array
  246. */
  247. public function purgeAction()
  248. {
  249. $settings = $this->getProgressParameters();
  250. if (!empty($settings['archiveFilePath']))
  251. {
  252. $path = new Main\IO\File($settings['archiveFilePath']);
  253. if ($path->isExists())
  254. {
  255. $path->delete();
  256. }
  257. }
  258. return array(
  259. 'SUMMARY' => Loc::getMessage('TR_EXPORT_FILE_DROPPED'),
  260. 'STATUS' => Translate\Controller\STATUS_COMPLETED
  261. );
  262. }
  263. /**
  264. * Deletes generated file.
  265. *
  266. * @return array
  267. */
  268. public function cancelAction()
  269. {
  270. $this->finalizeAction();
  271. $this->purgeAction();
  272. $this->clearProgressParameters();
  273. $cancelingAction = $this->request->get('cancelingAction');
  274. $summary =
  275. in_array($cancelingAction, [self::ACTION_COLLECT, self::ACTION_PACK]) ?
  276. Loc::getMessage('TR_EXPORT_ACTION_CANCELED') :
  277. Loc::getMessage('TR_IMPORT_ACTION_CANCELED')
  278. ;
  279. return array(
  280. 'SUMMARY' => $summary,
  281. 'STATUS' => Translate\Controller\STATUS_COMPLETED
  282. );
  283. }
  284. /**
  285. * Starts downloading genereted file.
  286. *
  287. * @return \Bitrix\Main\HttpResponse|void
  288. */
  289. public function downloadAction()
  290. {
  291. $settings = $this->getProgressParameters();
  292. if (!empty($settings['downloadParams']['filePath']) && !empty($settings['downloadParams']['fileName']))
  293. {
  294. $file = new Main\IO\File($settings['downloadParams']['filePath']);
  295. if ($file->isExists())
  296. {
  297. $response = new Main\Engine\Response\File(
  298. $file->getPath(),
  299. $settings['downloadParams']['fileName'],
  300. $settings['downloadParams']['fileType']
  301. );
  302. return $response;
  303. }
  304. }
  305. $this->addError(new Error('File not found'));
  306. }
  307. /**
  308. * Returns progress option name
  309. *
  310. * @return string
  311. */
  312. public function getProgressParameterOptionName()
  313. {
  314. return self::SETTING_ID;
  315. }
  316. /**
  317. * Gets actual maximum upload size.
  318. *
  319. * @return int
  320. */
  321. public static function getMaxUploadSize()
  322. {
  323. static $maxUploadSize = -1;
  324. if ($maxUploadSize < 0)
  325. {
  326. $maxUploadSize = min(
  327. \CUtil::unformat('32M'),
  328. \CUtil::unformat(ini_get('post_max_size')),
  329. \CUtil::unformat(ini_get('upload_max_filesize'))
  330. );
  331. }
  332. return $maxUploadSize;
  333. }
  334. }