WC_Email

Email Class.

Defined (1)

The class is defined in the following location(s).

/includes/emails/class-wc-email.php  
  1. class WC_Email extends WC_Settings_API { 
  2.  
  3. /** 
  4. * Email method ID. 
  5. * @var String 
  6. */ 
  7. public $id; 
  8.  
  9. /** 
  10. * Email method title. 
  11. * @var string 
  12. */ 
  13. public $title; 
  14.  
  15. /** 
  16. * 'yes' if the method is enabled. 
  17. * @var string yes, no 
  18. */ 
  19. public $enabled; 
  20.  
  21. /** 
  22. * Description for the email. 
  23. * @var string 
  24. */ 
  25. public $description; 
  26.  
  27. /** 
  28. * Plain text template path. 
  29. * @var string 
  30. */ 
  31. public $template_plain; 
  32.  
  33. /** 
  34. * HTML template path. 
  35. * @var string 
  36. */ 
  37. public $template_html; 
  38.  
  39. /** 
  40. * Template path. 
  41. * @var string 
  42. */ 
  43. public $template_base; 
  44.  
  45. /** 
  46. * Recipients for the email. 
  47. * @var string 
  48. */ 
  49. public $recipient; 
  50.  
  51. /** 
  52. * Heading for the email content. 
  53. * @var string 
  54. */ 
  55. public $heading; 
  56.  
  57. /** 
  58. * Subject for the email. 
  59. * @var string 
  60. */ 
  61. public $subject; 
  62.  
  63. /** 
  64. * Object this email is for, for example a customer, product, or email. 
  65. * @var object|bool 
  66. */ 
  67. public $object; 
  68.  
  69. /** 
  70. * Strings to find in subjects/headings. 
  71. * @var array 
  72. */ 
  73. public $find = array(); 
  74.  
  75. /** 
  76. * Strings to replace in subjects/headings. 
  77. * @var array 
  78. */ 
  79. public $replace = array(); 
  80.  
  81. /** 
  82. * Mime boundary (for multipart emails). 
  83. * @var string 
  84. */ 
  85. public $mime_boundary; 
  86.  
  87. /** 
  88. * Mime boundary header (for multipart emails). 
  89. * @var string 
  90. */ 
  91. public $mime_boundary_header; 
  92.  
  93. /** 
  94. * True when email is being sent. 
  95. * @var bool 
  96. */ 
  97. public $sending; 
  98.  
  99. /** 
  100. * True when the email notification is sent manually only. 
  101. * @var bool 
  102. */ 
  103. protected $manual = false; 
  104.  
  105. /** 
  106. * True when the email notification is sent to customers. 
  107. * @var bool 
  108. */ 
  109. protected $customer_email = false; 
  110.  
  111. /** 
  112. * List of preg* regular expression patterns to search for,  
  113. * used in conjunction with $plain_replace. 
  114. * https://raw.github.com/ushahidi/wp-silcc/master/class.html2text.inc 
  115. * @var array $plain_search 
  116. * @see $plain_replace 
  117. */ 
  118. public $plain_search = array( 
  119. "/\r/", // Non-legal carriage return 
  120. '/&(nbsp|#160);/i', // Non-breaking space 
  121. '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i', // Double quotes 
  122. '/&(apos|rsquo|lsquo|#8216|#8217);/i', // Single quotes 
  123. '/>/i', // Greater-than 
  124. '/</i', // Less-than 
  125. '/&/i', // Ampersand 
  126. '/&/i', // Ampersand 
  127. '/&/i', // Ampersand 
  128. '/&(copy|#169);/i', // Copyright 
  129. '/&(trade|#8482|#153);/i', // Trademark 
  130. '/&(reg|#174);/i', // Registered 
  131. '/&(mdash|#151|#8212);/i', // mdash 
  132. '/&(ndash|minus|#8211|#8722);/i', // ndash 
  133. '/&(bull|#149|#8226);/i', // Bullet 
  134. '/&(pound|#163);/i', // Pound sign 
  135. '/&(euro|#8364);/i', // Euro sign 
  136. '/$/', // Dollar sign 
  137. '/&[^&\s;]+;/i', // Unknown/unhandled entities 
  138. '/[ ]{2, }/', // Runs of spaces, post-handling 
  139. ); 
  140.  
  141. /** 
  142. * List of pattern replacements corresponding to patterns searched. 
  143. * @var array $plain_replace 
  144. * @see $plain_search 
  145. */ 
  146. public $plain_replace = array( 
  147. '', // Non-legal carriage return 
  148. ' ', // Non-breaking space 
  149. '"', // Double quotes 
  150. "'", // Single quotes 
  151. '>', // Greater-than 
  152. '<', // Less-than 
  153. '&', // Ampersand 
  154. '&', // Ampersand 
  155. '&', // Ampersand 
  156. '(c)', // Copyright 
  157. '(tm)', // Trademark 
  158. '(R)', // Registered 
  159. '--', // mdash 
  160. '-', // ndash 
  161. '*', // Bullet 
  162. '', // Pound sign 
  163. 'EUR', // Euro sign. * ? 
  164. '$', // Dollar sign 
  165. '', // Unknown/unhandled entities 
  166. ' ', // Runs of spaces, post-handling 
  167. ); 
  168.  
  169. /** 
  170. * Constructor. 
  171. */ 
  172. public function __construct() { 
  173. // Init settings 
  174. $this->init_form_fields(); 
  175. $this->init_settings(); 
  176.  
  177. // Save settings hook 
  178. add_action( 'woocommerce_update_options_email_' . $this->id, array( $this, 'process_admin_options' ) ); 
  179.  
  180. // Default template base if not declared in child constructor 
  181. if ( is_null( $this->template_base ) ) { 
  182. $this->template_base = WC()->plugin_path() . '/templates/'; 
  183.  
  184. // Settings 
  185. $this->heading = $this->get_option( 'heading', $this->heading ); 
  186. $this->subject = $this->get_option( 'subject', $this->subject ); 
  187. $this->email_type = $this->get_option( 'email_type' ); 
  188. $this->enabled = $this->get_option( 'enabled' ); 
  189.  
  190. // Find/replace 
  191. $this->find['blogname'] = '{blogname}'; 
  192. $this->find['site-title'] = '{site_title}'; 
  193. $this->replace['blogname'] = $this->get_blogname(); 
  194. $this->replace['site-title'] = $this->get_blogname(); 
  195.  
  196. // For multipart messages 
  197. add_action( 'phpmailer_init', array( $this, 'handle_multipart' ) ); 
  198.  
  199. /** 
  200. * Handle multipart mail. 
  201. * @param PHPMailer $mailer 
  202. * @return PHPMailer 
  203. */ 
  204. public function handle_multipart( $mailer ) { 
  205. if ( $this->sending && 'multipart' === $this->get_email_type() ) { 
  206. $mailer->AltBody = wordwrap( preg_replace( $this->plain_search, $this->plain_replace, strip_tags( $this->get_content_plain() ) ) ); 
  207. $this->sending = false; 
  208. return $mailer; 
  209.  
  210. /** 
  211. * Format email string. 
  212. * @param mixed $string 
  213. * @return string 
  214. */ 
  215. public function format_string( $string ) { 
  216. return str_replace( apply_filters( 'woocommerce_email_format_string_find', $this->find, $this ), apply_filters( 'woocommerce_email_format_string_replace', $this->replace, $this ), $string ); 
  217.  
  218. /** 
  219. * Get email subject. 
  220. * @return string 
  221. */ 
  222. public function get_subject() { 
  223. return apply_filters( 'woocommerce_email_subject_' . $this->id, $this->format_string( $this->subject ), $this->object ); 
  224.  
  225. /** 
  226. * Get email heading. 
  227. * @return string 
  228. */ 
  229. public function get_heading() { 
  230. return apply_filters( 'woocommerce_email_heading_' . $this->id, $this->format_string( $this->heading ), $this->object ); 
  231.  
  232. /** 
  233. * Get valid recipients. 
  234. * @return string 
  235. */ 
  236. public function get_recipient() { 
  237. $recipient = apply_filters( 'woocommerce_email_recipient_' . $this->id, $this->recipient, $this->object ); 
  238. $recipients = array_map( 'trim', explode( ', ', $recipient ) ); 
  239. $recipients = array_filter( $recipients, 'is_email' ); 
  240. return implode( ', ', $recipients ); 
  241.  
  242. /** 
  243. * Get email headers. 
  244. * @return string 
  245. */ 
  246. public function get_headers() { 
  247. $header = "Content-Type: " . $this->get_content_type() . "\r\n"; 
  248.  
  249. if ( 'new_order' === $this->id && $this->object && $this->object->get_billing_email() && ( $this->object->get_billing_first_name() || $this->object->get_billing_last_name() ) ) { 
  250. $header .= 'Reply-to: ' . $this->object->get_billing_first_name() . ' ' . $this->object->get_billing_last_name() . ' <' . $this->object->get_billing_email() . ">\r\n"; 
  251.  
  252. return apply_filters( 'woocommerce_email_headers', $header, $this->id, $this->object ); 
  253.  
  254. /** 
  255. * Get email attachments. 
  256. * @return string 
  257. */ 
  258. public function get_attachments() { 
  259. return apply_filters( 'woocommerce_email_attachments', array(), $this->id, $this->object ); 
  260.  
  261. /** 
  262. * get_type function. 
  263. * @return string 
  264. */ 
  265. public function get_email_type() { 
  266. return $this->email_type && class_exists( 'DOMDocument' ) ? $this->email_type : 'plain'; 
  267.  
  268. /** 
  269. * Get email content type. 
  270. * @return string 
  271. */ 
  272. public function get_content_type() { 
  273. switch ( $this->get_email_type() ) { 
  274. case 'html' : 
  275. return 'text/html'; 
  276. case 'multipart' : 
  277. return 'multipart/alternative'; 
  278. default : 
  279. return 'text/plain'; 
  280.  
  281. /** 
  282. * Return the email's title 
  283. * @return string 
  284. */ 
  285. public function get_title() { 
  286. return apply_filters( 'woocommerce_email_title', $this->title, $this ); 
  287.  
  288. /** 
  289. * Return the email's description 
  290. * @return string 
  291. */ 
  292. public function get_description() { 
  293. return apply_filters( 'woocommerce_email_description', $this->description, $this ); 
  294.  
  295. /** 
  296. * Proxy to parent's get_option and attempt to localize the result using gettext. 
  297. * @param string $key 
  298. * @param mixed $empty_value 
  299. * @return string 
  300. */ 
  301. public function get_option( $key, $empty_value = null ) { 
  302. $value = parent::get_option( $key, $empty_value ); 
  303. return apply_filters( 'woocommerce_email_get_option', $value, $this, $value, $key, $empty_value ); 
  304.  
  305. /** 
  306. * Checks if this email is enabled and will be sent. 
  307. * @return bool 
  308. */ 
  309. public function is_enabled() { 
  310. return apply_filters( 'woocommerce_email_enabled_' . $this->id, 'yes' === $this->enabled, $this->object ); 
  311.  
  312. /** 
  313. * Checks if this email is manually sent 
  314. * @return bool 
  315. */ 
  316. public function is_manual() { 
  317. return $this->manual; 
  318.  
  319. /** 
  320. * Checks if this email is customer focussed. 
  321. * @return bool 
  322. */ 
  323. public function is_customer_email() { 
  324. return $this->customer_email; 
  325.  
  326. /** 
  327. * Get WordPress blog name. 
  328. * @return string 
  329. */ 
  330. public function get_blogname() { 
  331. return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); 
  332.  
  333. /** 
  334. * Get email content. 
  335. * @return string 
  336. */ 
  337. public function get_content() { 
  338. $this->sending = true; 
  339.  
  340. if ( 'plain' === $this->get_email_type() ) { 
  341. $email_content = preg_replace( $this->plain_search, $this->plain_replace, strip_tags( $this->get_content_plain() ) ); 
  342. } else { 
  343. $email_content = $this->get_content_html(); 
  344.  
  345. return wordwrap( $email_content, 70 ); 
  346.  
  347. /** 
  348. * Apply inline styles to dynamic content. 
  349. * @param string|null $content 
  350. * @return string 
  351. */ 
  352. public function style_inline( $content ) { 
  353. // make sure we only inline CSS for html emails 
  354. if ( in_array( $this->get_content_type(), array( 'text/html', 'multipart/alternative' ) ) && class_exists( 'DOMDocument' ) ) { 
  355. ob_start(); 
  356. wc_get_template( 'emails/email-styles.php' ); 
  357. $css = apply_filters( 'woocommerce_email_styles', ob_get_clean() ); 
  358.  
  359. // apply CSS styles inline for picky email clients 
  360. try { 
  361. $emogrifier = new Emogrifier( $content, $css ); 
  362. $content = $emogrifier->emogrify(); 
  363. } catch ( Exception $e ) { 
  364. $logger = wc_get_logger(); 
  365. $logger->error( $e->getMessage(), array( 'source' => 'emogrifier' ) ); 
  366. return $content; 
  367.  
  368. /** 
  369. * Get the email content in plain text format. 
  370. * @return string 
  371. */ 
  372. public function get_content_plain() { return ''; } 
  373.  
  374. /** 
  375. * Get the email content in HTML format. 
  376. * @return string 
  377. */ 
  378. public function get_content_html() { return ''; } 
  379.  
  380. /** 
  381. * Get the from name for outgoing emails. 
  382. * @return string 
  383. */ 
  384. public function get_from_name() { 
  385. $from_name = apply_filters( 'woocommerce_email_from_name', get_option( 'woocommerce_email_from_name' ), $this ); 
  386. return wp_specialchars_decode( esc_html( $from_name ), ENT_QUOTES ); 
  387.  
  388. /** 
  389. * Get the from address for outgoing emails. 
  390. * @return string 
  391. */ 
  392. public function get_from_address() { 
  393. $from_address = apply_filters( 'woocommerce_email_from_address', get_option( 'woocommerce_email_from_address' ), $this ); 
  394. return sanitize_email( $from_address ); 
  395.  
  396. /** 
  397. * Send an email. 
  398. * @param string $to 
  399. * @param string $subject 
  400. * @param string $message 
  401. * @param string $headers 
  402. * @param string $attachments 
  403. * @return bool success 
  404. */ 
  405. public function send( $to, $subject, $message, $headers, $attachments ) { 
  406. add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) ); 
  407. add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) ); 
  408. add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) ); 
  409.  
  410. $message = apply_filters( 'woocommerce_mail_content', $this->style_inline( $message ) ); 
  411. $return = wp_mail( $to, $subject, $message, $headers, $attachments ); 
  412.  
  413. remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) ); 
  414. remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) ); 
  415. remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) ); 
  416.  
  417. return $return; 
  418.  
  419. /** 
  420. * Initialise Settings Form Fields - these are generic email options most will use. 
  421. */ 
  422. public function init_form_fields() { 
  423. $this->form_fields = array( 
  424. 'enabled' => array( 
  425. 'title' => __( 'Enable/Disable', 'woocommerce' ),  
  426. 'type' => 'checkbox',  
  427. 'label' => __( 'Enable this email notification', 'woocommerce' ),  
  428. 'default' => 'yes',  
  429. ),  
  430. 'subject' => array( 
  431. 'title' => __( 'Email subject', 'woocommerce' ),  
  432. 'type' => 'text',  
  433. /** translators: %s: default subject */ 
  434. 'description' => sprintf( __( 'Defaults to %s', 'woocommerce' ), '<code>' . $this->subject . '</code>' ),  
  435. 'placeholder' => '',  
  436. 'default' => '',  
  437. 'desc_tip' => true,  
  438. ),  
  439. 'heading' => array( 
  440. 'title' => __( 'Email heading', 'woocommerce' ),  
  441. 'type' => 'text',  
  442. /** translators: %s: default heading */ 
  443. 'description' => sprintf( __( 'Defaults to %s', 'woocommerce' ), '<code>' . $this->heading . '</code>' ),  
  444. 'placeholder' => '',  
  445. 'default' => '',  
  446. 'desc_tip' => true,  
  447. ),  
  448. 'email_type' => array( 
  449. 'title' => __( 'Email type', 'woocommerce' ),  
  450. 'type' => 'select',  
  451. 'description' => __( 'Choose which format of email to send.', 'woocommerce' ),  
  452. 'default' => 'html',  
  453. 'class' => 'email_type wc-enhanced-select',  
  454. 'options' => $this->get_email_type_options(),  
  455. 'desc_tip' => true,  
  456. ),  
  457. ); 
  458.  
  459. /** 
  460. * Email type options. 
  461. * @return array 
  462. */ 
  463. public function get_email_type_options() { 
  464. $types = array( 'plain' => __( 'Plain text', 'woocommerce' ) ); 
  465.  
  466. if ( class_exists( 'DOMDocument' ) ) { 
  467. $types['html'] = __( 'HTML', 'woocommerce' ); 
  468. $types['multipart'] = __( 'Multipart', 'woocommerce' ); 
  469.  
  470. return $types; 
  471.  
  472. /** 
  473. * Admin Panel Options Processing. 
  474. */ 
  475. public function process_admin_options() { 
  476. // Save regular options 
  477. parent::process_admin_options(); 
  478.  
  479. $post_data = $this->get_post_data(); 
  480.  
  481. // Save templates 
  482. if ( isset( $post_data['template_html_code'] ) ) { 
  483. $this->save_template( $post_data['template_html_code'], $this->template_html ); 
  484. if ( isset( $post_data['template_plain_code'] ) ) { 
  485. $this->save_template( $post_data['template_plain_code'], $this->template_plain ); 
  486.  
  487. /** 
  488. * Get template. 
  489. * @param string $type 
  490. * @return string 
  491. */ 
  492. public function get_template( $type ) { 
  493. $type = basename( $type ); 
  494.  
  495. if ( 'template_html' === $type ) { 
  496. return $this->template_html; 
  497. } elseif ( 'template_plain' === $type ) { 
  498. return $this->template_plain; 
  499. return ''; 
  500.  
  501. /** 
  502. * Save the email templates. 
  503. * @since 2.4.0 
  504. * @param string $template_code 
  505. * @param string $template_path 
  506. */ 
  507. protected function save_template( $template_code, $template_path ) { 
  508. if ( current_user_can( 'edit_themes' ) && ! empty( $template_code ) && ! empty( $template_path ) ) { 
  509. $saved = false; 
  510. $file = get_stylesheet_directory() . '/woocommerce/' . $template_path; 
  511. $code = wp_unslash( $template_code ); 
  512.  
  513. if ( is_writeable( $file ) ) { 
  514. $f = fopen( $file, 'w+' ); 
  515.  
  516. if ( false !== $f ) { 
  517. fwrite( $f, $code ); 
  518. fclose( $f ); 
  519. $saved = true; 
  520.  
  521. if ( ! $saved ) { 
  522. $redirect = add_query_arg( 'wc_error', urlencode( __( 'Could not write to template file.', 'woocommerce' ) ) ); 
  523. wp_safe_redirect( $redirect ); 
  524. exit; 
  525.  
  526. /** 
  527. * Get the template file in the current theme. 
  528. * @param string $template 
  529. * @return string 
  530. */ 
  531. public function get_theme_template_file( $template ) { 
  532. return get_stylesheet_directory() . '/' . apply_filters( 'woocommerce_template_directory', 'woocommerce', $template ) . '/' . $template; 
  533.  
  534. /** 
  535. * Move template action. 
  536. * @param string $template_type 
  537. */ 
  538. protected function move_template_action( $template_type ) { 
  539. if ( $template = $this->get_template( $template_type ) ) { 
  540. if ( ! empty( $template ) ) { 
  541.  
  542. $theme_file = $this->get_theme_template_file( $template ); 
  543.  
  544. if ( wp_mkdir_p( dirname( $theme_file ) ) && ! file_exists( $theme_file ) ) { 
  545.  
  546. // Locate template file 
  547. $core_file = $this->template_base . $template; 
  548. $template_file = apply_filters( 'woocommerce_locate_core_template', $core_file, $template, $this->template_base, $this->id ); 
  549.  
  550. // Copy template file 
  551. copy( $template_file, $theme_file ); 
  552.  
  553. /** 
  554. * woocommerce_copy_email_template action hook. 
  555. * @param string $template_type The copied template type 
  556. * @param string $email The email object 
  557. */ 
  558. do_action( 'woocommerce_copy_email_template', $template_type, $this ); 
  559.  
  560. echo '<div class="updated"><p>' . __( 'Template file copied to theme.', 'woocommerce' ) . '</p></div>'; 
  561.  
  562. /** 
  563. * Delete template action. 
  564. * @param string $template_type 
  565. */ 
  566. protected function delete_template_action( $template_type ) { 
  567. if ( $template = $this->get_template( $template_type ) ) { 
  568.  
  569. if ( ! empty( $template ) ) { 
  570.  
  571. $theme_file = $this->get_theme_template_file( $template ); 
  572.  
  573. if ( file_exists( $theme_file ) ) { 
  574. unlink( $theme_file ); 
  575.  
  576. /** 
  577. * woocommerce_delete_email_template action hook. 
  578. * @param string $template The deleted template type 
  579. * @param string $email The email object 
  580. */ 
  581. do_action( 'woocommerce_delete_email_template', $template_type, $this ); 
  582.  
  583. echo '<div class="updated"><p>' . __( 'Template file deleted from theme.', 'woocommerce' ) . '</p></div>'; 
  584.  
  585. /** 
  586. * Admin actions. 
  587. */ 
  588. protected function admin_actions() { 
  589. // Handle any actions 
  590. if ( 
  591. ( ! empty( $this->template_html ) || ! empty( $this->template_plain ) ) 
  592. && ( ! empty( $_GET['move_template'] ) || ! empty( $_GET['delete_template'] ) ) 
  593. && 'GET' === $_SERVER['REQUEST_METHOD'] 
  594. ) { 
  595. if ( empty( $_GET['_wc_email_nonce'] ) || ! wp_verify_nonce( $_GET['_wc_email_nonce'], 'woocommerce_email_template_nonce' ) ) { 
  596. wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); 
  597.  
  598. if ( ! current_user_can( 'edit_themes' ) ) { 
  599. wp_die( __( 'Cheatin’ huh?', 'woocommerce' ) ); 
  600.  
  601. if ( ! empty( $_GET['move_template'] ) ) { 
  602. $this->move_template_action( $_GET['move_template'] ); 
  603.  
  604. if ( ! empty( $_GET['delete_template'] ) ) { 
  605. $this->delete_template_action( $_GET['delete_template'] ); 
  606.  
  607. /** 
  608. * Admin Options. 
  609. * Setup the email settings screen. 
  610. * Override this in your email. 
  611. * @since 1.0.0 
  612. */ 
  613. public function admin_options() { 
  614. // Do admin actions. 
  615. $this->admin_actions(); 
  616. ?> 
  617. <h2><?php echo esc_html( $this->get_title() ); ?> <?php wc_back_link( __( 'Return to emails', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=email' ) ); ?></h2> 
  618.  
  619. <?php echo wpautop( wp_kses_post( $this->get_description() ) ); ?> 
  620.  
  621. <?php 
  622. /** 
  623. * woocommerce_email_settings_before action hook. 
  624. * @param string $email The email object 
  625. */ 
  626. do_action( 'woocommerce_email_settings_before', $this ); 
  627. ?> 
  628.  
  629. <table class="form-table"> 
  630. <?php $this->generate_settings_html(); ?> 
  631. </table> 
  632.  
  633. <?php 
  634. /** 
  635. * woocommerce_email_settings_after action hook. 
  636. * @param string $email The email object 
  637. */ 
  638. do_action( 'woocommerce_email_settings_after', $this ); 
  639. ?> 
  640.  
  641. <?php if ( current_user_can( 'edit_themes' ) && ( ! empty( $this->template_html ) || ! empty( $this->template_plain ) ) ) { ?> 
  642. <div id="template"> 
  643. <?php 
  644. $templates = array( 
  645. 'template_html' => __( 'HTML template', 'woocommerce' ),  
  646. 'template_plain' => __( 'Plain text template', 'woocommerce' ),  
  647. ); 
  648.  
  649. foreach ( $templates as $template_type => $title ) : 
  650. $template = $this->get_template( $template_type ); 
  651.  
  652. if ( empty( $template ) ) { 
  653. continue; 
  654.  
  655. $local_file = $this->get_theme_template_file( $template ); 
  656. $core_file = $this->template_base . $template; 
  657. $template_file = apply_filters( 'woocommerce_locate_core_template', $core_file, $template, $this->template_base, $this->id ); 
  658. $template_dir = apply_filters( 'woocommerce_template_directory', 'woocommerce', $template ); 
  659. ?> 
  660. <div class="template <?php echo $template_type; ?>"> 
  661.  
  662. <h4><?php echo wp_kses_post( $title ); ?></h4> 
  663.  
  664. <?php if ( file_exists( $local_file ) ) { ?> 
  665.  
  666. <p> 
  667. <a href="#" class="button toggle_editor"></a> 
  668.  
  669. <?php if ( is_writable( $local_file ) ) : ?> 
  670. <a href="<?php echo esc_url( wp_nonce_url( remove_query_arg( array( 'move_template', 'saved' ), add_query_arg( 'delete_template', $template_type ) ), 'woocommerce_email_template_nonce', '_wc_email_nonce' ) ); ?>" class="delete_template button"><?php _e( 'Delete template file', 'woocommerce' ); ?></a> 
  671. <?php endif; ?> 
  672.  
  673. <?php printf( __( 'This template has been overridden by your theme and can be found in: %s.', 'woocommerce' ), '<code>' . trailingslashit( basename( get_stylesheet_directory() ) ) . $template_dir . '/' . $template . '</code>' ); ?> 
  674. </p> 
  675.  
  676. <div class="editor" style="display:none"> 
  677. <textarea class="code" cols="25" rows="20" <?php if ( ! is_writable( $local_file ) ) : ?>readonly="readonly" disabled="disabled"<?php else : ?>data-name="<?php echo $template_type . '_code'; ?>"<?php endif; ?>><?php echo file_get_contents( $local_file ); ?></textarea> 
  678. </div> 
  679.  
  680. <?php } elseif ( file_exists( $template_file ) ) { ?> 
  681.  
  682. <p> 
  683. <a href="#" class="button toggle_editor"></a> 
  684.  
  685. <?php if ( ( is_dir( get_stylesheet_directory() . '/' . $template_dir . '/emails/' ) && is_writable( get_stylesheet_directory() . '/' . $template_dir . '/emails/' ) ) || is_writable( get_stylesheet_directory() ) ) { ?> 
  686. <a href="<?php echo esc_url( wp_nonce_url( remove_query_arg( array( 'delete_template', 'saved' ), add_query_arg( 'move_template', $template_type ) ), 'woocommerce_email_template_nonce', '_wc_email_nonce' ) ); ?>" class="button"><?php _e( 'Copy file to theme', 'woocommerce' ); ?></a> 
  687. <?php } ?> 
  688.  
  689. <?php printf( __( 'To override and edit this email template copy %1$s to your theme folder: %2$s.', 'woocommerce' ), '<code>' . plugin_basename( $template_file ) . '</code>', '<code>' . trailingslashit( basename( get_stylesheet_directory() ) ) . $template_dir . '/' . $template . '</code>' ); ?> 
  690. </p> 
  691.  
  692. <div class="editor" style="display:none"> 
  693. <textarea class="code" readonly="readonly" disabled="disabled" cols="25" rows="20"><?php echo file_get_contents( $template_file ); ?></textarea> 
  694. </div> 
  695.  
  696. <?php } else { ?> 
  697.  
  698. <p><?php _e( 'File was not found.', 'woocommerce' ); ?></p> 
  699.  
  700. <?php } ?> 
  701.  
  702. </div> 
  703. <?php 
  704. endforeach; 
  705. ?> 
  706. </div> 
  707. <?php 
  708. wc_enqueue_js( " 
  709. jQuery( 'select.email_type' ).change( function() { 
  710.  
  711. var val = jQuery( this ).val(); 
  712.  
  713. jQuery( '.template_plain, .template_html' ).show(); 
  714.  
  715. if ( val != 'multipart' && val != 'html' ) { 
  716. jQuery('.template_html').hide(); 
  717.  
  718. if ( val != 'multipart' && val != 'plain' ) { 
  719. jQuery('.template_plain').hide(); 
  720.  
  721. }).change(); 
  722.  
  723. var view = '" . esc_js( __( 'View template', 'woocommerce' ) ) . "'; 
  724. var hide = '" . esc_js( __( 'Hide template', 'woocommerce' ) ) . "'; 
  725.  
  726. jQuery( 'a.toggle_editor' ).text( view ).toggle( function() { 
  727. jQuery( this ).text( hide ).closest(' .template' ).find( '.editor' ).slideToggle(); 
  728. return false; 
  729. }, function() { 
  730. jQuery( this ).text( view ).closest( '.template' ).find( '.editor' ).slideToggle(); 
  731. return false; 
  732. } ); 
  733.  
  734. jQuery( 'a.delete_template' ).click( function() { 
  735. if ( window.confirm('" . esc_js( __( 'Are you sure you want to delete this template file?', 'woocommerce' ) ) . "') ) { 
  736. return true; 
  737.  
  738. return false; 
  739. }); 
  740.  
  741. jQuery( '.editor textarea' ).change( function() { 
  742. var name = jQuery( this ).attr( 'data-name' ); 
  743.  
  744. if ( name ) { 
  745. jQuery( this ).attr( 'name', name ); 
  746. }); 
  747. " );