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

/modules/translate/lib/io/directory.php

https://gitlab.com/alexprowars/bitrix
PHP | 294 lines | 213 code | 36 blank | 45 comment | 25 complexity | a4a57de98acb46c640da85f18c41dadf MD5 | raw file
  1. <?php declare(strict_types = 1);
  2. namespace Bitrix\Translate\IO;
  3. use Bitrix\Translate;
  4. use Bitrix\Main;
  5. class Directory
  6. extends Main\IO\Directory
  7. implements Translate\IErrorable
  8. {
  9. // trait implements interface Translate\IErrorable
  10. use Translate\Error;
  11. /**
  12. * Constructor.
  13. * @param string $path Folder path.
  14. * @param string|null $siteId Site id.
  15. */
  16. public function __construct(string $path, ?string $siteId = null)
  17. {
  18. parent::__construct($path, $siteId);
  19. }
  20. /**
  21. * Creates temporal directory.
  22. *
  23. * @param string $prefix Name prefix.
  24. * @param int $timeToLive Hours to keep files alive.
  25. *
  26. * @return self
  27. */
  28. public static function generateTemporalDirectory(string $prefix, int $timeToLive = 3): self
  29. {
  30. $tempDirPath = \CTempFile::GetDirectoryName($timeToLive, array($prefix, uniqid($prefix, true)));
  31. $tempDir = new static($tempDirPath);
  32. if (!$tempDir->isExists())
  33. {
  34. $tempDir->create();
  35. }
  36. return $tempDir;
  37. }
  38. /**
  39. * Copy full structure of the folders with its contents.
  40. *
  41. * @param Main\IO\Directory $target Destination folder.
  42. * @param bool $reWrite Rewrire files.
  43. * @param bool $recursive Recurcivly follow folder structure.
  44. * @param bool $convertEncoding Allow encoding conver.
  45. * @param string $sourceEncoding Encoding of source files.
  46. * @param string $targetEncoding Target encoding.
  47. *
  48. * @return boolean
  49. */
  50. public function copy(
  51. Main\IO\Directory $target,
  52. bool $reWrite = true,
  53. bool $recursive = false,
  54. bool $convertEncoding = false,
  55. string $sourceEncoding = '',
  56. string $targetEncoding = ''
  57. ): bool
  58. {
  59. if (mb_strpos($target->getPhysicalPath(), $this->getPhysicalPath()) === 0)
  60. {
  61. $this->addError(new Main\Error('Destination is inside in the source folder.'));
  62. return false;
  63. }
  64. if (!$this->isExists())
  65. {
  66. $this->addError(new Main\Error('Source is not exists.'));
  67. return false;
  68. }
  69. if (!$target->isExists())
  70. {
  71. $target->create();
  72. }
  73. $retFlag = true;
  74. $children = $this->getChildren();
  75. /** @var Main\IO\Directory $dir */
  76. foreach ($children as $entry)
  77. {
  78. if (in_array($entry->getName(), Translate\IGNORE_FS_NAMES, true))
  79. {
  80. continue;
  81. }
  82. if (
  83. ($entry instanceof Main\IO\Directory) &&
  84. $entry->isDirectory() &&
  85. $recursive
  86. )
  87. {
  88. $source = new self($entry->getPhysicalPath());
  89. $res = $source->copy(
  90. (new Main\IO\Directory($target->getPhysicalPath(). '/'. $entry->getName())),
  91. $reWrite,
  92. $recursive,
  93. $convertEncoding,
  94. $sourceEncoding,
  95. $targetEncoding
  96. );
  97. if (!$res)
  98. {
  99. $retFlag = false;
  100. $this->addErrors($source->getErrors());
  101. }
  102. }
  103. elseif (
  104. ($entry instanceof Main\IO\File) &&
  105. $entry->isFile()
  106. )
  107. {
  108. $file = new Main\IO\File($target->getPhysicalPath(). '/'. $entry->getName());
  109. if ($file->isExists() && !$reWrite)
  110. {
  111. continue;
  112. }
  113. try
  114. {
  115. $content = $entry->getContents();
  116. $content = str_replace(array("\r\n", "\r"), array("\n", "\n"), $content);
  117. if ($convertEncoding)
  118. {
  119. $content = \Bitrix\Main\Text\Encoding::convertEncoding($content, $sourceEncoding, $targetEncoding);
  120. }
  121. $file->putContents($content);
  122. }
  123. catch (Main\IO\IoException $exception)
  124. {
  125. $retFlag = false;
  126. $this->addError(new Main\Error($exception->getMessage()));
  127. }
  128. }
  129. }
  130. return $retFlag;
  131. }
  132. /**
  133. * Copy only language folders with content.
  134. *
  135. * @param Main\IO\Directory $target Destination folder.
  136. * @param string $languageId Language to filter.
  137. * @param bool $convertEncoding Allow encoding conver.
  138. * @param string $sourceEncoding Encoding of source files.
  139. * @param string $targetEncoding Target encoding.
  140. *
  141. * @return boolean
  142. */
  143. public function copyLangOnly(
  144. Main\IO\Directory $target,
  145. string $languageId,
  146. bool $convertEncoding = false,
  147. string $sourceEncoding = '',
  148. string $targetEncoding = ''
  149. ): bool
  150. {
  151. if (mb_strpos($target->getPhysicalPath(), $this->getPhysicalPath()) === 0)
  152. {
  153. $this->addError(new Main\Error('Destination is inside in the source folder.'));
  154. return false;
  155. }
  156. if (!$this->isExists())
  157. {
  158. $this->addError(new Main\Error('Source is not exists.'));
  159. return false;
  160. }
  161. $children = $this->getChildren();
  162. $retFlag = true;
  163. /** @var Main\IO\Directory $dir */
  164. foreach ($children as $dir)
  165. {
  166. $dirName = $dir->getName();
  167. if (
  168. !$dir instanceof Main\IO\Directory ||
  169. !$dir->isDirectory() ||
  170. in_array($dirName, Translate\IGNORE_FS_NAMES, true)
  171. )
  172. {
  173. continue;
  174. }
  175. if ($dirName === 'lang' || $dirName === 'payment')
  176. {
  177. $source = new self($dir->getPhysicalPath(). '/'. $languageId);
  178. if ($source->isExists())
  179. {
  180. if (!$target->isExists())
  181. {
  182. $target->create();
  183. }
  184. $targetDir = $target->createSubdirectory($dirName)->createSubdirectory($languageId);
  185. $res = $source->copy(
  186. $targetDir,
  187. true,
  188. true,
  189. $convertEncoding,
  190. $sourceEncoding,
  191. $targetEncoding
  192. );
  193. if (!$res)
  194. {
  195. $retFlag = false;
  196. $this->addErrors($source->getErrors());
  197. }
  198. }
  199. }
  200. else
  201. {
  202. $source = new self($dir->getPhysicalPath());
  203. $res = $source->copyLangOnly(
  204. (new Main\IO\Directory($target->getPhysicalPath(). '/'. $dirName)),
  205. $languageId,
  206. $convertEncoding,
  207. $sourceEncoding,
  208. $targetEncoding
  209. );
  210. if (!$res)
  211. {
  212. $retFlag = false;
  213. $this->addErrors($source->getErrors());
  214. }
  215. }
  216. }
  217. return $retFlag;
  218. }
  219. /**
  220. * Wipes folder out of children.
  221. *
  222. * @param \Closure|null $filter Filter function.
  223. * @return bool
  224. */
  225. public function wipe(?\Closure $filter = null): bool
  226. {
  227. if (!$this->isExists())
  228. {
  229. throw new Main\IO\FileNotFoundException($this->originalPath);
  230. }
  231. if($this->getPath() === '/')
  232. {
  233. throw new Main\IO\InvalidPathException($this->originalPath);
  234. }
  235. $children = $this->getChildren();
  236. $result = true;
  237. foreach ($children as $entry)
  238. {
  239. if ($filter instanceof \Closure)
  240. {
  241. if ($filter($entry) !== true)
  242. {
  243. continue;
  244. }
  245. }
  246. $result = $entry->delete();
  247. if (!$result)
  248. {
  249. break;
  250. }
  251. }
  252. if ($result)
  253. {
  254. clearstatcache();
  255. }
  256. return $result;
  257. }
  258. }