Edit.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Email\Block\Adminhtml\Template;
  7. use Magento\Backend\Block\Widget;
  8. use Magento\Backend\Block\Widget\ContainerInterface;
  9. use Magento\Email\Model\BackendTemplate;
  10. /**
  11. * Adminhtml system template edit block
  12. *
  13. * @author Magento Core Team <core@magentocommerce.com>
  14. * @method array getTemplateOptions()
  15. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  16. */
  17. class Edit extends Widget implements ContainerInterface
  18. {
  19. /**
  20. * @var \Magento\Framework\Registry
  21. * @deprecated 101.0.0 since 2.3.0 in favor of stateful global objects elimination.
  22. */
  23. protected $_registryManager;
  24. /**
  25. * @var \Magento\Backend\Model\Menu\Config
  26. */
  27. protected $_menuConfig;
  28. /**
  29. * @var \Magento\Config\Model\Config\Structure
  30. */
  31. protected $_configStructure;
  32. /**
  33. * @var \Magento\Email\Model\Template\Config
  34. */
  35. private $_emailConfig;
  36. /**
  37. * Template file
  38. *
  39. * @var string
  40. */
  41. protected $_template = 'Magento_Email::template/edit.phtml';
  42. /**
  43. * @var \Magento\Framework\Json\EncoderInterface
  44. */
  45. protected $_jsonEncoder;
  46. /**
  47. * @var \Magento\Framework\Json\Helper\Data
  48. */
  49. protected $jsonHelper;
  50. /**
  51. * @var \Magento\Backend\Block\Widget\Button\ButtonList
  52. */
  53. protected $buttonList;
  54. /**
  55. * @var \Magento\Backend\Block\Widget\Button\ToolbarInterface
  56. */
  57. protected $toolbar;
  58. /**
  59. * @param \Magento\Backend\Block\Template\Context $context
  60. * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
  61. * @param \Magento\Framework\Registry $registry
  62. * @param \Magento\Backend\Model\Menu\Config $menuConfig
  63. * @param \Magento\Config\Model\Config\Structure $configStructure
  64. * @param \Magento\Email\Model\Template\Config $emailConfig
  65. * @param \Magento\Framework\Json\Helper\Data $jsonHelper
  66. * @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
  67. * @param \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar
  68. * @param array $data
  69. *
  70. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  71. */
  72. public function __construct(
  73. \Magento\Backend\Block\Template\Context $context,
  74. \Magento\Framework\Json\EncoderInterface $jsonEncoder,
  75. \Magento\Framework\Registry $registry,
  76. \Magento\Backend\Model\Menu\Config $menuConfig,
  77. \Magento\Config\Model\Config\Structure $configStructure,
  78. \Magento\Email\Model\Template\Config $emailConfig,
  79. \Magento\Framework\Json\Helper\Data $jsonHelper,
  80. \Magento\Backend\Block\Widget\Button\ButtonList $buttonList,
  81. \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar,
  82. array $data = []
  83. ) {
  84. $this->jsonHelper = $jsonHelper;
  85. $this->_jsonEncoder = $jsonEncoder;
  86. $this->_registryManager = $registry;
  87. $this->_menuConfig = $menuConfig;
  88. $this->_configStructure = $configStructure;
  89. $this->_emailConfig = $emailConfig;
  90. $this->buttonList = $buttonList;
  91. $this->toolbar = $toolbar;
  92. parent::__construct($context, $data);
  93. }
  94. /**
  95. * {@inheritdoc}
  96. */
  97. public function updateButton($buttonId, $key, $data)
  98. {
  99. $this->buttonList->update($buttonId, $key, $data);
  100. return $this;
  101. }
  102. /**
  103. * {@inheritdoc}
  104. */
  105. public function canRender(\Magento\Backend\Block\Widget\Button\Item $item)
  106. {
  107. return !$item->isDeleted();
  108. }
  109. /**
  110. * {@inheritdoc}
  111. */
  112. public function removeButton($buttonId)
  113. {
  114. $this->buttonList->remove($buttonId);
  115. return $this;
  116. }
  117. /**
  118. * Prepare layout
  119. *
  120. * @return $this
  121. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  122. */
  123. protected function _prepareLayout()
  124. {
  125. $this->buttonList->add(
  126. 'back',
  127. [
  128. 'label' => __('Back'),
  129. 'onclick' => "window.location.href = '" . $this->getUrl('adminhtml/*') . "'",
  130. 'class' => 'back'
  131. ]
  132. );
  133. $this->buttonList->add(
  134. 'reset',
  135. ['label' => __('Reset'), 'onclick' => 'window.location.href = window.location.href']
  136. );
  137. if ($this->getEditMode()) {
  138. $this->buttonList->add(
  139. 'delete',
  140. [
  141. 'label' => __('Delete Template'),
  142. 'data_attribute' => [
  143. 'role' => 'template-delete',
  144. ],
  145. 'class' => 'delete'
  146. ]
  147. );
  148. }
  149. if (!$this->isTextType()) {
  150. $this->buttonList->add(
  151. 'to_plain',
  152. [
  153. 'label' => __('Convert to Plain Text'),
  154. 'data_attribute' => [
  155. 'role' => 'template-strip',
  156. ],
  157. 'id' => 'convert_button'
  158. ]
  159. );
  160. $this->buttonList->add(
  161. 'to_html',
  162. [
  163. 'label' => __('Return Html Version'),
  164. 'data_attribute' => [
  165. 'role' => 'template-unstrip',
  166. ],
  167. 'id' => 'convert_button_back',
  168. 'style' => 'display:none'
  169. ]
  170. );
  171. }
  172. $this->buttonList->add(
  173. 'preview',
  174. [
  175. 'label' => __('Preview Template'),
  176. 'data_attribute' => [
  177. 'role' => 'template-preview',
  178. ]
  179. ]
  180. );
  181. $this->buttonList->add(
  182. 'save',
  183. [
  184. 'label' => __('Save Template'),
  185. 'data_attribute' => [
  186. 'role' => 'template-save',
  187. ],
  188. 'class' => 'save primary save-template'
  189. ]
  190. );
  191. $this->buttonList->add(
  192. 'load',
  193. [
  194. 'label' => __('Load Template'),
  195. 'data_attribute' => [
  196. 'role' => 'template-load',
  197. ],
  198. 'type' => 'button',
  199. 'class' => 'save'
  200. ],
  201. 0,
  202. 0,
  203. null
  204. );
  205. $this->toolbar->pushButtons($this, $this->buttonList);
  206. $this->addChild(
  207. 'form',
  208. \Magento\Email\Block\Adminhtml\Template\Edit\Form::class,
  209. [
  210. 'email_template' => $this->getEmailTemplate()
  211. ]
  212. );
  213. return parent::_prepareLayout();
  214. }
  215. /**
  216. * {@inheritdoc}
  217. */
  218. public function addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
  219. {
  220. $this->buttonList->add($buttonId, $data, $level, $sortOrder, $region);
  221. return $this;
  222. }
  223. /**
  224. * Collect, sort and set template options
  225. *
  226. * @return $this
  227. */
  228. protected function _beforeToHtml()
  229. {
  230. $groupedOptions = [];
  231. foreach ($this->_getDefaultTemplatesAsOptionsArray() as $option) {
  232. $groupedOptions[$option['group']][] = $option;
  233. }
  234. ksort($groupedOptions);
  235. $this->setData('template_options', $groupedOptions);
  236. return parent::_beforeToHtml();
  237. }
  238. /**
  239. * Get default templates as options array
  240. *
  241. * @return array
  242. */
  243. protected function _getDefaultTemplatesAsOptionsArray()
  244. {
  245. $options = array_merge(
  246. [['value' => '', 'label' => '', 'group' => '']],
  247. $this->_emailConfig->getAvailableTemplates()
  248. );
  249. uasort(
  250. $options,
  251. function (array $firstElement, array $secondElement) {
  252. return strcmp($firstElement['label'], $secondElement['label']);
  253. }
  254. );
  255. return $options;
  256. }
  257. /**
  258. * Get the html element for load button
  259. *
  260. * @return string
  261. */
  262. public function getLoadButtonHtml()
  263. {
  264. return $this->getChildHtml('load_button');
  265. }
  266. /**
  267. * Return edit flag for block
  268. *
  269. * @return int|null
  270. */
  271. public function getEditMode()
  272. {
  273. return $this->getEmailTemplate()->getId();
  274. }
  275. /**
  276. * Return header text for form
  277. *
  278. * @return \Magento\Framework\Phrase
  279. */
  280. public function getHeaderText()
  281. {
  282. if ($this->getEditMode()) {
  283. return __('Edit Email Template');
  284. }
  285. return __('New Email Template');
  286. }
  287. /**
  288. * Return form block HTML
  289. *
  290. * @return string
  291. */
  292. public function getFormHtml()
  293. {
  294. return $this->getChildHtml('form');
  295. }
  296. /**
  297. * Return action url for form
  298. *
  299. * @return string
  300. */
  301. public function getSaveUrl()
  302. {
  303. return $this->getUrl('adminhtml/*/save', ['_current' => true]);
  304. }
  305. /**
  306. * Return preview action url for form
  307. *
  308. * @return string
  309. */
  310. public function getPreviewUrl()
  311. {
  312. return $this->getUrl('adminhtml/*/preview');
  313. }
  314. /**
  315. * Return true if template type is text; return false otherwise
  316. *
  317. * @return bool
  318. */
  319. public function isTextType()
  320. {
  321. return $this->getEmailTemplate()->isPlain();
  322. }
  323. /**
  324. * Return template type from template object
  325. *
  326. * @return int
  327. */
  328. public function getTemplateType()
  329. {
  330. return $this->getEmailTemplate()->getType();
  331. }
  332. /**
  333. * Return delete url for customer group
  334. *
  335. * @return string
  336. */
  337. public function getDeleteUrl()
  338. {
  339. return $this->getUrl('adminhtml/*/delete', ['_current' => true]);
  340. }
  341. /**
  342. * Retrieve email template model
  343. *
  344. * @return \Magento\Email\Model\Template
  345. */
  346. public function getEmailTemplate()
  347. {
  348. return $this->getData('email_template');
  349. }
  350. /**
  351. * Load template url
  352. *
  353. * @return string
  354. */
  355. public function getLoadUrl()
  356. {
  357. return $this->getUrl('adminhtml/*/defaultTemplate');
  358. }
  359. /**
  360. * Get paths of where current template is currently used
  361. *
  362. * @param bool $asJSON
  363. * @return string
  364. */
  365. public function getCurrentlyUsedForPaths($asJSON = true)
  366. {
  367. /** @var $template BackendTemplate */
  368. $template = $this->getEmailTemplate();
  369. $paths = $template->getSystemConfigPathsWhereCurrentlyUsed();
  370. $pathsParts = $this->_getSystemConfigPathsParts($paths);
  371. if ($asJSON) {
  372. return $this->_jsonEncoder->encode($pathsParts);
  373. }
  374. return $pathsParts;
  375. }
  376. /**
  377. * Convert xml config paths to decorated names
  378. *
  379. * @param array $paths
  380. * @return array
  381. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  382. */
  383. protected function _getSystemConfigPathsParts($paths)
  384. {
  385. $result = $urlParams = $prefixParts = [];
  386. $scopeLabel = __('Default Config');
  387. if ($paths) {
  388. /** @var $menu \Magento\Backend\Model\Menu */
  389. $menu = $this->_menuConfig->getMenu();
  390. $item = $menu->get('Magento_Backend::stores');
  391. // create prefix path parts
  392. $prefixParts[] = ['title' => __($item->getTitle())];
  393. $item = $menu->get('Magento_Config::system_config');
  394. $prefixParts[] = [
  395. 'title' => __($item->getTitle()),
  396. 'url' => $this->getUrl('adminhtml/system_config/'),
  397. ];
  398. $pathParts = $prefixParts;
  399. foreach ($paths as $pathData) {
  400. $pathDataParts = explode('/', $pathData['path']);
  401. $sectionName = array_shift($pathDataParts);
  402. $urlParams = ['section' => $sectionName];
  403. if (isset($pathData['scope']) && isset($pathData['scope_id'])) {
  404. switch ($pathData['scope']) {
  405. case 'stores':
  406. $store = $this->_storeManager->getStore($pathData['scope_id']);
  407. if ($store) {
  408. $urlParams['website'] = $store->getWebsite()->getCode();
  409. $urlParams['store'] = $store->getCode();
  410. $scopeLabel = $store->getWebsite()->getName() . '/' . $store->getName();
  411. }
  412. break;
  413. case 'websites':
  414. $website = $this->_storeManager->getWebsite($pathData['scope_id']);
  415. if ($website) {
  416. $urlParams['website'] = $website->getCode();
  417. $scopeLabel = $website->getName();
  418. }
  419. break;
  420. default:
  421. break;
  422. }
  423. }
  424. $pathParts[] = [
  425. 'title' => $this->_configStructure->getElement($sectionName)->getLabel(),
  426. 'url' => $this->getUrl('adminhtml/system_config/edit', $urlParams),
  427. ];
  428. $elementPathParts = [$sectionName];
  429. while (count($pathDataParts) != 1) {
  430. $elementPathParts[] = array_shift($pathDataParts);
  431. $pathParts[] = [
  432. 'title' => $this->_configStructure->getElementByPathParts($elementPathParts)->getLabel(),
  433. ];
  434. }
  435. $elementPathParts[] = array_shift($pathDataParts);
  436. $pathParts[] = [
  437. 'title' => $this->_configStructure->getElementByPathParts($elementPathParts)->getLabel(),
  438. 'scope' => $scopeLabel,
  439. ];
  440. $result[] = $pathParts;
  441. $pathParts = $prefixParts;
  442. }
  443. }
  444. return $result;
  445. }
  446. /**
  447. * Return original template code of current template
  448. *
  449. * @return string
  450. */
  451. public function getOrigTemplateCode()
  452. {
  453. return $this->getEmailTemplate()->getOrigTemplateCode();
  454. }
  455. }