WYSIJA_help_wj_engine

The MailPoet Newsletters WYSIJA help wj engine class.

Defined (1)

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

/helpers/wj_engine.php  
  1. class WYSIJA_help_wj_engine extends WYSIJA_object { 
  2. // debug mode 
  3. var $_debug = false; 
  4.  
  5. // contains email data 
  6. var $_email_data = null; 
  7.  
  8. // rendering context (editor, email) 
  9. var $_context = 'editor'; 
  10.  
  11. // toggles for vib & unsub 
  12. var $_hide_viewbrowser = false; 
  13. var $_hide_unsubscribe = false; 
  14.  
  15. // data holders 
  16. var $_data = null; 
  17. var $_styles = null; 
  18.  
  19. // language direction 
  20. var $_is_rtl = false; 
  21.  
  22. // styles: defaults 
  23. var $VIEWBROWSER_SIZES = array(7, 8, 9, 10, 11, 12, 13, 14); 
  24. var $TEXT_SIZES = array(8, 9, 10, 11, 12, 13, 14, 16, 18, 24, 36, 48, 72); 
  25. var $TITLE_SIZES = array(16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 40, 44, 48, 54, 60, 66, 72); 
  26. var $FONTS = array( 
  27. 'Arial' => "Arial, 'Helvetica Neue', Helvetica, sans-serif",  
  28. 'Comic Sans MS' => "'Comic Sans MS', 'Marker Felt-Thin', Arial, sans-serif",  
  29. 'Courier New' => "'Courier New', Courier, 'Lucida Sans Typewriter', 'Lucida Typewriter', monospace",  
  30. 'Georgia' => "Georgia, Times, 'Times New Roman', serif",  
  31. 'Tahoma' => "Tahoma, Verdana, Segoe, sans-serif",  
  32. 'Times New Roman' => "'Times New Roman', Times, Baskerville, Georgia, serif",  
  33. 'Trebuchet MS' => "'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif",  
  34. 'Verdana' => "Verdana, Geneva, sans-serif" 
  35. ); 
  36.  
  37. /** Constructor */ 
  38. function __construct() { 
  39. parent::__construct(); 
  40.  
  41. /** i18n methods */ 
  42. function getTranslations() { 
  43. return array( 
  44. 'dropHeaderNotice' => __('Drop your logo in this header.', WYSIJA),  
  45. 'dropFooterNotice' => __('Drop your footer image here.', WYSIJA),  
  46. 'dropBannerNotice' => __('If you leave this area empty, it will not display once you send your email', WYSIJA),  
  47. 'clickToEditText' => __('Click here to add a title or text.', WYSIJA),  
  48. 'alignmentLeft' => __('Align left', WYSIJA),  
  49. 'alignmentCenter' => __('Align center', WYSIJA),  
  50. 'alignmentRight' => __('Align right', WYSIJA),  
  51. 'addImageLink' => __('Add link / Alternative text', WYSIJA),  
  52. 'removeImageLink' => __('Remove link', WYSIJA),  
  53. 'removeImage' => __('Remove image', WYSIJA),  
  54. 'remove' => __('Remove', WYSIJA),  
  55. 'editText' => __( 'Edit text', WYSIJA),  
  56. 'removeText' => __('Remove text', WYSIJA),  
  57. 'textLabel' => __('Titles & text', WYSIJA),  
  58. 'dividerLabel' => __('Horizontal line', WYSIJA),  
  59. 'customDividerLabel' => __('Custom horizontal line', WYSIJA),  
  60. 'postLabel' => __('WordPress post', WYSIJA),  
  61. 'styleBodyLabel' => __('Text', WYSIJA),  
  62. 'styleViewbrowserLabel' => __('"View in browser"', WYSIJA),  
  63. 'styleH1Label' => __('Heading 1', WYSIJA),  
  64. 'styleH2Label' => __('Heading 2', WYSIJA),  
  65. 'styleH3Label' => __('Heading 3', WYSIJA),  
  66. 'styleLinksLabel' => __('Links', WYSIJA),  
  67. 'styleLinksDecorationLabel' => __('underline', WYSIJA),  
  68. 'styleFooterLabel' => __('Footer text', WYSIJA),  
  69. 'styleFooterBackgroundLabel' => __('Footer background', WYSIJA),  
  70. 'styleBodyBackgroundLabel' => __('Newsletter', WYSIJA),  
  71. 'styleHtmlBackgroundLabel' => __('Background', WYSIJA),  
  72. 'styleHeaderBackgroundLabel' => __('Header background', WYSIJA),  
  73. 'styleDividerLabel' => __('Horizontal line', WYSIJA),  
  74. 'styleUnsubscribeColorLabel' => __('Unsubscribe', WYSIJA),  
  75. 'articleSelectionTitle' => __('Post Selection', WYSIJA),  
  76. 'bookmarkSelectionTitle' => __('Social Bookmark Selection', WYSIJA),  
  77. 'dividerSelectionTitle' => __('Divider Selection', WYSIJA),  
  78. 'abouttodeletetheme' => __('You are about to delete the theme : %1$s. Do you really want to do that?', WYSIJA),  
  79. 'addLinkTitle' => __('Add Link & Alternative text', WYSIJA),  
  80. 'styleTransparent' => __('Check this box if you want transparency', WYSIJA),  
  81. 'ajaxLoading' => __('Loading...', WYSIJA),  
  82. 'customFieldsLabel' => __('Insert dynamic data about your subscribers, the newsletter, today\'s date, etc...', WYSIJA),  
  83. 'autoPostSettingsTitle' => __('Selection options', WYSIJA),  
  84. 'autoPostEditSettings' => __('Edit Automatic latest content', WYSIJA),  
  85. 'autoPostImmediateNotice' => __('You can only add one widget when designing a post notification sent immediately after an article is published', WYSIJA),  
  86. 'toggleImagesTitle' => __('Preview without images', WYSIJA),  
  87. // Tags labels 
  88. 'tags_user' => __('Subscriber', WYSIJA),  
  89. 'tags_user_firstname' => __('First Name', WYSIJA),  
  90. 'tags_user_lastname' => __('Last Name', WYSIJA),  
  91. 'tags_user_email' => __('Email Address', WYSIJA),  
  92. 'tags_user_displayname' => __('WordPress user display name', WYSIJA),  
  93. 'tags_user_count' => __('Total of subscribers', WYSIJA),  
  94. 'tags_newsletter' => __('Newsletter', WYSIJA),  
  95. 'tags_newsletter_subject' => __('Newsletter Subject', WYSIJA),  
  96. 'tags_newsletter_autonl' => __('Post Notifications', WYSIJA),  
  97. 'tags_newsletter_total' => __('Total number of posts or pages', WYSIJA),  
  98. 'tags_newsletter_post_title' => __('Latest post title', WYSIJA),  
  99. 'tags_newsletter_number' => __('Issue number', WYSIJA),  
  100. 'tags_date' => __('Date', WYSIJA),  
  101. 'tags_date_d' => __('Current day of the month number', WYSIJA),  
  102. 'tags_date_dordinal' => __('Current day of the month in ordinal, ie. 2nd, 3rd, etc.', WYSIJA),  
  103. 'tags_date_dtext' => __('Full name of current day', WYSIJA),  
  104. 'tags_date_m' => __('Current month number', WYSIJA),  
  105. 'tags_date_mtext' => __('Full name of current month', WYSIJA),  
  106. 'tags_date_y' => __('Year', WYSIJA),  
  107. 'tags_global' => __('Links', WYSIJA),  
  108. 'tags_global_unsubscribe' => __('Unsubscribe link', WYSIJA),  
  109. 'tags_global_manage' => __('Edit subscription page link', WYSIJA),  
  110. 'tags_global_browser' => __('View in browser link', WYSIJA),  
  111. 'custom_fields_title' => __('Custom Fields', WYSIJA),  
  112. 'custom_fields_list' => WJ_Field::get_all_names(),  
  113. // Themes specific labels 
  114. 'theme_setting_default' => __('Saving default style...', WYSIJA),  
  115. 'theme_saved_default' => __('Default style saved.', WYSIJA),  
  116. 'theme_save_as_default' => __('Set as default style.', WYSIJA),  
  117. // Placeholders 
  118. 'drop_block_here' => __('Insert block here', WYSIJA) 
  119. ); 
  120.  
  121. /** Data methods */ 
  122. function getData($type = null) { 
  123. if($type !== null) { 
  124. if(array_key_exists($type, $this->_data)) { 
  125. return $this->_data[$type]; 
  126. } else { 
  127. // return default value 
  128. $defaults = $this->getDefaultData(); 
  129. return $defaults[$type]; 
  130. return $this->_data; 
  131.  
  132. function setData($value = null, $decode = false) { 
  133. if(!$value) { 
  134. $this->_data = $this->getDefaultData(); 
  135. } else { 
  136. $this->_data = $value; 
  137. if($decode) { 
  138. $this->_data = $this->getDecoded('data'); 
  139.  
  140. function getEmailData($key = null) { 
  141. if($key === null) { 
  142. return $this->_email_data; 
  143. } else { 
  144. if(array_key_exists($key, $this->_email_data)) { 
  145. return $this->_email_data[$key]; 
  146. return null; 
  147.  
  148. function setEmailData($value = null) { 
  149. if($value !== null) { 
  150. $this->_email_data = $value; 
  151.  
  152. function setLanguageDirection() { 
  153. // right to left language property 
  154. if(function_exists('is_rtl')) { 
  155. $this->_is_rtl = is_rtl(); 
  156.  
  157. function isRtl() { 
  158. return $this->_is_rtl; 
  159.  
  160. function getDefaultData() { 
  161. $dividersHelper = WYSIJA::get('dividers', 'helper'); 
  162. return array( 
  163. 'header' => array( 
  164. 'alignment' => 'center',  
  165. 'type' => 'header',  
  166. 'static' => '1',  
  167. 'text' => null,  
  168. 'image' => array( 
  169. 'src' => null,  
  170. 'width' => 600,  
  171. 'height' => 86,  
  172. 'url' => null,  
  173. 'alignment' => 'center',  
  174. 'static' => '1' 
  175. ),  
  176. 'body' => array(),  
  177. 'footer' => array( 
  178. 'alignment' => 'center',  
  179. 'type' => 'footer',  
  180. 'static' => '1',  
  181. 'text' => null,  
  182. 'image' => array( 
  183. 'src' => null,  
  184. 'width' => 600,  
  185. 'height' => 86,  
  186. 'url' => null,  
  187. 'alignment' => 'center',  
  188. 'static' => '1' 
  189. ),  
  190. 'widgets' => array( 
  191. 'divider' => array_merge($dividersHelper->getDefault(), array('type' => 'divider')) 
  192. ); 
  193.  
  194. /** Styles methods */ 
  195. function getStyles($keys = null) { 
  196. if($keys === null) return $this->_styles; 
  197.  
  198. if(!is_array($keys)) { 
  199. $keys = array($keys); 
  200. $output = array(); 
  201. for($i=0; $i<count($keys);$i++) { 
  202. if(isset($this->_styles[$keys[$i]])) { 
  203. $output = array_merge($output, $this->_styles[$keys[$i]]); 
  204. return $output; 
  205.  
  206. function getStyle($key, $subkey) { 
  207. $styles = $this->getStyles($key); 
  208. return $styles[$subkey]; 
  209.  
  210. function setStyles($value = null, $decode = false) { 
  211. if(!$value) { 
  212. $this->_styles = $this->getDefaultStyles(); 
  213. } else { 
  214. $this->_styles = $value; 
  215. if($decode) { 
  216. $this->_styles = $this->getDecoded('styles'); 
  217.  
  218. function getDefaultStyles() { 
  219.  
  220. $defaults = array( 
  221. 'html' => array( 
  222. 'background' => 'FFFFFF' 
  223. ),  
  224. 'header' => array( 
  225. 'background' => 'FFFFFF' 
  226. ),  
  227. 'body' => array( 
  228. 'color' => '000000',  
  229. 'family' => 'Arial',  
  230. 'size' => $this->TEXT_SIZES[5],  
  231. 'background' => 'FFFFFF' 
  232. ),  
  233. 'footer' => array( 
  234. 'color' => '000000',  
  235. 'family' => 'Arial',  
  236. 'size' => $this->TEXT_SIZES[5],  
  237. 'background' => 'cccccc' 
  238. ),  
  239. 'h1' => array( 
  240. 'color' => '000000',  
  241. 'family' => 'Arial',  
  242. 'size' => $this->TITLE_SIZES[6] 
  243. ),  
  244. 'h2' => array( 
  245. 'color' => '424242',  
  246. 'family' => 'Arial',  
  247. 'size' => $this->TITLE_SIZES[5] 
  248. ),  
  249. 'h3' => array( 
  250. 'color' => '424242',  
  251. 'family' => 'Arial',  
  252. 'size' => $this->TITLE_SIZES[4] 
  253. ),  
  254. 'a' => array( 
  255. 'color' => '4a91b0',  
  256. 'underline' => false 
  257. ),  
  258. 'unsubscribe' => array( 
  259. 'color' => '000000' 
  260. ),  
  261. 'viewbrowser' => array( 
  262. 'color' => '000000',  
  263. 'family' => 'Arial',  
  264. 'size' => $this->VIEWBROWSER_SIZES[4] 
  265. ); 
  266.  
  267. // get default selected theme 
  268. $model_config = WYSIJA::get('config', 'model'); 
  269. $default_theme = $model_config->getValue('newsletter_default_theme', 'default'); 
  270.  
  271. if($default_theme === 'default') { 
  272. return $defaults; 
  273. } else { 
  274. $helper_themes = WYSIJA::get('themes', 'helper'); 
  275. $stylesheet = $helper_themes->getStylesheet($default_theme); 
  276.  
  277. $styles = array(); 
  278. // look for each tags 
  279. foreach($defaults as $tag => $values) { 
  280. // look for css rules 
  281. preg_match('/\.?'.$tag.'\s?{(.+)}/Ui', $stylesheet, $matches); 
  282. if(isset($matches[1])) { 
  283. // extract styles 
  284. $styles[$tag] = $this->extractStyles($matches[1]); 
  285. } else { 
  286. // fallback to default 
  287. $styles[$tag] = $defaults[$tag]; 
  288.  
  289. return $styles; 
  290.  
  291. function getApplicationData() { 
  292. $app = array(); 
  293.  
  294. $app['domain'] = WJ_Utils::get_domain(); 
  295.  
  296. return $app; 
  297.  
  298. /** Editor methods */ 
  299. function renderEditor() { 
  300. $this->setContext('editor'); 
  301.  
  302. if($this->isDataValid() === false) { 
  303. throw new Exception('data is not valid'); 
  304. } else { 
  305. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  306. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  307.  
  308. // get company addressfrom settings 
  309. $config=WYSIJA::get("config", "model"); 
  310.  
  311. $data = array( 
  312. 'header' => $this->renderEditorHeader(),  
  313. 'body' => $this->renderEditorBody(),  
  314. 'footer' => $this->renderEditorFooter(),  
  315. 'unsubscribe' => $config->emailFooterLinks(true),  
  316. 'company_address' => nl2br($config->getValue('company_address')),  
  317. 'is_debug' => $this->isDebug(),  
  318. 'i18n' => $this->getTranslations() 
  319. ); 
  320.  
  321. $viewbrowser = $config->view_in_browser_link(true); 
  322. if($viewbrowser) { 
  323. $data['viewbrowser'] = $viewbrowser; 
  324.  
  325. return $helper_render_engine->render($data, 'templates/newsletter/editor/editor_template.html'); 
  326.  
  327. function renderEditorHeader($data = null) { 
  328. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  329. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  330. $helper_render_engine->setStripSpecialchars(true); 
  331.  
  332. if($data !== null) { 
  333. $block = $data; 
  334. } else { 
  335. $block = $this->getData('header'); 
  336.  
  337. $data = array_merge($block, array('i18n' => $this->getTranslations())); 
  338. return $helper_render_engine->render($data, 'templates/newsletter/editor/header_template.html'); 
  339.  
  340. function renderEditorBody() { 
  341. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  342. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  343.  
  344. $blocks = $this->getData('body'); 
  345. if(empty($blocks)) return ''; 
  346.  
  347. $body = ''; 
  348. foreach($blocks as $key => $block) { 
  349. // generate block template 
  350. $data = array_merge($block, array('i18n' => $this->getTranslations())); 
  351. $body .= $helper_render_engine->render($data, 'templates/newsletter/editor/block_template.html'); 
  352.  
  353. return $body; 
  354.  
  355. function renderEditorFooter($data = null) 
  356. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  357. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  358.  
  359. if($data !== null) { 
  360. $block = $data; 
  361. } else { 
  362. $block = $this->getData('footer'); 
  363.  
  364. $data = array_merge($block, array('i18n' => $this->getTranslations())); 
  365.  
  366. return $helper_render_engine->render($data, 'templates/newsletter/editor/footer_template.html'); 
  367.  
  368. function renderEditorBlock($block = array()) { 
  369. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  370. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  371. $helper_render_engine->setStripSpecialchars(true); 
  372.  
  373. $block['i18n'] = $this->getTranslations(); 
  374.  
  375. return $helper_render_engine->render($block, 'templates/newsletter/editor/block_'.$block['type'].'.html'); 
  376.  
  377. /** render auto post */ 
  378. function renderEditorAutoPost($posts = array(), $params = array()) { 
  379. $output = ''; 
  380. if(isset($params['post_ids'])) { 
  381. $output .= '<input type="hidden" name="post_ids" value="'.$params['post_ids'].'" />'; 
  382.  
  383. // check if there are posts to display 
  384. if(empty($posts)) { 
  385. // set background color 
  386. $background_color = ''; 
  387. if(isset($params['bgcolor1'])) { 
  388. $background_color = $params['bgcolor1']; 
  389.  
  390. // display a message stating that the latest content has been sent 
  391. $block = array( 
  392. 'no-block' => true,  
  393. 'type' => 'content',  
  394. 'alignment' => 'center',  
  395. 'background_color' => $background_color,  
  396. 'image' => null,  
  397. 'text' => array('value' => base64_encode(__('Latest content already sent.', WYSIJA))) 
  398. ); 
  399. $output .= $this->renderEditorBlock($block); 
  400. } else { 
  401. // otherwise, render all posts into blocks 
  402. $output .= $this->renderPostsToBlocks($posts, $params, 'autopost'); 
  403.  
  404. return $output; 
  405.  
  406. function renderEmailAutoPost($posts = array(), $params = array()) { 
  407. if(empty($posts)) { 
  408. return ''; 
  409. } else { 
  410. return $this->renderPostsToBlocks($posts, $params, 'autopost'); 
  411.  
  412. function renderEmailBlock($block = array()) { 
  413. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  414. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  415. $helper_render_engine->setStripSpecialchars(true); 
  416.  
  417. // set block background color 
  418. $background_color = null; 
  419. if(isset($block['background_color'])) { 
  420. $background_color = $block['background_color']; 
  421.  
  422. // set rtl mode 
  423. $block['is_rtl'] = $this->isRtl(); 
  424.  
  425. $blockHTML = $helper_render_engine->render($block, 'templates/newsletter/email/block_template.html'); 
  426.  
  427. // convert lists 
  428. $blockHTML = $this->convertLists($blockHTML); 
  429.  
  430. // apply inline styles 
  431. $blockHTML = $this->applyInlineStyles('body', $blockHTML, array('background_color' => $background_color)); 
  432.  
  433. return $blockHTML; 
  434.  
  435. function renderPostsToBlocks($posts = array(), $params = array(), $mode = 'post') { 
  436. $html = ''; 
  437. $context = $this->getContext(); 
  438.  
  439. $helper_articles = WYSIJA::get('articles', 'helper'); 
  440.  
  441. if($params['title_tag'] === 'list') { 
  442. $list = '<ul class="align-'.$params['title_alignment'].'">'; 
  443.  
  444. // make sure empty bgcolors are set to transparent 
  445. if(!isset($params['bgcolor1']) || (isset($params['bgcolor1']) && strlen($params['bgcolor1']) === 0)) { 
  446. $params['bgcolor1'] = ''; 
  447. if(!isset($params['bgcolor2']) || (isset($params['bgcolor2']) && strlen($params['bgcolor2']) === 0)) { 
  448. $params['bgcolor2'] = ''; 
  449.  
  450. // BEGIN - posts 
  451. for($i = 0, $count = count($posts); $i < $count; $i++) { 
  452. $post = $posts[$i]; 
  453. $is_odd = (bool)($i % 2); 
  454. $is_last = (bool)($i === ($count - 1)); 
  455.  
  456. // set default background color to transparent 
  457. $background_color = ''; 
  458.  
  459. // set background color for each post 
  460. if($is_odd === false) $background_color = $params['bgcolor1']; 
  461. if($is_odd === true) $background_color = $params['bgcolor2']; 
  462.  
  463. if($params['image_alignment'] === 'alternate') { 
  464. $image_alignment = ($is_odd === false) ? 'left' : 'right'; 
  465. } else if($params['image_alignment'] === 'none') { 
  466. $image_alignment = 'left'; 
  467. $post['post_image'] = null; 
  468. } else { 
  469. $image_alignment = $params['image_alignment']; 
  470.  
  471. // build basic block data 
  472. $block = array( 
  473. 'position' => $i,  
  474. 'type' => 'content',  
  475. 'alignment' => $image_alignment,  
  476. 'background_color' => $background_color,  
  477. 'image' => null,  
  478. 'text' => null 
  479. ); 
  480.  
  481. // in case of autopost, we need to remove the "block" container because each block will be rendered within the autopost block 
  482. if($mode === 'autopost') { 
  483. $block['no-block'] = true; 
  484.  
  485. // get title 
  486. $title = $helper_articles->getPostTitle($post, $params); 
  487.  
  488. if(!isset($params['title_position'])) { 
  489. $params['title_position'] = 'inside'; 
  490.  
  491. // if post content is title, force title position inside 
  492. if($params['post_content'] === 'title') { 
  493. $params['title_position'] = 'inside'; 
  494.  
  495. // only display titles as a list 
  496. if($params['title_tag'] === 'list') { 
  497. $list .= $title; 
  498. continue; 
  499.  
  500. // if the title is outside, generate its own block 
  501. if($params['title_position'] === 'outside') { 
  502. // generate title 
  503. $title_block = array_merge($block, array( 
  504. 'alignment' => 'left',  
  505. 'text' => array( 
  506. 'value' => base64_encode($title) 
  507. )); 
  508.  
  509. if($context === 'editor') { 
  510. $html .= $this->renderEditorBlock($title_block); 
  511. } else if($context === 'email') { 
  512. $html .= $this->renderEmailBlock($title_block); 
  513.  
  514. // generate content 
  515. $content_block = array_merge($block, $helper_articles->convertPostToBlock($post, array_merge($params, array('image_alignment' => $image_alignment)))); 
  516.  
  517. if($context === 'editor') { 
  518. $html .= $this->renderEditorBlock($content_block); 
  519. } else if($context === 'email') { 
  520. $html .= $this->renderEmailBlock($content_block); 
  521.  
  522. // display divider if required 
  523. if(isset($params['divider']) && ($params['divider'] !== null && $is_last === false)) { 
  524. // display divider only if there is one and if it's not the last post 
  525. $divider_block = array_merge( 
  526. array( 
  527. 'type' => 'divider',  
  528. 'no-block' => ($mode === 'autopost') 
  529. ),  
  530. $params['divider'] 
  531. ); 
  532.  
  533. if($context === 'editor') { 
  534. $html .= $this->renderEditorBlock($divider_block); 
  535. } else if($context === 'email') { 
  536. $html .= $this->renderEmailBlock($divider_block); 
  537. // END - Posts 
  538.  
  539. if($params['title_tag'] === 'list') { 
  540. $list .= '</ul>'; 
  541. $list_block = array_merge($block, array( 
  542. 'alignment' => 'center',  
  543. 'type' => 'content',  
  544. 'text' => array( 
  545. 'value' => base64_encode($list) 
  546. )); 
  547. if($context === 'editor') { 
  548. $html .= $this->renderEditorBlock($list_block); 
  549. } else if($context === 'email') { 
  550. $html .= $this->renderEmailBlock($list_block); 
  551.  
  552. return $html; 
  553.  
  554. /** render draggable images list */ 
  555. function renderImages($data = array()) { 
  556. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  557. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  558.  
  559. return $helper_render_engine->render(array('images' => $data), 'templates/newsletter/editor/toolbar/images.html'); 
  560.  
  561. /** render themes list */ 
  562. function renderThemes() { 
  563. $themes = array(); 
  564. $hThemes = WYSIJA::get('themes', 'helper'); 
  565.  
  566. $installed = $hThemes->getInstalled(); 
  567.  
  568. // get default selected theme 
  569. $model_config = WYSIJA::get('config', 'model'); 
  570. $default_theme = $model_config->getValue('newsletter_default_theme', 'default'); 
  571.  
  572. if(empty($installed)) { 
  573. return ''; 
  574. } else { 
  575. foreach($installed as $theme) { 
  576. $theme_info = $hThemes->getInformation($theme); 
  577. $theme_info['is_selected'] = (bool)($default_theme === $theme); 
  578. $themes[] = $theme_info; 
  579.  
  580. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  581. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  582.  
  583. return $helper_render_engine->render(array('themes' => $themes, 'i18n' => $this->getTranslations()), 'templates/newsletter/editor/toolbar/themes.html'); 
  584.  
  585. function renderThemeStyles($theme = 'default') { 
  586. $this->setContext('editor'); 
  587.  
  588. $hThemes = WYSIJA::get('themes', 'helper'); 
  589. $stylesheet = $hThemes->getStylesheet($theme); 
  590.  
  591. if($stylesheet === NULL) { 
  592. // load default settings 
  593. $this->setStyles(null); 
  594. } else { 
  595. // a stylesheet has been found, let's extract styles 
  596. $styles = array(); 
  597. $defaults = $this->getDefaultStyles(); 
  598. // look for each tags 
  599. foreach($defaults as $tag => $values) { 
  600. // look for css rules 
  601. preg_match('/\.?'.$tag.'\s?{(.+)}/Ui', $stylesheet, $matches); 
  602. if(isset($matches[1])) { 
  603. // extract styles 
  604. $styles[$tag] = $this->extractStyles($matches[1]); 
  605. } else { 
  606. // fallback to default 
  607. $styles[$tag] = $defaults[$tag]; 
  608. $this->setStyles($styles); 
  609.  
  610. return array( 
  611. 'css' => $this->renderStyles(),  
  612. 'form' => $this->renderStylesBar() 
  613. ); 
  614.  
  615. function extractStyles($raw) { 
  616. $rules = explode(';', $raw); 
  617. $output = array(); 
  618. foreach($rules as $rule) { 
  619. $sub_property = false; 
  620. $combo = explode(':', $rule); 
  621. if(count($combo) === 2) { 
  622. list($property, $value) = $combo; 
  623. // remove leading and trailing space 
  624. $property = trim($property); 
  625. $value = trim($value); 
  626. } else { 
  627. continue; 
  628.  
  629. switch($property) { 
  630. case 'background': 
  631. case 'background-color': 
  632. $property = 'background'; 
  633. case 'color': 
  634. // remove # from color 
  635. $value = str_replace('#', '', $value); 
  636. // check if its a 3 chars color 
  637. if(strlen($value) === 3) { 
  638. $value = sprintf('%s%s%s%s%s%s', substr($value, 0, 1), substr($value, 0, 1), substr($value, 1, 1), substr($value, 1, 1), substr($value, 2, 1), substr($value, 2, 1)); 
  639. break; 
  640. case 'font-family': 
  641. $property = 'family'; 
  642. $fonts = explode(', ', $value); 
  643. $value = array_shift($fonts); 
  644. break; 
  645. case 'font-size': 
  646. $property = 'size'; 
  647. case 'height': 
  648. $value = (int)$value; 
  649. break; 
  650. case 'text-decoration': 
  651. $property = 'underline'; 
  652. $value = ($value === 'none') ? '-1' : '1'; 
  653. break; 
  654. case 'border-color': 
  655. // remove # from color 
  656. $value = str_replace('#', '', $value); 
  657. // check if its a 3 chars color 
  658. if(strlen($value) === 3) { 
  659. $value = sprintf('%s%s%s%s%s%s', substr($value, 0, 1), substr($value, 0, 1), substr($value, 1, 1), substr($value, 1, 1), substr($value, 2, 1), substr($value, 2, 1)); 
  660. list($property, $sub_property) = explode('-', $property); 
  661. break; 
  662. case 'border-size': 
  663. $value = (int)$value; 
  664. list($property, $sub_property) = explode('-', $property); 
  665. break; 
  666. case 'border-style': 
  667. list($property, $sub_property) = explode('-', $property); 
  668. break; 
  669.  
  670. if($sub_property !== FALSE) { 
  671. $output[$property][$sub_property] = $value; 
  672. } else { 
  673. $output[$property] = $value; 
  674. return $output; 
  675.  
  676. function renderTheme($theme = 'default') { 
  677. $output = array( 
  678. 'header' => null,  
  679. 'footer' => null,  
  680. 'divider' => null 
  681. ); 
  682.  
  683. $hThemes = WYSIJA::get('themes', 'helper'); 
  684. $data = $hThemes->getData($theme); 
  685.  
  686. if($data['header'] !== NULL) { 
  687. $output['header'] = $this->renderEditorHeader($data['header']); 
  688.  
  689. if($data['footer'] !== NULL) { 
  690. $output['footer'] = $this->renderEditorFooter($data['footer']); 
  691.  
  692. if($data['divider'] !== NULL) { 
  693. $output['divider'] = $this->renderEditorBlock(array_merge(array('no-block' => true), $data['divider'])); 
  694. $output['divider_options'] = $data['divider']; 
  695.  
  696. return $output; 
  697.  
  698. /** render styles bar */ 
  699. function renderStylesBar() { 
  700. $this->setContext('editor'); 
  701.  
  702. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  703. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  704. $helper_render_engine->setStripSpecialchars(true); 
  705.  
  706. $data = $this->getStyles(); 
  707. $data['i18n'] = $this->getTranslations(); 
  708. $data['TEXT_SIZES'] = $this->TEXT_SIZES; 
  709. $data['VIEWBROWSER_SIZES'] = $this->VIEWBROWSER_SIZES; 
  710. $data['TITLE_SIZES'] = $this->TITLE_SIZES; 
  711. $data['FONTS'] = array_keys($this->FONTS); 
  712.  
  713. return $helper_render_engine->render($data, 'templates/newsletter/editor/toolbar/styles.html'); 
  714.  
  715. function formatStyles($styles = array()) { 
  716. if(empty($styles)) return; 
  717.  
  718. $data = array(); 
  719. foreach($styles as $style => $value) { 
  720. $stylesArray = explode('-', $style); 
  721. if(count($stylesArray) === 2) { 
  722. $data[$stylesArray[0]][$stylesArray[1]] = $value; 
  723. } else if(count($stylesArray) === 3) { 
  724. // handle transparent colors 
  725. if($stylesArray[2] === 'transparent') { 
  726. $data[$stylesArray[0]][$stylesArray[1]] = $stylesArray[2]; 
  727. } else { 
  728. $data[$stylesArray[0]][$stylesArray[1]][$stylesArray[2]] = $value; 
  729.  
  730. return $data; 
  731.  
  732. function getContext() { 
  733. return $this->_context; 
  734.  
  735. function setContext($value = null) { 
  736. if($value !== null) $this->_context = $value; 
  737.  
  738. function isDebug() { 
  739. return ($this->_debug === true); 
  740.  
  741. function getEncoded($type = 'data') { 
  742. return base64_encode(serialize($this->{'get'.ucfirst($type)}())); 
  743.  
  744. function getDecoded($type = 'data') { 
  745. return unserialize(base64_decode($this->{'get'.ucfirst($type)}())); 
  746.  
  747. /** methods */ 
  748. function isDataValid() { 
  749. return ($this->getData() !== null); 
  750.  
  751. /** Styles methods */ 
  752. function renderStyles() { 
  753. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  754. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  755. $helper_render_engine->setStripSpecialchars(true); 
  756. $helper_render_engine->setInline(true); 
  757.  
  758. $data = $this->getStyles(); 
  759. $data['context'] = $this->getContext(); 
  760. $data['is_rtl'] = $this->isRtl(); 
  761.  
  762. switch($data['context']) { 
  763. case 'editor': 
  764. $helper_render_engine->setStripSpecialchars(false); 
  765. $data['viewbrowser_container'] = '#wysija_viewbrowser'; 
  766. $data['wysija_container'] = '#wysija_wrapper'; 
  767. $data['header_container'] = '#wysija_header'; 
  768. $data['body_container'] = '#wysija_body'; 
  769. $data['text_container'] = '.wysija_editable'; 
  770. $data['footer_container'] = '#wysija_footer'; 
  771. $data['placeholder_container'] = '#wysija_block_placeholder'; 
  772. $data['unsubscribe_container'] = '#wysija_unsubscribe'; 
  773. return $helper_render_engine->render($data, 'styles/css-'.$data['context'].'.html'); 
  774. break; 
  775.  
  776. case 'email': 
  777. $helper_render_engine->setStripSpecialchars(true); 
  778. $data['wysija_container'] = '#wysija_wrapper'; 
  779. $data['viewbrowser_container'] = '.wysija_viewbrowser_container'; 
  780. $data['header'] = '.wysija_header'; 
  781. $data['header_container'] = '.wysija_header_container'; 
  782. $data['body_container'] = '.wysija_block'; 
  783. $data['text_container'] = '.wysija_text_container'; 
  784. $data['image_container'] = '.wysija_image_container'; 
  785. $data['image_placeholder'] = '.wysija_image_placeholder'; 
  786. $data['footer'] = '.wysija_footer'; 
  787. $data['footer_container'] = '.wysija_footer_container'; 
  788. $data['unsubscribe_container'] = '.wysija_unsubscribe_container'; 
  789. return $helper_render_engine->render($data, 'templates/newsletter/email/css.html'); 
  790. break; 
  791.  
  792. /** Email methods */ 
  793. function renderNotification($email = NULL) { 
  794. $this->_hide_viewbrowser = true; 
  795. $this->_hide_unsubscribe = true; 
  796. return $this->renderEmail($email); 
  797.  
  798. function renderEmail($email = NULL) { 
  799.  
  800. // fixes issue with pcre functions 
  801. @ini_set('pcre.backtrack_limit', 1000000); 
  802.  
  803. $this->setContext('email'); 
  804.  
  805. // set language direction 
  806. $this->setLanguageDirection(); 
  807.  
  808. if($this->isDataValid() === false) { 
  809. throw new Exception('data is not valid'); 
  810. } else { 
  811. // set email data for later use 
  812. $this->setEmailData($email); 
  813.  
  814. // render header 
  815. $data = array( 
  816. 'viewbrowser' => $this->renderEmailViewBrowser(),  
  817. 'header' => $this->renderEmailHeader(),  
  818. 'body' => $this->renderEmailBody(),  
  819. 'footer' => $this->renderEmailFooter(),  
  820. 'unsubscribe' => $this->renderEmailUnsubscribe(),  
  821. 'css' => $this->renderStyles(),  
  822. 'styles' => $this->getStyles(),  
  823. 'hide_viewbrowser' => $this->_hide_viewbrowser,  
  824. 'hide_unsubscribe' => $this->_hide_unsubscribe 
  825. ); 
  826.  
  827. // get language direction 
  828. $data['is_rtl'] = $this->isRtl(); 
  829.  
  830. // set email subject if specified 
  831. $data['subject'] = $this->getEmailData('subject'); 
  832.  
  833. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  834. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  835. $helper_render_engine->setStripSpecialchars(true); 
  836. $helper_render_engine->setInline(true); 
  837.  
  838. try { 
  839. $template = $helper_render_engine->render($data, 'templates/newsletter/email/email_template.html'); 
  840. $template = preg_replace('/\s*(?!<\")\/\*[^\*]+\*\/(?!\")\s*/', '', $template); 
  841.  
  842. return $template; 
  843. } catch(Exception $e) { 
  844. return ''; 
  845.  
  846. function renderEmailViewBrowser() { 
  847. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  848. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  849. $helper_render_engine->setStripSpecialchars(true); 
  850.  
  851. $config=WYSIJA::get('config', 'model'); 
  852. $data = $config->view_in_browser_link(); 
  853. if(!isset($data['link'])) { 
  854. return ''; 
  855. } else { 
  856. // generate block template 
  857. $viewbrowser = $helper_render_engine->render($data, 'templates/newsletter/email/viewbrowser_template.html'); 
  858.  
  859. // apply inline styles 
  860. $viewbrowser = $this->applyInlineStyles('viewbrowser', $viewbrowser); 
  861.  
  862. return $viewbrowser; 
  863.  
  864. function renderEmailUnsubscribe() { 
  865. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  866. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  867. $helper_render_engine->setStripSpecialchars(true); 
  868.  
  869. $config = WYSIJA::get('config', 'model'); 
  870.  
  871. $data = array( 
  872. 'unsubscribe' => $config->emailFooterLinks(),  
  873. 'company_address' => nl2br($config->getValue('company_address')) 
  874. ); 
  875.  
  876. // generate block template 
  877. $unsubscribe = $helper_render_engine->render($data, 'templates/newsletter/email/unsubscribe_template.html'); 
  878.  
  879. // apply inline styles 
  880. $unsubscribe = $this->applyInlineStyles('unsubscribe', $unsubscribe); 
  881.  
  882. return $unsubscribe; 
  883.  
  884. function renderEmailHeader() { 
  885. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  886. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  887. $helper_render_engine->setStripSpecialchars(true); 
  888.  
  889. $data = $this->getData('header'); 
  890. $data['styles'] = array('header' => $this->getStyles('header')); 
  891.  
  892. // check for emptyness 
  893. if($data['text'] === NULL and $data['image']['static'] === TRUE) { 
  894. return NULL; 
  895.  
  896. // set header content width 
  897. $data['block_width'] = 600; 
  898.  
  899. // generate block template 
  900. $header = $helper_render_engine->render($data, 'templates/newsletter/email/header_template.html'); 
  901.  
  902. // apply inline styles 
  903. $header = $this->applyInlineStyles('header', $header); 
  904.  
  905. return $header; 
  906.  
  907. function encodeParameters($params = array()) { 
  908. // encode string parameters 
  909. $keys_to_encode = array('author_label', 'category_label', 'readmore'); 
  910. foreach($keys_to_encode as $key) { 
  911. if(isset($params[$key]) && strlen(trim($params[$key])) > 0) { 
  912. $params[$key] = base64_encode(stripslashes($params[$key])); 
  913. return $params; 
  914.  
  915. function decodeParameters($params = array()) { 
  916. // decode string parameters 
  917. $keys_to_decode = array('author_label', 'category_label', 'readmore'); 
  918. foreach($keys_to_decode as $key) { 
  919. if(isset($params[$key]) && strlen(trim($params[$key])) > 0) { 
  920. $params[$key] = base64_decode($params[$key]); 
  921. return $params; 
  922.  
  923. function renderEmailBody() { 
  924. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  925. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  926. $helper_render_engine->setStripSpecialchars(true); 
  927.  
  928. $blocks = $this->getData('body'); 
  929. $styles = array('body' => $this->getStyles('body')); 
  930.  
  931. // default newsletter type 
  932. $newsletter_type = 'default'; 
  933.  
  934. // check if we need to interpret shortcodes 
  935. $model_config = WYSIJA::get('config', 'model'); 
  936. $interpret_shortcode = (bool)$model_config->getValue('interp_shortcode'); 
  937.  
  938. $body = ''; 
  939.  
  940. // check if we are dealing with an auto newsletter 
  941. $email = $this->getEmailData(); 
  942. if(isset($email['params']['autonl']) && !empty($email['params']['autonl'])) { 
  943. // set newsletter type to automattic newsletter 
  944. $newsletter_type = 'automatic'; 
  945.  
  946. // posts data 
  947. $first_subject = null; 
  948. $post_count = 0; 
  949. $post_ids = array(); 
  950.  
  951.  
  952. foreach($blocks as $key => $block) { 
  953. // reset block HTML so as to avoid duplicates 
  954. $blockHTML = ''; 
  955.  
  956. // reset category_ids 
  957. $include_category_ids = array(); 
  958. $exclude_category_ids = array(); 
  959. $category_ids = array(); 
  960.  
  961. // specific background color 
  962. $block_background_color = null; 
  963.  
  964. // get background color if specified 
  965. if(isset($block['background_color']) && strlen($block['background_color']) === 6) { 
  966. $block_background_color = $block['background_color']; 
  967.  
  968. // block width 
  969. $block['block_width'] = 600; 
  970.  
  971. if($block['type'] === 'auto-post') { 
  972. // special case for auto post, we need to fetch posts, taking previously sent posts into account 
  973.  
  974. // get email data 
  975. //$email = $this->getEmailData(); 
  976.  
  977. // get block params 
  978. $blockParams = $block['params']; 
  979.  
  980. // format parameters 
  981. $params = array(); 
  982.  
  983. $category_ids = array(); 
  984. $category_condition = 'include'; 
  985.  
  986. foreach($blockParams as $pairs) { 
  987. // store category_ids in email for better performance on immediate sending of WP Posts. 
  988. if($pairs['key'] === 'category_ids') { 
  989. $pair_value = trim($pairs['value']); 
  990. if(!empty($pair_value)) { 
  991. $category_ids = array_map('intval', explode(', ', trim($pairs['value']))); 
  992. // store category condition (include / exclude) for same above reason. 
  993. if($pairs['key'] === 'category_condition') { 
  994. $category_condition = (in_array(trim($pairs['value']), array('include', 'exclude'))) ? trim($pairs['value']) : 'include'; 
  995. $params[$pairs['key']] = $pairs['value']; 
  996.  
  997. // make sure we store category_ids 
  998. if(!empty($category_ids)) { 
  999. if($category_condition === 'include') { 
  1000. $include_category_ids = array_unique($category_ids); 
  1001. if($category_condition === 'exclude') { 
  1002. $exclude_category_ids = array_unique($category_ids); 
  1003.  
  1004. // make sure empty bgcolors are set to transparent 
  1005. if(isset($params['bgcolor1']) && strlen($params['bgcolor1']) === 0) { 
  1006. $params['bgcolor1'] = 'transparent'; 
  1007. if(isset($params['bgcolor2']) && strlen($params['bgcolor2']) === 0) { 
  1008. $params['bgcolor2'] = 'transparent'; 
  1009.  
  1010. // make sure the default params are set 
  1011. if(array_key_exists('autonl', $email['params']) === false) { 
  1012. $email['params']['autonl'] = array(); 
  1013. if(array_key_exists('articles', $email['params']['autonl']) === false) { 
  1014. $email['params']['autonl']['articles'] = array( 
  1015. 'ids' => array(),  
  1016. 'count' => 0,  
  1017. 'first_subject' => '' 
  1018. ); 
  1019.  
  1020. // exclude already sent post ids from selection 
  1021. if(!empty($email['params']['autonl']['articles']['ids'])) { 
  1022. $params['exclude'] = $email['params']['autonl']['articles']['ids']; 
  1023. } else { 
  1024. $email['params']['autonl']['articles']['ids'] = array(); 
  1025.  
  1026. //we set the post_date to filter articles only older than that one 
  1027. if(isset($email['params']['autonl']['firstSend'])) { 
  1028. $params['post_date'] = $email['params']['autonl']['firstSend']; 
  1029.  
  1030. // if immediate let it know to the get post 
  1031. if(isset($email['params']['autonl']['articles']['immediatepostid'])) { 
  1032. $params['include'] = (int)$email['params']['autonl']['articles']['immediatepostid']; 
  1033. $params['post_limit'] = 1; 
  1034. }else{ 
  1035. //we set the post_date to filter articles only older than the last time we sent articles 
  1036. if(isset($email['params']['autonl']['lastSend'])) { 
  1037. $params['post_date'] = $email['params']['autonl']['lastSend']; 
  1038. }else{ 
  1039. //get the latest child newsletter sent_at value 
  1040. $mEmail=WYSIJA::get('email', 'model'); 
  1041. $mEmail->reset(); 
  1042. $mEmail->orderBy('email_id', 'DESC'); 
  1043. $lastEmailSent=$mEmail->getOne(false, array('campaign_id'=>$email['campaign_id'], 'type'=>'1')); 
  1044.  
  1045. if(!empty($lastEmailSent)) $params['post_date'] = $lastEmailSent['sent_at']; 
  1046.  
  1047. // decode specific keys 
  1048. $params = $this->decodeParameters($params); 
  1049.  
  1050. // include/exclude category_ids 
  1051. $params['include_category_ids'] = $include_category_ids; 
  1052. $params['exclude_category_ids'] = $exclude_category_ids; 
  1053.  
  1054. // check for already inserted posts 
  1055. if(!empty($post_ids)) { 
  1056. $params['exclude'] = $post_ids; 
  1057.  
  1058. // get posts for this block 
  1059. $model_wp_posts = WYSIJA::get('wp_posts', 'model'); 
  1060. $posts = $model_wp_posts->get_posts($params); 
  1061.  
  1062. // check if we have posts to display 
  1063. if(!empty($posts)) { 
  1064. // get divider if necessary 
  1065. if(isset($params['show_divider']) && $params['show_divider'] === 'yes') { 
  1066. if(isset($email['params']['divider'])) { 
  1067. // either from the email params 
  1068. $params['divider'] = $email['params']['divider']; 
  1069. } else { 
  1070. // get default divider otherwise 
  1071. $helper_dividers = WYSIJA::get('dividers', 'helper'); 
  1072. $params['divider'] = $helper_dividers->getDefault(); 
  1073.  
  1074. $helper_articles = WYSIJA::get('articles', 'helper'); 
  1075.  
  1076. foreach($posts as $key => $post) { 
  1077. // assign first post title to autonl parameters (this is used to display the [newsletter:post_title] shortcode in the subject) 
  1078. if($first_subject === null && strlen(trim($posts[$key]['post_title'])) > 0) { 
  1079. $first_subject = trim($posts[$key]['post_title']); 
  1080.  
  1081. // check if shortcodes should be interpreted (value comes from WP options) 
  1082. if($interpret_shortcode === true) { 
  1083. // interpret shortcodes 
  1084. $posts[$key]['post_content'] = apply_filters('the_content', $post['post_content']); 
  1085. if($params['image_alignment'] !== 'none') { 
  1086. // get thumbnail 
  1087. $posts[$key]['post_image'] = $helper_articles->getImage($post); 
  1088. $post_ids[] = (int)$post['ID']; 
  1089. $post_count++; 
  1090. // render html from post data and params 
  1091. $blockHTML = $this->renderEmailAutoPost($posts, $params); 
  1092.  
  1093. $this->setEmailData($email); 
  1094. } else { 
  1095. // set styles 
  1096. $block['styles'] = $styles; 
  1097.  
  1098. // set rtl 
  1099. $block['is_rtl'] = $this->isRtl(); 
  1100.  
  1101. // generate block template 
  1102. $blockHTML = $helper_render_engine->render($block, 'templates/newsletter/email/block_template.html'); 
  1103.  
  1104. if($block['type'] !== 'raw') { 
  1105. // convert lists in block 
  1106. $blockHTML = $this->convertLists($blockHTML); 
  1107.  
  1108. // apply inline styles 
  1109. $blockHTML = $this->applyInlineStyles('body', $blockHTML, array('background_color' => $block_background_color)); 
  1110.  
  1111. // append generated html to body 
  1112. if($blockHTML !== '') { 
  1113. // render each block 
  1114. $body .= $blockHTML; 
  1115.  
  1116. if($newsletter_type === 'automatic') { 
  1117. $email = $this->getEmailData(); 
  1118. // set auto newsletter parameters 
  1119. $email['params']['autonl']['articles']['count'] = $post_count; 
  1120. $email['params']['autonl']['articles']['first_subject'] = $first_subject; 
  1121. // merge post ids 
  1122. if(!isset( $email['params']['autonl']['articles']['ids'])) { 
  1123. $email['params']['autonl']['articles']['ids'] = array(); 
  1124. $email['params']['autonl']['articles']['ids'] = array_unique(array_merge( 
  1125. (array)$email['params']['autonl']['articles']['ids'],  
  1126. (array)$post_ids 
  1127. )); 
  1128.  
  1129. $this->setEmailData($email); 
  1130.  
  1131. return $body; 
  1132.  
  1133. function renderEmailFooter() { 
  1134. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  1135. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  1136. $helper_render_engine->setStripSpecialchars(true); 
  1137.  
  1138. $data = $this->getData('footer'); 
  1139. $data['styles'] = array('footer' => $this->getStyles('footer')); 
  1140.  
  1141. // check for emptyness 
  1142. if($data['text'] === NULL and $data['image']['static'] === TRUE) { 
  1143. return NULL; 
  1144.  
  1145. // set footer content width 
  1146. $data['block_width'] = 600; 
  1147.  
  1148. // generate block template 
  1149. $footer = $helper_render_engine->render($data, 'templates/newsletter/email/footer_template.html'); 
  1150.  
  1151. // apply inline styles 
  1152. $footer = $this->applyInlineStyles('footer', $footer); 
  1153.  
  1154. return $footer; 
  1155.  
  1156. /** 
  1157. * area : header, body, footer, unsubscribe, viewbrowser 
  1158. * block : raw html 
  1159. */ 
  1160. function applyInlineStyles($area, $block, $extra = array()) { 
  1161. $helper_render_engine = WYSIJA::get('render_engine', 'helper'); 
  1162. $helper_render_engine->setTemplatePath(WYSIJA_EDITOR_TOOLS); 
  1163. $helper_render_engine->setInline(true); 
  1164.  
  1165. // common tags 
  1166. $tags = array( 
  1167. 'table' => array( 
  1168. 'border-collapse' => 'collapse',  
  1169. 'mso-table-space' => '0pt',  
  1170. 'clear' => 'both' 
  1171. ),  
  1172. 'td' => array( 
  1173. 'border-collapse' => 'collapse' 
  1174. ); 
  1175. // common classes 
  1176. $classes = array(); 
  1177.  
  1178. // set block background color 
  1179. if(array_key_exists('background_color', $extra) and $extra['background_color'] !== null) { 
  1180. $background_color = $extra['background_color']; 
  1181. } else { 
  1182. switch ($area) { 
  1183. case 'header': 
  1184. case 'footer': 
  1185. case 'body': 
  1186. $background_color = $this->getStyle($area, 'background'); 
  1187. break; 
  1188. case 'unsubscribe': 
  1189. $background_color = $this->getStyle('html', 'background'); 
  1190. break; 
  1191. default: 
  1192. $background_color = $this->getStyle('html', 'background'); 
  1193. break; 
  1194.  
  1195. // set common styles 
  1196. $styles = array( 
  1197. 'titles' => array( 
  1198. 'padding' => '0',  
  1199. 'margin' => '0',  
  1200. 'font-style' => 'normal',  
  1201. 'font-weight' => 'normal',  
  1202. 'line-height' => '125%',  
  1203. 'letter-spacing' => 'normal' 
  1204. ),  
  1205. 'images' => array( 
  1206. 'margin' => '0',  
  1207. 'padding' => '0',  
  1208. 'display' => 'block',  
  1209. 'border' => array( 
  1210. 'size' => '1px',  
  1211. 'style' => 'solid',  
  1212. 'color' => $this->formatColor($background_color) 
  1213. ); 
  1214.  
  1215. // area specific classes/tags 
  1216. switch($area) { 
  1217. case 'header': 
  1218. case 'footer': 
  1219. $classes = array( 
  1220. 'wysija_'.$area => array('min-width' => '100%'),  
  1221. 'wysija_'.$area.'_container' => $this->getStyles($area),  
  1222. 'wysija_content_container' => array_merge($this->getStyles($area), array('padding' => '0')),  
  1223. // images alignments 
  1224. 'wysija_image_container center' => array_merge($styles['images'], array('margin' => '0 auto 0 auto', 'text-align' => 'center', 'border' => '0')),  
  1225. 'wysija_image_container left' => array_merge($styles['images'], array('border' => '0')),  
  1226. 'wysija_image_container right' => array_merge($styles['images'], array('border' => '0')),  
  1227. // image placeholder 
  1228. 'wysija_image_placeholder' => array('padding' => '0 0 0 0', 'margin' => '0 0 0 0', 'display' => 'block'),  
  1229.  
  1230. // links around images 
  1231. 'wysija_image_link' => array('outline' => '0', 'border' => '0', 'margin' => '0', 'padding' => '0', 'display' => 'block'),  
  1232.  
  1233. // images 
  1234. 'image_fix' => array('display' => 'block', 'outline' => '0', 'text-decoration' => 'none', 'interpolation' => 'bicubic') 
  1235. ); 
  1236. break; 
  1237.  
  1238. case 'body': 
  1239. $tags = array_merge($tags, array( 
  1240. 'h1' => array_merge($styles['titles'], $this->getStyles('h1')),  
  1241. 'h2' => array_merge($styles['titles'], $this->getStyles('h2')),  
  1242. 'h3' => array_merge($styles['titles'], $this->getStyles('h3')),  
  1243. 'p' => array_merge($this->getStyles('body'), array('word-wrap' => true, 'padding' => '0', 'margin' => '1em 0', 'line-height' => '1.5em', 'vertical-align' => 'top', 'letter-spacing' => 'normal')),  
  1244. 'li' => array_merge($this->getStyles('body'), array('word-wrap' => true, 'padding' => '0', 'margin' => '0', 'line-height' => '1.5em', 'vertical-align' => 'top', 'letter-spacing' => 'normal')),  
  1245. 'a' => array_merge($this->getStyles('a'), array('word-wrap' => true)),  
  1246. 'br' => array('margin' => '0', 'padding' => '0', 'line-height' => '150%') 
  1247. )); 
  1248.  
  1249. $classes = array( 
  1250. // blocks 
  1251. 'wysija_block' => array('min-width' => '100%'),  
  1252. 'wysija_content_container' => array('padding' => '10px 17px 10px 17px'),  
  1253. 'wysija_divider_container' => array('padding' => '15px 17px 15px 17px'),  
  1254. 'wysija_gallery_container' => array('padding' => '10px 17px 10px 17px'),  
  1255.  
  1256. // text 
  1257. // 'wysija_text_container' => array('margin' => '1em 0'),  
  1258. 'align-left' => array('text-align' => 'left'),  
  1259. 'align-center' => array('text-align' => 'center'),  
  1260. 'align-right' => array('text-align' => 'right'),  
  1261. 'align-justify' => array('text-align' => 'justify'),  
  1262.  
  1263. // links around images 
  1264. 'wysija_image_link' => array('outline' => '0', 'border' => '0', 'margin' => '0', 'padding' => '0', 'display' => 'block'),  
  1265.  
  1266. // images 
  1267. 'image_fix' => array('display' => 'block', 'outline' => '0', 'text-decoration' => 'none', 'interpolation' => 'bicubic'),  
  1268.  
  1269. // images alignments 
  1270. 'wysija_image_table center' => array('margin' => '0 auto 0 auto', 'text-align' => 'center'),  
  1271.  
  1272. 'wysija_image_container center' => array_merge($styles['images'], array('padding' => '0 0 0 0', 'margin' => '0 auto 0 auto', 'text-align' => 'left')),  
  1273. 'wysija_image_container left' => array_merge($styles['images'], array('padding' => '0 10px 0 0')),  
  1274. 'wysija_image_container right' => array_merge($styles['images'], array('padding' => '0 0 0 10px')),  
  1275.  
  1276. 'wysija_image_placeholder left' => array('padding' => '0 0 0 0', 'margin' => '0 10px 0 0', 'display' => 'block'),  
  1277. 'wysija_image_placeholder right' => array('padding' => '0 0 0 0', 'margin' => '0 0 0 10px', 'display' => 'block'),  
  1278.  
  1279. // gallery 
  1280. 'wysija_gallery_table center' => array('margin' => '0 auto 0 auto', 'text-align' => 'center'),  
  1281. 'wysija_cell_container' => array('border' => $styles['images']['border']),  
  1282.  
  1283. // lists 
  1284. 'wysija_list_item' => array('margin' => '0') 
  1285. ); 
  1286. break; 
  1287.  
  1288. case 'viewbrowser': 
  1289. $tags = array_merge($tags, array( 
  1290. 'a' => $this->getStyles('viewbrowser') 
  1291. )); 
  1292.  
  1293. $classes = array( 
  1294. 'wysija_viewbrowser_container' => array_merge( 
  1295. $this->getStyles('html'),  
  1296. $this->getStyles('viewbrowser'),  
  1297. array( 
  1298. 'text-align' => 'center',  
  1299. 'padding' => '8px' 
  1300. ); 
  1301. break; 
  1302.  
  1303. case 'unsubscribe': 
  1304. $tags = array_merge($tags, array( 
  1305. 'a' => $this->getStyles('unsubscribe') 
  1306. )); 
  1307.  
  1308. $classes = array( 
  1309. 'wysija_unsubscribe_container' => array_merge( 
  1310. $this->getStyles('html'),  
  1311. $this->getStyles('unsubscribe'),  
  1312. array( 
  1313. 'family' => 'Verdana',  
  1314. 'size' => '12',  
  1315. 'text-align' => 'center',  
  1316. 'padding' => '8px' 
  1317. ); 
  1318. break; 
  1319.  
  1320. $tags_to_check = array('p', 'a', 'ul', 'li', 'h1', 'h2', 'h3'); 
  1321. $classes_to_check = array('wysija_content_container', 'wysija_image_container', 'wysija_divider_container', 'wysija_gallery_container', 'wysija_cell_container', 'wysija_list_item'); 
  1322.  
  1323. // check tags and set custom background color 
  1324. foreach($tags_to_check as $tag) { 
  1325. if(isset($tags[$tag])) { 
  1326. $tags[$tag]['background'] = $background_color; 
  1327.  
  1328. // check classes and set custom background color 
  1329. foreach($classes_to_check as $class) { 
  1330. if(isset($classes[$class])) { 
  1331. $classes[$class]['background'] = $background_color; 
  1332.  
  1333. if(empty($tags) === FALSE) { 
  1334.  
  1335. foreach($tags as $tag => $styles) { 
  1336. $styles = $this->splitSpacing($styles); 
  1337. $inlineStyles = $helper_render_engine->renderCSS($styles); 
  1338. $tags['#< *'.$tag.'((?:(?!style).)*)>#Ui'] = '<'.$tag.' style="'.$inlineStyles.'"$1>'; 
  1339. unset($tags[$tag]); 
  1340.  
  1341. $block = preg_replace(array_keys($tags), $tags, $block); 
  1342.  
  1343. if(empty($classes) === FALSE) { 
  1344. foreach($classes as $class => $styles) { 
  1345. // split spacing styles 
  1346. $styles = $this->splitSpacing($styles); 
  1347. $inlineStyles = $helper_render_engine->renderCSS($styles); 
  1348.  
  1349. // build regexp for this class 
  1350. $classes['#<([^ /]+) ((?:(?!>|style).)*)(?:style="([^"]*)")?((?:(?!>|style).)*)class="([^"]*)'.$class.'([^"]*)"((?:(?!>|style).)*)(?:style="([^"]*)")?((?:(?!>|style).)*)>#Ui'] = '<$1 $2$4$7 class="$5'.$class.'$6" style="$3$8'.$inlineStyles.'" $9>'; 
  1351.  
  1352. unset($classes[$class]); 
  1353.  
  1354. // apply styles 
  1355. $styledBlock = preg_replace(array_keys($classes), $classes, $block); 
  1356. // cleanup output (fixes rendering issues) 
  1357. $styledBlock = preg_replace('/(\t+)/', ' ', $styledBlock); 
  1358. $styledBlock = preg_replace('/( +)/', ' ', $styledBlock); 
  1359.  
  1360. // Check if the preg_replace worked. Otherwise we simply return the original block 
  1361. if(strlen(trim($styledBlock)) > 0) { 
  1362. $block = $styledBlock; 
  1363.  
  1364. return $block; 
  1365.  
  1366. function splitSpacing($styles) { 
  1367. foreach($styles as $property => $value) { 
  1368. if($property === 'margin' or $property === 'padding') { 
  1369. // extract multi-values 
  1370. $values = explode(' ', $value); 
  1371.  
  1372. // split values depending on values count 
  1373. switch(count($values)) { 
  1374. case 1: 
  1375. $styles[$property.'-top'] = $values[0]; 
  1376. $styles[$property.'-right'] = $values[0]; 
  1377. $styles[$property.'-bottom'] = $values[0]; 
  1378. $styles[$property.'-left'] = $values[0]; 
  1379. break; 
  1380. case 2: 
  1381. $styles[$property.'-top'] = $values[0]; 
  1382. $styles[$property.'-right'] = $values[1]; 
  1383. $styles[$property.'-bottom'] = $values[0]; 
  1384. $styles[$property.'-left'] = $values[1]; 
  1385. break; 
  1386. case 4: 
  1387. $styles[$property.'-top'] = $values[0]; 
  1388. $styles[$property.'-right'] = $values[1]; 
  1389. $styles[$property.'-bottom'] = $values[2]; 
  1390. $styles[$property.'-left'] = $values[3]; 
  1391. break; 
  1392.  
  1393. // unset original value 
  1394. unset($styles[$property]); 
  1395. return $styles; 
  1396.  
  1397. function formatColor($color) { 
  1398. if(strlen(trim($color)) === 0 or $color === 'transparent') { 
  1399. return 'transparent'; 
  1400. } else { 
  1401. return '#'.$color; 
  1402.  
  1403. // converts lists (ul, ol, li) into paragraphs for email compatibility 
  1404. function convertList($matches) { 
  1405. $output = $matches[5]; 
  1406. // get alignment from ul tag and make sure it's a valid value 
  1407. $alignment = (isset($matches[3]) && in_array($matches[3], array('align-left', 'align-center', 'align-right'))) ? trim($matches[3]) : 'align-left'; 
  1408. // convert opening li tag to paragraph 
  1409. $output = preg_replace('#<li ?((?:(?!>|class).)*)(?:class="([^"]*)")?((?:(?!>|class).)*)>#Uis', "\n".'<p class="wysija_list_item '.$alignment.'">• ', $output); 
  1410. // replace all closing li tags by p 
  1411. $output = str_replace('</li>', "</p>\n", $output); 
  1412. return $output; 
  1413.  
  1414. function convertLists($html) { 
  1415. $model_config = WYSIJA::get('config', 'model'); 
  1416. if((bool)$model_config->getValue('disable_list_conversion') === true) { 
  1417. return $html; 
  1418. // define maximum recursion level 
  1419. $max_recursion = 100; 
  1420. $recursion_count = 0; 
  1421. // as long as there are ul tags in the content and we haven't reached the maximum recursion value 
  1422. while(strpos($html, '<ul') !== false && $recursion_count < $max_recursion) { 
  1423. $html = preg_replace_callback( 
  1424. '#(<ul ?((?:(?!>|class).)*)(?:class="([^"]*)")?((?:(?!>|class).)*)>((?:(?!<ul).)*)<\/ul>)#Uis',  
  1425. array($this, 'convertList'),  
  1426. $html 
  1427. ); 
  1428. $recursion_count++; 
  1429.  
  1430. return $html;