/core/fields/wysiwyg.php

  1. <?php 
  2.  
  3. class acf_field_wysiwyg extends acf_field 
  4.  
  5. /** 
  6. * __construct 
  7. * 
  8. * Set name / label needed for actions / filters 
  9. * 
  10. * @since 3.6 
  11. * @date 23/01/13 
  12. */ 
  13.  
  14. function __construct() 
  15. // vars 
  16. $this->name = 'wysiwyg'; 
  17. $this->label = __("Wysiwyg Editor", 'acf'); 
  18. $this->category = __("Content", 'acf'); 
  19. $this->defaults = array( 
  20. 'toolbar' => 'full',  
  21. 'media_upload' => 'yes',  
  22. 'default_value' => '',  
  23. ); 
  24.  
  25.  
  26. // Create an acf version of the_content filter (acf_the_content) 
  27. if( isset($GLOBALS['wp_embed']) ) { 
  28.  
  29. add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 ); 
  30. add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 ); 
  31.  
  32.  
  33. add_filter( 'acf_the_content', 'capital_P_dangit', 11 ); 
  34. add_filter( 'acf_the_content', 'wptexturize' ); 
  35. add_filter( 'acf_the_content', 'convert_smilies' ); 
  36. add_filter( 'acf_the_content', 'convert_chars' ); 
  37. add_filter( 'acf_the_content', 'wpautop' ); 
  38. add_filter( 'acf_the_content', 'shortcode_unautop' ); 
  39. //add_filter( 'acf_the_content', 'prepend_attachment' ); *should only be for the_content (causes double image on attachment page) 
  40. add_filter( 'acf_the_content', 'do_shortcode', 11); 
  41.  
  42.  
  43. // do not delete! 
  44. parent::__construct(); 
  45.  
  46.  
  47. // filters 
  48. add_filter( 'acf/fields/wysiwyg/toolbars', array( $this, 'toolbars'), 1, 1 ); 
  49. add_filter( 'mce_external_plugins', array( $this, 'mce_external_plugins'), 20, 1 ); 
  50.  
  51.  
  52.  
  53. /** 
  54. * mce_external_plugins 
  55. * 
  56. * This filter will add in the tinyMCE 'code' plugin which is missing in WP 3.9 
  57. * 
  58. * @type function 
  59. * @date 18/04/2014 
  60. * @since 5.0.0 
  61. * 
  62. * @param $post_id (int) 
  63. * @return $post_id (int) 
  64. */ 
  65.  
  66. function mce_external_plugins( $plugins ) { 
  67.  
  68. // global 
  69. global $wp_version; 
  70.  
  71.  
  72. // WP 3.9 an above 
  73. if( version_compare($wp_version, '3.9', '>=' ) ) { 
  74.  
  75. // add code 
  76. $plugins['code'] = apply_filters('acf/get_info', 'dir') . 'js/tinymce.code.min.js'; 
  77.  
  78.  
  79.  
  80. // return 
  81. return $plugins; 
  82.  
  83.  
  84.  
  85. /** 
  86. * toolbars() 
  87. * 
  88. * This filter allowsyou to customize the WYSIWYG toolbars 
  89. * 
  90. * @param $toolbars - an array of toolbars 
  91. * 
  92. * @return $toolbars - the modified $toolbars 
  93. * 
  94. * @type filter 
  95. * @since 3.6 
  96. * @date 23/01/13 
  97. */ 
  98.  
  99. function toolbars( $toolbars ) { 
  100.  
  101. // global 
  102. global $wp_version; 
  103.  
  104.  
  105. // vars 
  106. $editor_id = 'acf_settings'; 
  107.  
  108.  
  109. if( version_compare($wp_version, '3.9', '>=' ) ) { 
  110.  
  111. // Full 
  112. $toolbars['Full'] = array( 
  113.  
  114. 1 => apply_filters( 'mce_buttons', array('bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'hr', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ), $editor_id ),  
  115.  
  116. 2 => apply_filters( 'mce_buttons_2', array( 'formatselect', 'underline', 'alignjustify', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help', 'code' ), $editor_id ),  
  117.  
  118. 3 => apply_filters('mce_buttons_3', array(), $editor_id),  
  119.  
  120. 4 => apply_filters('mce_buttons_4', array(), $editor_id),  
  121.  
  122. ); 
  123.  
  124.  
  125. // Basic 
  126. $toolbars['Basic'] = array( 
  127.  
  128. 1 => apply_filters( 'teeny_mce_buttons', array('bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'alignleft', 'aligncenter', 'alignright', 'undo', 'redo', 'link', 'unlink', 'fullscreen'), $editor_id ),  
  129.  
  130. ); 
  131.  
  132. } else { 
  133.  
  134. // Full 
  135. $toolbars['Full'] = array( 
  136.  
  137. 1 => apply_filters( 'mce_buttons', array('bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'justifyleft', 'justifycenter', 'justifyright', 'link', 'unlink', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ), $editor_id ),  
  138.  
  139. 2 => apply_filters( 'mce_buttons_2', array( 'formatselect', 'underline', 'justifyfull', 'forecolor', 'pastetext', 'pasteword', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help', 'code' ), $editor_id ),  
  140.  
  141. 3 => apply_filters('mce_buttons_3', array(), $editor_id),  
  142.  
  143. 4 => apply_filters('mce_buttons_4', array(), $editor_id),  
  144.  
  145. ); 
  146.  
  147.  
  148. // Basic 
  149. $toolbars['Basic'] = array( 
  150.  
  151. 1 => apply_filters( 'teeny_mce_buttons', array('bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'undo', 'redo', 'link', 'unlink', 'fullscreen'), $editor_id ),  
  152.  
  153. ); 
  154.  
  155.  
  156.  
  157.  
  158. // Custom - can be added with acf/fields/wysiwyg/toolbars filter 
  159.  
  160.  
  161. return $toolbars; 
  162.  
  163.  
  164. /** 
  165. * input_admin_head() 
  166. * 
  167. * This action is called in the admin_head action on the edit screen where your field is created. 
  168. * Use this action to add css and javascript to assist your create_field() action. 
  169. * 
  170. * @info http://codex.wordpress.org/Plugin_API/Action_Reference/admin_head 
  171. * @type action 
  172. * @since 3.6 
  173. * @date 23/01/13 
  174. */ 
  175.  
  176. function input_admin_head() 
  177. add_action( 'admin_footer', array( $this, 'admin_footer') ); 
  178.  
  179. function admin_footer() 
  180. ?> 
  181. <div style="display:none;"> 
  182. <?php wp_editor( '', 'acf_settings' ); ?> 
  183. </div> 
  184. <?php 
  185.  
  186.  
  187. /** 
  188. * create_field() 
  189. * 
  190. * Create the HTML interface for your field 
  191. * 
  192. * @param $field - an array holding all the field's data 
  193. * 
  194. * @type action 
  195. * @since 3.6 
  196. * @date 23/01/13 
  197. */ 
  198.  
  199. function create_field( $field ) { 
  200.  
  201. // global 
  202. global $wp_version; 
  203.  
  204.  
  205. // vars 
  206. $id = uniqid('acf-editor-'); 
  207. $default_editor = 'tinymce'; 
  208.  
  209.  
  210. // filter value for editor 
  211. remove_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 ); 
  212. remove_filter( 'acf_the_editor_content', 'wp_htmledit_pre', 10, 1 ); 
  213. remove_filter( 'acf_the_editor_content', 'wp_richedit_pre', 10, 1 ); 
  214.  
  215.  
  216. // WP 4.3 
  217. if( version_compare($wp_version, '4.3', '>=' ) ) { 
  218.  
  219. add_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 ); 
  220.  
  221.  
  222. // WP < 4.3 
  223. } else { 
  224.  
  225. $function = user_can_richedit() ? 'wp_richedit_pre' : 'wp_htmledit_pre'; 
  226.  
  227. add_filter('acf_the_editor_content', $function, 10, 1); 
  228.  
  229.  
  230.  
  231. // filter 
  232. $field['value'] = apply_filters( 'acf_the_editor_content', $field['value'], $default_editor ); 
  233.  
  234. ?> 
  235. <div id="wp-<?php echo $id; ?>-wrap" class="acf_wysiwyg wp-core-ui wp-editor-wrap tmce-active" data-toolbar="<?php echo $field['toolbar']; ?>" data-upload="<?php echo $field['media_upload']; ?>"> 
  236. <div id="wp-<?php echo $id; ?>-editor-tools" class="wp-editor-tools hide-if-no-js"> 
  237. <?php if( user_can_richedit() && $field['media_upload'] == 'yes' ): ?> 
  238. <div id="wp-<?php echo $id; ?>-media-buttons" class="wp-media-buttons"> 
  239. <?php do_action( 'media_buttons', $id ); ?> 
  240. </div> 
  241. <?php endif; ?> 
  242. </div> 
  243. <div id="wp-<?php echo $id; ?>-editor-container" class="wp-editor-container"> 
  244. <textarea id="<?php echo $id; ?>" class="wp-editor-area" name="<?php echo $field['name']; ?>"><?php echo $field['value']; ?></textarea> 
  245. </div> 
  246. </div> 
  247. <?php 
  248.  
  249.  
  250.  
  251. /** 
  252. * create_options() 
  253. * 
  254. * Create extra options for your field. This is rendered when editing a field. 
  255. * The value of $field['name'] can be used (like bellow) to save extra data to the $field 
  256. * 
  257. * @type action 
  258. * @since 3.6 
  259. * @date 23/01/13 
  260. * 
  261. * @param $field - an array holding all the field's data 
  262. */ 
  263.  
  264. function create_options( $field ) 
  265. // vars 
  266. $key = $field['name']; 
  267.  
  268. ?> 
  269. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  270. <td class="label"> 
  271. <label><?php _e("Default Value", 'acf'); ?></label> 
  272. <p><?php _e("Appears when creating a new post", 'acf') ?></p> 
  273. </td> 
  274. <td> 
  275. <?php  
  276. do_action('acf/create_field', array( 
  277. 'type' => 'textarea',  
  278. 'name' => 'fields['.$key.'][default_value]',  
  279. 'value' => $field['default_value'],  
  280. )); 
  281. ?> 
  282. </td> 
  283. </tr> 
  284. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  285. <td class="label"> 
  286. <label><?php _e("Toolbar", 'acf'); ?></label> 
  287. </td> 
  288. <td> 
  289. <?php 
  290.  
  291. $toolbars = apply_filters( 'acf/fields/wysiwyg/toolbars', array() ); 
  292. $choices = array(); 
  293.  
  294. if( is_array($toolbars) ) 
  295. foreach( $toolbars as $k => $v ) 
  296. $label = $k; 
  297. $name = sanitize_title( $label ); 
  298. $name = str_replace('-', '_', $name); 
  299.  
  300. $choices[ $name ] = $label; 
  301.  
  302. do_action('acf/create_field', array( 
  303. 'type' => 'radio',  
  304. 'name' => 'fields['.$key.'][toolbar]',  
  305. 'value' => $field['toolbar'],  
  306. 'layout' => 'horizontal',  
  307. 'choices' => $choices 
  308. )); 
  309. ?> 
  310. </td> 
  311. </tr> 
  312. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  313. <td class="label"> 
  314. <label><?php _e("Show Media Upload Buttons?", 'acf'); ?></label> 
  315. </td> 
  316. <td> 
  317. <?php  
  318. do_action('acf/create_field', array( 
  319. 'type' => 'radio',  
  320. 'name' => 'fields['.$key.'][media_upload]',  
  321. 'value' => $field['media_upload'],  
  322. 'layout' => 'horizontal',  
  323. 'choices' => array( 
  324. 'yes' => __("Yes", 'acf'),  
  325. 'no' => __("No", 'acf'),  
  326. )); 
  327. ?> 
  328. </td> 
  329. </tr> 
  330. <?php 
  331.  
  332.  
  333. /** 
  334. * format_value_for_api() 
  335. * 
  336. * This filter is appied to the $value after it is loaded from the db and before it is passed back to the api functions such as the_field 
  337. * 
  338. * @type filter 
  339. * @since 3.6 
  340. * @date 23/01/13 
  341. * 
  342. * @param $value - the value which was loaded from the database 
  343. * @param $post_id - the $post_id from which the value was loaded 
  344. * @param $field - the field array holding all the field options 
  345. * 
  346. * @return $value - the modified value 
  347. */ 
  348.  
  349. function format_value_for_api( $value, $post_id, $field ) 
  350. // apply filters 
  351. $value = apply_filters( 'acf_the_content', $value ); 
  352.  
  353.  
  354. // follow the_content function in /wp-includes/post-template.php 
  355. $value = str_replace(']]>', ']]>', $value); 
  356.  
  357.  
  358. return $value; 
  359.  
  360.  
  361. new acf_field_wysiwyg(); 
  362.  
  363. ?> 
.