fields.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. <?php
  2. class NewsletterFields {
  3. static $field_open = '<div>';
  4. static $field_close = '</div>';
  5. var $controls;
  6. public function __construct(NewsletterControls $controls) {
  7. $this->controls = $controls;
  8. }
  9. public function _open($subclass = '') {
  10. echo '<div class="tnp-field ', $subclass, '">';
  11. }
  12. public function _close() {
  13. echo '</div>';
  14. }
  15. public function _label($text, $for = '') {
  16. echo '<label class="tnp-label">', $text, '</label>';
  17. }
  18. public function _description($attrs) {
  19. if (empty($attrs['description']))
  20. return;
  21. echo '<div class="tnp-description">', $attrs['description'], '</div>';
  22. }
  23. public function _id($name) {
  24. return 'options-' . esc_attr($name);
  25. }
  26. public function _merge_base_attrs($attrs) {
  27. return array_merge(array('description' => '', 'label' => '', 'help_url' => ''), $attrs);
  28. }
  29. public function _merge_attrs($attrs, $defaults = array()) {
  30. return array_merge(array('description' => '', 'label' => '', 'help_url' => ''), $defaults, $attrs);
  31. }
  32. public function section($title = '') {
  33. echo '<h3 class="tnp-section">', $title, '</h3>';
  34. }
  35. public function separator() {
  36. echo '<div class="tnp-field tnp-separator"></div>';
  37. }
  38. public function checkbox($name, $label = '', $attrs = array()) {
  39. $attrs = $this->_merge_base_attrs($attrs);
  40. $attrs = array_merge(array('description' => '', 'label' => ''), $attrs);
  41. $this->_open('tnp-checkbox');
  42. $this->controls->checkbox($name, $label);
  43. $this->_description($attrs);
  44. $this->_close();
  45. }
  46. public function text($name, $label = '', $attrs = array()) {
  47. $attrs = $this->_merge_base_attrs($attrs);
  48. $attrs = array_merge(array('description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => ''), $attrs);
  49. $this->_open();
  50. $this->_label($label);
  51. $value = $this->controls->get_value($name);
  52. echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[' . $name . ']" type="text"';
  53. if (!empty($attrs['size'])) {
  54. echo ' style="width: ', $attrs['size'], 'px"';
  55. }
  56. echo ' value="', esc_attr($value), '">';
  57. if (!empty($attrs['label_after']))
  58. echo $attrs['label_after'];
  59. //$this->controls->text($name, $attrs['size'], $attrs['placeholder']);
  60. $this->_description($attrs);
  61. $this->_close();
  62. }
  63. public function multitext($name, $label = '', $count = 10, $attrs = array()) {
  64. $attrs = $this->_merge_base_attrs($attrs);
  65. $attrs = array_merge(array('description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => ''), $attrs);
  66. $this->_open();
  67. $this->_label($label);
  68. for ($i = 1; $i <= $count; $i++) {
  69. $value = $this->controls->get_value($name . '_' . $i);
  70. echo '<input id="', $this->_id($name . '_' . $i), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[', $name, '_', $i, ']" type="text"';
  71. if (!empty($attrs['size'])) {
  72. echo ' style="width: ', $attrs['size'], 'px"';
  73. }
  74. echo ' value="', esc_attr($value), '">';
  75. }
  76. if (!empty($attrs['label_after']))
  77. echo $attrs['label_after'];
  78. //$this->controls->text($name, $attrs['size'], $attrs['placeholder']);
  79. $this->_description($attrs);
  80. $this->_close();
  81. }
  82. public function textarea($name, $label = '', $attrs = array()) {
  83. $attrs = $this->_merge_attrs($attrs);
  84. $this->_open();
  85. $this->_label($label);
  86. $this->controls->textarea_fixed($name);
  87. $this->_description($attrs);
  88. $this->_close();
  89. }
  90. public function wp_editor($name, $label = '', $attrs = array()) {
  91. global $wp_version;
  92. $attrs = $this->_merge_attrs($attrs);
  93. $this->_open();
  94. $this->_label($label);
  95. $value = $this->controls->get_value($name);
  96. if (is_array($value)) {
  97. $value = implode("\n", $value);
  98. }
  99. if (version_compare($wp_version, '4.8', '<')) {
  100. echo '<p><strong>Rich editor available only with WP 4.8+</strong></p>';
  101. }
  102. echo '<textarea id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" style="width: 100%;height:250px">';
  103. echo esc_html($value);
  104. echo '</textarea>';
  105. if (version_compare($wp_version, '4.8', '>=')) {
  106. echo '<script>wp.editor.remove("options-', $name, '");';
  107. echo 'wp.editor.initialize("options-', $name, '", { tinymce: {toolbar1: "undo redo | formatselect fontselect fontsizeselect | bold italic forecolor backcolor | link unlink | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | help", fontsize_formats: "11px 12px 14px 16px 18px 24px 36px 48px", plugins: "link textcolor colorpicker", default_link_target: "_blank", relative_urls : false, convert_urls: false}});</script>';
  108. }
  109. $this->_description($attrs);
  110. $this->_close();
  111. }
  112. public function select($name, $label = '', $options = array(), $attrs = array()) {
  113. $attrs = $this->_merge_attrs($attrs);
  114. $this->_open();
  115. $this->_label($label);
  116. $this->controls->select($name, $options);
  117. $this->_description($attrs);
  118. $this->_close();
  119. }
  120. public function yesno($name, $label = '', $attrs = array()) {
  121. $attrs = $this->_merge_attrs($attrs);
  122. $this->_open();
  123. $this->_label($label);
  124. $this->controls->yesno($name);
  125. $this->_description($attrs);
  126. $this->_close();
  127. }
  128. public function select_number($name, $label = '', $min, $max, $attrs = array()) {
  129. $attrs = $this->_merge_attrs($attrs);
  130. $this->_open();
  131. $this->_label($label);
  132. $this->controls->select_number($name, $min, $max);
  133. $this->_description($attrs);
  134. $this->_close();
  135. }
  136. /** General field to collect a dimension */
  137. public function size($name, $label = '', $attrs = array()) {
  138. $attrs = $this->_merge_base_attrs($attrs);
  139. $attrs = array_merge(array('description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => 'px'), $attrs);
  140. $this->_open('tnp-size');
  141. $this->_label($label);
  142. $value = $this->controls->get_value($name);
  143. echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[' . $name . ']" type="text"';
  144. if (!empty($attrs['size'])) {
  145. echo ' style="width: ', $attrs['size'], 'px"';
  146. }
  147. echo ' value="', esc_attr($value), '">', $attrs['label_after'];
  148. //$this->controls->text($name, $attrs['size'], $attrs['placeholder']);
  149. $this->_description($attrs);
  150. $this->_close();
  151. }
  152. /** Collects a color in RGB format (#RRGGBB) with a picker. */
  153. public function color($name, $label, $attrs = array()) {
  154. $attrs = array_merge(array('description' => '', 'placeholder' => ''), $attrs);
  155. $this->_open('tnp-color');
  156. $this->_label($label);
  157. $this->controls->color($name);
  158. $this->_description($attrs);
  159. $this->_close();
  160. }
  161. /** Configuration for a simple button with label and color */
  162. public function button($name, $label = '', $attrs = array()) {
  163. $attrs = $this->_merge_attrs($attrs, array('placeholder' => 'Label...', 'url_placeholder' => 'https://...', 'url' => true));
  164. $this->_open('tnp-cta');
  165. $this->_label($label);
  166. $value = $this->controls->get_value($name . '_label');
  167. echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[' . $name . '_label]" type="text"';
  168. echo ' style="width: 200px"';
  169. echo ' value="', esc_attr($value), '">';
  170. if ($attrs['url']) {
  171. $value = $this->controls->get_value($name . '_url');
  172. echo '<input id="', $this->_id($name . '_url'), '" placeholder="', esc_attr($attrs['url_placeholder']), '" name="options[' . $name . '_url]" type="url"';
  173. echo ' style="width: 200px"';
  174. echo ' value="', esc_attr($value), '">';
  175. }
  176. $this->controls->css_font($name . '_font', array('weight' => false));
  177. $this->controls->color($name . '_background');
  178. $this->_close();
  179. }
  180. public function url($name, $label = '', $attrs = array()) {
  181. $attrs = array_merge(array('description' => '', 'placeholder' => 'https://...'), $attrs);
  182. $this->_open();
  183. $this->_label($label);
  184. $this->controls->text_url($name);
  185. $this->_description($attrs);
  186. $this->_close();
  187. }
  188. public function post_type($name = 'post_type', $label = '', $attrs = array()) {
  189. $post_types = get_post_types(array('public' => true), 'objects', 'and');
  190. $attrs = array_merge(array('description' => ''), $attrs);
  191. $this->_open();
  192. $this->_label($label);
  193. $options = array('post' => 'Standard post');
  194. foreach ($post_types as $post_type) {
  195. if ($post_type->name == 'post' || $post_type->name == 'page' || $post_type->name == 'attachment')
  196. continue;
  197. $options[$post_type->name] = $post_type->labels->name;
  198. }
  199. $value = $this->controls->get_value($name);
  200. echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" onchange="tnpc_reload_options(event); return false;">';
  201. if (!empty($first)) {
  202. echo '<option value="">' . esc_html($first) . '</option>';
  203. }
  204. foreach ($options as $key => $label) {
  205. echo '<option value="' . esc_attr($key) . '"';
  206. if ($value == $key)
  207. echo ' selected';
  208. echo '>' . esc_html($label) . '</option>';
  209. }
  210. echo '</select>';
  211. $this->_description($attrs);
  212. $this->_close();
  213. }
  214. function posts($name, $label, $count = 20, $args = array()) {
  215. $args = array_merge(array('filters' => array(
  216. 'posts_per_page' => 5,
  217. 'offset' => 0,
  218. 'category' => '',
  219. 'category_name' => '',
  220. 'orderby' => 'date',
  221. 'order' => 'DESC',
  222. 'include' => '',
  223. 'exclude' => '',
  224. 'meta_key' => '',
  225. 'meta_value' => '',
  226. 'post_type' => 'post',
  227. 'post_mime_type' => '',
  228. 'post_parent' => '',
  229. 'author' => '',
  230. 'author_name' => '',
  231. 'post_status' => 'publish',
  232. 'suppress_filters' => true,
  233. 'last_post_option'=>false
  234. )), $args);
  235. $args['filters']['posts_per_page'] = $count;
  236. $posts = get_posts($args['filters']);
  237. $options = array();
  238. if ($args['last_post_option']) {
  239. $options['last'] = 'Most recent post';
  240. }
  241. foreach ($posts as $post) {
  242. $options['' . $post->ID] = $post->post_title;
  243. }
  244. $this->select($name, $label, $options);
  245. }
  246. function lists($name, $label, $attrs = array()) {
  247. $attrs = $this->_merge_attrs($attrs);
  248. $this->_open();
  249. $this->_label($label);
  250. $lists = $this->controls->get_list_options($empty_label);
  251. $this->controls->select($name, $lists);
  252. $this->_description($attrs);
  253. $this->_close();
  254. }
  255. /**
  256. * Media selector using the WP media library (for images and files.
  257. * The field to use it the {$name}_id which contains the media id.
  258. *
  259. * @param type $name
  260. * @param type $label
  261. * @param type $attrs
  262. */
  263. public function media($name, $label = '', $attrs = array()) {
  264. $attrs = $this->_merge_attrs($attrs, array('alt'=>false));
  265. $this->_open();
  266. $this->_label($label);
  267. $this->controls->media($name);
  268. if ($attrs['alt']) {
  269. $this->controls->text($name . '_alt', 20, 'Alternative text');
  270. }
  271. $this->_description($attrs);
  272. $this->_close();
  273. }
  274. public function categories($name = 'categories', $label = '', $attrs = array()) {
  275. if (empty($label))
  276. $label = __('Categories', 'newsletter');
  277. $attrs = $this->_merge_attrs($attrs);
  278. $this->_open('tnp-categories');
  279. $this->_label($label);
  280. $this->controls->categories_group($name);
  281. $this->_description($attrs);
  282. $this->_close();
  283. }
  284. public function terms($taxonomy, $label = '', $attrs = array()) {
  285. $name = 'tax_' . $taxonomy;
  286. if (empty($label))
  287. $label = __('Terms', 'newsletter');
  288. $attrs = $this->_merge_attrs($attrs);
  289. $this->_open('tnp-categories');
  290. $this->_label($label);
  291. $terms = get_terms($taxonomy);
  292. if (empty($terms)) {
  293. echo 'No terms in use';
  294. } else {
  295. echo '<div class="newsletter-checkboxes-group">';
  296. foreach ($terms as $term) {
  297. /* @var $term WP_Term */
  298. echo '<div class="newsletter-checkboxes-item">';
  299. $this->controls->checkbox_group($name, $term->term_id, esc_html($term->name));
  300. echo '</div>';
  301. }
  302. echo '<div style="clear: both"></div>';
  303. echo '</div>';
  304. }
  305. $this->_description($attrs);
  306. $this->_close();
  307. }
  308. public function language($name = 'language', $label = '', $attrs = array()) {
  309. if (!Newsletter::instance()->is_multilanguage())
  310. return;
  311. if (empty($label))
  312. $label = __('Language', 'newsletter');
  313. $attrs = $this->_merge_attrs($attrs);
  314. $this->_open('tnp-language');
  315. $this->_label($label);
  316. $this->controls->language($name);
  317. $this->_description($attrs);
  318. $this->_close();
  319. }
  320. /**
  321. * Collects font details for a text: family, color, size and weight to be used
  322. * directly on CSS rules. Size is a pure number.
  323. *
  324. * @param type $name
  325. * @param type $label
  326. * @param type $attrs
  327. */
  328. public function font($name = 'font', $label = 'Font', $attrs = array()) {
  329. $attrs = $this->_merge_base_attrs($attrs);
  330. $attrs = array_merge(array('hide_family' => false, 'hide_color' => false, 'hide_size' => false), $attrs);
  331. $this->_open('tnp-font');
  332. $this->_label($label);
  333. $this->controls->css_font($name);
  334. $this->_description($attrs);
  335. $this->_close();
  336. }
  337. /**
  338. * Collects fout number values representing the padding of a box. The values can
  339. * be found as {$name}_top, {$name}_bottom, {$name}_left, {$name}_right.
  340. *
  341. * @param type $name
  342. * @param type $label
  343. * @param type $attrs
  344. */
  345. public function padding($name = 'block_padding', $label = 'Padding', $attrs = array()) {
  346. $attrs = $this->_merge_base_attrs($attrs);
  347. $attrs = array_merge(array('padding_top' => 0, 'padding_left' => 0, 'padding_right' => 0, 'padding_bottom' => 0), $attrs);
  348. $field_only = !empty($attrs['field_only']);
  349. if (!$field_only) {
  350. $this->_open('tnp-padding');
  351. $this->_label($label);
  352. }
  353. echo '<div class="tnp-padding-fields">';
  354. echo '&larr;';
  355. $this->controls->text($name . '_left', 5);
  356. echo '&nbsp;&nbsp;&nbsp;';
  357. echo '&uarr;';
  358. $this->controls->text($name . '_top', 5);
  359. echo '&nbsp;&nbsp;&nbsp;';
  360. $this->controls->text($name . '_bottom', 5);
  361. echo '&darr;';
  362. echo '&nbsp;&nbsp;&nbsp;';
  363. $this->controls->text($name . '_right', 5);
  364. echo '&rarr;';
  365. echo '</div>';
  366. if (!$field_only) {
  367. $this->_description($attrs);
  368. $this->_close();
  369. }
  370. }
  371. /**
  372. * Background color selector for a block.
  373. */
  374. public function block_background() {
  375. $this->color('block_background', __('Block Background', 'newsletter'));
  376. }
  377. /**
  378. * Padding selector for a block.
  379. */
  380. public function block_padding() {
  381. $this->padding('block_padding', __('Padding', 'newsletter'));
  382. }
  383. public function block_commons() {
  384. $this->separator();
  385. $this->_open('tnp-block-commons');
  386. $this->_label('Padding and background');
  387. $this->controls->color('block_background');
  388. echo '&nbsp;&nbsp;&nbsp;';
  389. $this->padding('block_padding', '', $attrs = array('field_only' => true));
  390. $this->_close();
  391. }
  392. }