Storage.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Theme storage helper
  8. */
  9. namespace Magento\Theme\Helper;
  10. use Magento\Framework\App\Filesystem\DirectoryList;
  11. /**
  12. * @api
  13. * @since 100.0.2
  14. */
  15. class Storage extends \Magento\Framework\App\Helper\AbstractHelper
  16. {
  17. /**
  18. * Parameter name of node
  19. */
  20. const PARAM_NODE = 'node';
  21. /**
  22. * Parameter name of content type
  23. */
  24. const PARAM_CONTENT_TYPE = 'content_type';
  25. /**
  26. * Parameter name of theme identification number
  27. */
  28. const PARAM_THEME_ID = 'theme_id';
  29. /**
  30. * Parameter name of filename
  31. */
  32. const PARAM_FILENAME = 'filename';
  33. /**
  34. * Root node value identification number
  35. */
  36. const NODE_ROOT = 'root';
  37. /**
  38. * Display name for images storage type
  39. */
  40. const IMAGES = 'Images';
  41. /**
  42. * Display name for fonts storage type
  43. */
  44. const FONTS = 'Fonts';
  45. /**
  46. * Current directory path
  47. *
  48. * @var string
  49. */
  50. protected $_currentPath;
  51. /**
  52. * Current storage root path
  53. *
  54. * @var string
  55. */
  56. protected $_storageRoot;
  57. /**
  58. * Magento filesystem
  59. *
  60. * @var \Magento\Framework\Filesystem
  61. */
  62. protected $filesystem;
  63. /**
  64. * @var \Magento\Backend\Model\Session
  65. */
  66. protected $_session;
  67. /**
  68. * @var \Magento\Framework\View\Design\Theme\FlyweightFactory
  69. */
  70. protected $_themeFactory;
  71. /**
  72. * @var \Magento\Framework\Filesystem\Directory\Write
  73. */
  74. protected $mediaDirectoryWrite;
  75. /**
  76. * @param \Magento\Framework\App\Helper\Context $context
  77. * @param \Magento\Framework\Filesystem $filesystem
  78. * @param \Magento\Backend\Model\Session $session
  79. * @param \Magento\Framework\View\Design\Theme\FlyweightFactory $themeFactory
  80. */
  81. public function __construct(
  82. \Magento\Framework\App\Helper\Context $context,
  83. \Magento\Framework\Filesystem $filesystem,
  84. \Magento\Backend\Model\Session $session,
  85. \Magento\Framework\View\Design\Theme\FlyweightFactory $themeFactory
  86. ) {
  87. parent::__construct($context);
  88. $this->filesystem = $filesystem;
  89. $this->_session = $session;
  90. $this->_themeFactory = $themeFactory;
  91. $this->mediaDirectoryWrite = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
  92. $this->mediaDirectoryWrite->create($this->mediaDirectoryWrite->getRelativePath($this->getStorageRoot()));
  93. }
  94. /**
  95. * Convert path to id
  96. *
  97. * @param string $path
  98. * @return string
  99. */
  100. public function convertPathToId($path)
  101. {
  102. $path = str_replace($this->getStorageRoot(), '', $path);
  103. return $this->urlEncoder->encode($path);
  104. }
  105. /**
  106. * Convert id to path
  107. *
  108. * @param string $value
  109. * @return string
  110. */
  111. public function convertIdToPath($value)
  112. {
  113. $path = $this->urlDecoder->decode($value);
  114. if (!strstr($path, $this->getStorageRoot())) {
  115. $path = $this->getStorageRoot() . $path;
  116. }
  117. return $path;
  118. }
  119. /**
  120. * Get short file name
  121. *
  122. * @param string $filename
  123. * @param int $maxLength
  124. * @return string
  125. */
  126. public function getShortFilename($filename, $maxLength = 20)
  127. {
  128. return strlen($filename) <= $maxLength ? $filename : substr($filename, 0, $maxLength) . '...';
  129. }
  130. /**
  131. * Get storage root directory
  132. *
  133. * @return string
  134. */
  135. public function getStorageRoot()
  136. {
  137. if (null === $this->_storageRoot) {
  138. $this->_storageRoot = implode(
  139. '/',
  140. [$this->_getTheme()->getCustomization()->getCustomizationPath(), $this->getStorageType()]
  141. );
  142. }
  143. return $this->_storageRoot;
  144. }
  145. /**
  146. * Get theme module for custom static files
  147. *
  148. * @return \Magento\Theme\Model\Theme
  149. * @throws \InvalidArgumentException
  150. */
  151. protected function _getTheme()
  152. {
  153. $themeId = $this->_getRequest()->getParam(self::PARAM_THEME_ID);
  154. $theme = $this->_themeFactory->create($themeId);
  155. if (!$themeId || !$theme) {
  156. throw new \InvalidArgumentException('Theme was not found.');
  157. }
  158. return $theme;
  159. }
  160. /**
  161. * Get storage type
  162. *
  163. * @return string
  164. * @throws \Magento\Framework\Exception\LocalizedException
  165. */
  166. public function getStorageType()
  167. {
  168. $allowedTypes = [
  169. \Magento\Theme\Model\Wysiwyg\Storage::TYPE_FONT,
  170. \Magento\Theme\Model\Wysiwyg\Storage::TYPE_IMAGE,
  171. ];
  172. $type = (string)$this->_getRequest()->getParam(self::PARAM_CONTENT_TYPE);
  173. if (!in_array($type, $allowedTypes)) {
  174. throw new \Magento\Framework\Exception\LocalizedException(__('Invalid type'));
  175. }
  176. return $type;
  177. }
  178. /**
  179. * Relative url to static content
  180. *
  181. * @return string
  182. */
  183. public function getRelativeUrl()
  184. {
  185. $pathPieces = ['..', $this->getStorageType()];
  186. $node = $this->_getRequest()->getParam(self::PARAM_NODE);
  187. if ($node !== self::NODE_ROOT) {
  188. $node = $this->urlDecoder->decode($node);
  189. $nodes = explode('/', trim($node, '/'));
  190. $pathPieces = array_merge($pathPieces, $nodes);
  191. }
  192. $pathPieces[] = $this->urlDecoder->decode($this->_getRequest()->getParam(self::PARAM_FILENAME));
  193. return implode('/', $pathPieces);
  194. }
  195. /**
  196. * Get current path
  197. *
  198. * @return string
  199. */
  200. public function getCurrentPath()
  201. {
  202. if (!$this->_currentPath) {
  203. $currentPath = $this->getStorageRoot();
  204. $path = $this->_getRequest()->getParam(self::PARAM_NODE);
  205. if ($path && $path !== self::NODE_ROOT) {
  206. $path = $this->convertIdToPath($path);
  207. if ($this->mediaDirectoryWrite->isDirectory($path) && 0 === strpos($path, $currentPath)) {
  208. $currentPath = $this->mediaDirectoryWrite->getRelativePath($path);
  209. }
  210. }
  211. $this->_currentPath = $currentPath;
  212. }
  213. return $this->_currentPath;
  214. }
  215. /**
  216. * Get thumbnail directory for path
  217. *
  218. * @param string $path
  219. * @return string
  220. */
  221. public function getThumbnailDirectory($path)
  222. {
  223. return pathinfo($path, PATHINFO_DIRNAME) . '/' . \Magento\Theme\Model\Wysiwyg\Storage::THUMBNAIL_DIRECTORY;
  224. }
  225. /**
  226. * Get thumbnail path in current directory by image name
  227. *
  228. * @param string $imageName
  229. * @return string
  230. * @throws \InvalidArgumentException
  231. */
  232. public function getThumbnailPath($imageName)
  233. {
  234. $imagePath = $this->getCurrentPath() . '/' . $imageName;
  235. if (!$this->mediaDirectoryWrite->isExist($imagePath) || 0 !== strpos($imagePath, $this->getStorageRoot())) {
  236. throw new \InvalidArgumentException('The image not found.');
  237. }
  238. return $this->getThumbnailDirectory($imagePath) . '/' . pathinfo($imageName, PATHINFO_BASENAME);
  239. }
  240. /**
  241. * Request params for selected theme
  242. *
  243. * @return array
  244. */
  245. public function getRequestParams()
  246. {
  247. $themeId = $this->_getRequest()->getParam(self::PARAM_THEME_ID);
  248. $contentType = $this->_getRequest()->getParam(self::PARAM_CONTENT_TYPE);
  249. $node = $this->_getRequest()->getParam(self::PARAM_NODE);
  250. return [
  251. self::PARAM_THEME_ID => $themeId,
  252. self::PARAM_CONTENT_TYPE => $contentType,
  253. self::PARAM_NODE => $node
  254. ];
  255. }
  256. /**
  257. * Get allowed extensions by type
  258. *
  259. * @return string[]
  260. * @throws \Magento\Framework\Exception\LocalizedException
  261. */
  262. public function getAllowedExtensionsByType()
  263. {
  264. return $this->getStorageType() == \Magento\Theme\Model\Wysiwyg\Storage::TYPE_FONT
  265. ? ['ttf', 'otf', 'eot', 'svg', 'woff']
  266. : ['jpg', 'jpeg', 'gif', 'png', 'xbm', 'wbmp'];
  267. }
  268. /**
  269. * Get storage type name for display.
  270. *
  271. * @return string
  272. * @throws \Magento\Framework\Exception\LocalizedException
  273. */
  274. public function getStorageTypeName()
  275. {
  276. return $this->getStorageType() == \Magento\Theme\Model\Wysiwyg\Storage::TYPE_FONT
  277. ? self::FONTS
  278. : self::IMAGES;
  279. }
  280. /**
  281. * Get session model
  282. *
  283. * @return \Magento\Backend\Model\Session
  284. */
  285. public function getSession()
  286. {
  287. return $this->_session;
  288. }
  289. }