Template.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Email\Model;
  7. use Magento\Store\Model\StoreManagerInterface;
  8. /**
  9. * Template model
  10. *
  11. * @method string getTemplateCode()
  12. * @method \Magento\Email\Model\Template setTemplateCode(string $value)
  13. * @method string getTemplateText()
  14. * @method \Magento\Email\Model\Template setTemplateText(string $value)
  15. * @method string getTemplateStyles()
  16. * @method \Magento\Email\Model\Template setTemplateStyles(string $value)
  17. * @method int getTemplateType()
  18. * @method \Magento\Email\Model\Template setTemplateType(int $value)
  19. * @method string getTemplateSubject()
  20. * @method \Magento\Email\Model\Template setTemplateSubject(string $value)
  21. * @method string getTemplateSenderName()
  22. * @method \Magento\Email\Model\Template setTemplateSenderName(string $value)
  23. * @method string getTemplateSenderEmail()
  24. * @method \Magento\Email\Model\Template setTemplateSenderEmail(string $value)
  25. * @method string getAddedAt()
  26. * @method \Magento\Email\Model\Template setAddedAt(string $value)
  27. * @method string getModifiedAt()
  28. * @method \Magento\Email\Model\Template setModifiedAt(string $value)
  29. * @method string getOrigTemplateCode()
  30. * @method \Magento\Email\Model\Template setOrigTemplateCode(string $value)
  31. * @method string getOrigTemplateVariables()
  32. * @method \Magento\Email\Model\Template setOrigTemplateVariables(string $value)
  33. *
  34. * @api
  35. *
  36. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  37. * @since 100.0.2
  38. */
  39. class Template extends AbstractTemplate implements \Magento\Framework\Mail\TemplateInterface
  40. {
  41. /**
  42. * Configuration path to source of Return-Path and whether it should be set at all
  43. * @deprecated
  44. * @see \Magento\Email\Model\Transport::XML_PATH_SENDING_SET_RETURN_PATH
  45. */
  46. const XML_PATH_SENDING_SET_RETURN_PATH = 'system/smtp/set_return_path';
  47. /**
  48. * Configuration path for custom Return-Path email
  49. * @deprecated
  50. * @see \Magento\Email\Model\Transport::XML_PATH_SENDING_RETURN_PATH_EMAIL
  51. */
  52. const XML_PATH_SENDING_RETURN_PATH_EMAIL = 'system/smtp/return_path_email';
  53. /**
  54. * Config path to mail sending setting that shows if email communications are disabled
  55. * @deprecated
  56. */
  57. const XML_PATH_SYSTEM_SMTP_DISABLE = 'system/smtp/disable';
  58. /**
  59. * BCC list
  60. *
  61. * @var array
  62. */
  63. protected $_bcc = [];
  64. /**
  65. * Return path
  66. *
  67. * @var string
  68. */
  69. protected $_returnPath = '';
  70. /**
  71. * Reply address
  72. *
  73. * @var string
  74. */
  75. protected $_replyTo = '';
  76. /**
  77. * @var array
  78. */
  79. protected $_vars = [];
  80. /**
  81. * @var \Exception|null
  82. */
  83. protected $_sendingException = null;
  84. /**
  85. * Email filter factory
  86. *
  87. * @var \Magento\Email\Model\Template\FilterFactory
  88. */
  89. private $filterFactory;
  90. /**
  91. * @var \Magento\Framework\Serialize\Serializer\Json
  92. */
  93. private $serializer;
  94. /**
  95. * Template constructor.
  96. *
  97. * @param \Magento\Framework\Model\Context $context
  98. * @param \Magento\Framework\View\DesignInterface $design
  99. * @param \Magento\Framework\Registry $registry
  100. * @param \Magento\Store\Model\App\Emulation $appEmulation
  101. * @param StoreManagerInterface $storeManager
  102. * @param \Magento\Framework\View\Asset\Repository $assetRepo
  103. * @param \Magento\Framework\Filesystem $filesystem
  104. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  105. * @param Template\Config $emailConfig
  106. * @param TemplateFactory $templateFactory
  107. * @param \Magento\Framework\Filter\FilterManager $filterManager
  108. * @param \Magento\Framework\UrlInterface $urlModel
  109. * @param Template\FilterFactory $filterFactory
  110. * @param array $data
  111. * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
  112. * @throws \RuntimeException
  113. *
  114. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  115. */
  116. public function __construct(
  117. \Magento\Framework\Model\Context $context,
  118. \Magento\Framework\View\DesignInterface $design,
  119. \Magento\Framework\Registry $registry,
  120. \Magento\Store\Model\App\Emulation $appEmulation,
  121. StoreManagerInterface $storeManager,
  122. \Magento\Framework\View\Asset\Repository $assetRepo,
  123. \Magento\Framework\Filesystem $filesystem,
  124. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  125. \Magento\Email\Model\Template\Config $emailConfig,
  126. \Magento\Email\Model\TemplateFactory $templateFactory,
  127. \Magento\Framework\Filter\FilterManager $filterManager,
  128. \Magento\Framework\UrlInterface $urlModel,
  129. \Magento\Email\Model\Template\FilterFactory $filterFactory,
  130. array $data = [],
  131. \Magento\Framework\Serialize\Serializer\Json $serializer = null
  132. ) {
  133. $this->filterFactory = $filterFactory;
  134. $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
  135. ->get(\Magento\Framework\Serialize\Serializer\Json::class);
  136. parent::__construct(
  137. $context,
  138. $design,
  139. $registry,
  140. $appEmulation,
  141. $storeManager,
  142. $assetRepo,
  143. $filesystem,
  144. $scopeConfig,
  145. $emailConfig,
  146. $templateFactory,
  147. $filterManager,
  148. $urlModel,
  149. $data
  150. );
  151. }
  152. /**
  153. * Initialize email template model
  154. *
  155. * @return void
  156. */
  157. protected function _construct()
  158. {
  159. $this->_init(\Magento\Email\Model\ResourceModel\Template::class);
  160. }
  161. /**
  162. * Return template id
  163. *
  164. * @return int|null
  165. */
  166. public function getId()
  167. {
  168. return $this->getTemplateId();
  169. }
  170. /**
  171. * Set id of template
  172. *
  173. * @param int $value
  174. * @return $this
  175. */
  176. public function setId($value)
  177. {
  178. return $this->setTemplateId($value);
  179. }
  180. /**
  181. * Return true if this template can be used for sending queue as main template
  182. *
  183. * @return bool
  184. */
  185. public function isValidForSend()
  186. {
  187. return $this->getSenderName() && $this->getSenderEmail() && $this->getTemplateSubject();
  188. }
  189. /**
  190. * Getter for template type
  191. *
  192. * @return int
  193. */
  194. public function getType()
  195. {
  196. $templateType = $this->getTemplateType();
  197. if (null === $templateType && $this->getId()) {
  198. $templateType = $this->emailConfig->getTemplateType($this->getId());
  199. $templateType = $templateType == 'html' ? self::TYPE_HTML : self::TYPE_TEXT;
  200. }
  201. return $templateType !== null ? $templateType : self::TYPE_HTML;
  202. }
  203. /**
  204. * Get exception, generated during send() method
  205. *
  206. * @return \Exception|null
  207. * @codeCoverageIgnore
  208. */
  209. public function getSendingException()
  210. {
  211. return $this->_sendingException;
  212. }
  213. /**
  214. * Process email subject
  215. *
  216. * @param array $variables
  217. * @return string
  218. * @throws \Magento\Framework\Exception\MailException
  219. */
  220. public function getProcessedTemplateSubject(array $variables)
  221. {
  222. $processor = $this->getTemplateFilter();
  223. $variables['this'] = $this;
  224. $processor->setVariables($variables);
  225. $this->applyDesignConfig();
  226. $storeId = $this->getDesignConfig()->getStore();
  227. try {
  228. $processedResult = $processor->setStoreId($storeId)->filter(__($this->getTemplateSubject()));
  229. } catch (\Exception $e) {
  230. $this->cancelDesignConfig();
  231. throw new \Magento\Framework\Exception\MailException(__($e->getMessage()), $e);
  232. }
  233. $this->cancelDesignConfig();
  234. return $processedResult;
  235. }
  236. /**
  237. * Add email BCC
  238. *
  239. * @param string|array $bcc
  240. * @return $this
  241. * @codeCoverageIgnore
  242. */
  243. public function addBcc($bcc)
  244. {
  245. $this->_bcc[] = $bcc;
  246. return $this;
  247. }
  248. /**
  249. * Set Return Path
  250. *
  251. * @param string $email
  252. * @return $this
  253. * @codeCoverageIgnore
  254. */
  255. public function setReturnPath($email)
  256. {
  257. $this->_returnPath = $email;
  258. return $this;
  259. }
  260. /**
  261. * Add Reply-To header
  262. *
  263. * @param string $email
  264. * @return $this
  265. * @codeCoverageIgnore
  266. */
  267. public function setReplyTo($email)
  268. {
  269. $this->_replyTo = $email;
  270. return $this;
  271. }
  272. /**
  273. * Parse variables string into array of variables
  274. *
  275. * @param string $variablesString
  276. * @return array
  277. */
  278. protected function _parseVariablesString($variablesString)
  279. {
  280. $variables = [];
  281. if ($variablesString && is_string($variablesString)) {
  282. $variablesString = str_replace("\n", '', $variablesString);
  283. $variables = $this->serializer->unserialize($variablesString);
  284. }
  285. return $variables;
  286. }
  287. /**
  288. * Retrieve option array of variables
  289. *
  290. * @param boolean $withGroup if true wrap variable options in group
  291. * @return array
  292. */
  293. public function getVariablesOptionArray($withGroup = false)
  294. {
  295. $optionArray = [];
  296. $variables = $this->_parseVariablesString($this->getData('orig_template_variables'));
  297. if ($variables) {
  298. foreach ($variables as $value => $label) {
  299. $optionArray[] = ['value' => '{{' . $value . '}}', 'label' => __('%1', $label)];
  300. }
  301. if ($withGroup) {
  302. $optionArray = ['label' => __('Template Variables'), 'value' => $optionArray];
  303. }
  304. }
  305. return $optionArray;
  306. }
  307. /**
  308. * Validate email template code
  309. *
  310. * @throws \Magento\Framework\Exception\MailException
  311. * @return $this
  312. */
  313. public function beforeSave()
  314. {
  315. $code = $this->getTemplateCode();
  316. if (empty($code)) {
  317. throw new \Magento\Framework\Exception\MailException(__('Please enter a template name.'));
  318. }
  319. if ($this->_getResource()->checkCodeUsage($this)) {
  320. throw new \Magento\Framework\Exception\MailException(__('Duplicate Of Template Name'));
  321. }
  322. parent::beforeSave();
  323. return $this;
  324. }
  325. /**
  326. * Get processed template
  327. *
  328. * @return string
  329. * @throws \Magento\Framework\Exception\MailException
  330. */
  331. public function processTemplate()
  332. {
  333. // Support theme fallback for email templates
  334. $isDesignApplied = $this->applyDesignConfig();
  335. $templateId = $this->getId();
  336. if (is_numeric($templateId)) {
  337. $this->load($templateId);
  338. } else {
  339. $this->loadDefault($templateId);
  340. }
  341. if (!$this->getId()) {
  342. throw new \Magento\Framework\Exception\MailException(
  343. __('Invalid transactional email code: %1', $templateId)
  344. );
  345. }
  346. $this->setUseAbsoluteLinks(true);
  347. $text = $this->getProcessedTemplate($this->_getVars());
  348. if ($isDesignApplied) {
  349. $this->cancelDesignConfig();
  350. }
  351. return $text;
  352. }
  353. /**
  354. * Get processed subject
  355. *
  356. * @return string
  357. */
  358. public function getSubject()
  359. {
  360. return $this->getProcessedTemplateSubject($this->_getVars());
  361. }
  362. /**
  363. * Set template variables
  364. *
  365. * @param array $vars
  366. * @return $this
  367. */
  368. public function setVars(array $vars)
  369. {
  370. $this->_vars = $vars;
  371. return $this;
  372. }
  373. /**
  374. * Set template options
  375. *
  376. * @param array $options
  377. * @return $this
  378. */
  379. public function setOptions(array $options)
  380. {
  381. return $this->setDesignConfig($options);
  382. }
  383. /**
  384. * @return \Magento\Email\Model\Template\FilterFactory
  385. */
  386. protected function getFilterFactory()
  387. {
  388. return $this->filterFactory;
  389. }
  390. /**
  391. * Retrieve template variables
  392. *
  393. * @return array
  394. */
  395. protected function _getVars()
  396. {
  397. return $this->_vars;
  398. }
  399. }