PageRenderTime 27ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/php/core.php

https://github.com/quadcodes/wp-front-end-editor
PHP | 277 lines | 239 code | 31 blank | 7 comment | 10 complexity | f163838885fe169f96f4e6178ffc69ce MD5 | raw file
  1. <?php
  2. abstract class FEE_Core {
  3. const NONCE = 'front-end-editor';
  4. static $options;
  5. private static $fields;
  6. private static $active_fields;
  7. private static $instances = array();
  8. private static $plugin_url;
  9. private static $js_dependencies = array();
  10. static function init( $options ) {
  11. self::$options = $options;
  12. add_action( 'wp_ajax_front-end-editor', array( __CLASS__, 'ajax_response' ) );
  13. add_action( 'template_redirect', array( __CLASS__, '_init' ) );
  14. // TODO: Add equivalent hook for BuddyPress
  15. }
  16. static function _init() {
  17. if ( !is_user_logged_in() || apply_filters( 'front_end_editor_disable', false ) ) {
  18. return;
  19. }
  20. if ( self::$options->rich ) {
  21. FEE_AlohaEditor::enqueue();
  22. }
  23. add_action( 'wp_head', array( __CLASS__, 'add_filters' ), 100 );
  24. add_action( 'wp_footer', array( __CLASS__, 'scripts' ) );
  25. }
  26. static function scripts() {
  27. $wrapped = array_keys( FEE_Field_Base::get_wrapped() );
  28. if ( empty( $wrapped ) ) {
  29. return;
  30. }
  31. // Prepare data
  32. $data = array(
  33. 'edit_text' => __( 'Edit', 'front-end-editor' ),
  34. 'save_text' => __( 'Save', 'front-end-editor' ),
  35. 'cancel_text' => __( 'Cancel', 'front-end-editor' ),
  36. 'add_buttons' => current_theme_supports( 'fee-automatic-buttons' ),
  37. 'spinner' => admin_url( 'images/loading.gif' ),
  38. 'ajax_url' => admin_url( 'admin-ajax.php' ),
  39. 'nonce' => wp_create_nonce( self::NONCE ),
  40. );
  41. $css_dependencies = array();
  42. // Autosuggest
  43. if ( in_array( 'terminput', $wrapped ) ) {
  44. self::$js_dependencies[] = 'suggest';
  45. }
  46. // Thickbox
  47. if ( count( array_intersect( array( 'image', 'thumbnail', 'rich' ), $wrapped ) ) ) {
  48. $data['image'] = array(
  49. 'url' => admin_url( 'media-upload.php?post_id=0&type=image&editable_image=1&TB_iframe=true&width=640' ),
  50. 'change' => __( 'Change Image', 'front-end-editor' ),
  51. 'insert' => __( 'Insert Image', 'front-end-editor' ),
  52. 'revert' => '(' . __( 'Clear', 'front-end-editor' ) . ')',
  53. 'tb_close' => get_bloginfo( 'wpurl' ) . '/wp-includes/js/thickbox/tb-close.png',
  54. );
  55. $css_dependencies[] = 'thickbox';
  56. self::$js_dependencies[] = 'thickbox';
  57. }
  58. // Core script
  59. if ( defined('FEE_DEBUG') ) {
  60. foreach ( array( 'core', 'hover', 'init' ) as $handle ) {
  61. self::register_script( "fee-$handle", "js/$handle.js" );
  62. }
  63. foreach ( glob( dirname( FRONT_END_EDITOR_MAIN_FILE ) . '/js/fields/*.js' ) as $file ) {
  64. $file = basename( $file );
  65. self::register_script( "fee-fields-$file", "js/fields/$file", array( 'fee-core' ) );
  66. }
  67. $css_path = 'css/core.css';
  68. } else {
  69. $min = defined('SCRIPT_DEBUG') ? '' : '.min';
  70. self::register_script( 'fee-editor', "build/editor$min.js" );
  71. $css_path = 'build/editor.css';
  72. }
  73. // Core style
  74. wp_register_style( 'fee-editor', plugins_url( $css_path, FRONT_END_EDITOR_MAIN_FILE ), $css_dependencies, FRONT_END_EDITOR_VERSION );
  75. scbUtil::do_styles( 'fee-editor' );
  76. ?>
  77. <script type='text/javascript'>
  78. var FrontEndEditor = {};
  79. FrontEndEditor.data = <?php echo json_encode( $data ) ?>;
  80. </script>
  81. <?php
  82. scbUtil::do_scripts( self::$js_dependencies );
  83. do_action( 'front_end_editor_loaded', $wrapped );
  84. }
  85. private static function register_script( $handle, $src, $dependencies = array() ) {
  86. $src = plugins_url( $src, FRONT_END_EDITOR_MAIN_FILE );
  87. wp_register_script( $handle, $src, $dependencies, FRONT_END_EDITOR_VERSION, true );
  88. self::$js_dependencies[] = $handle;
  89. }
  90. // Register a new editable field
  91. static function register() {
  92. list ( $filter, $args ) = func_get_arg( 0 );
  93. if ( !class_exists( $args['class'] ) ) {
  94. trigger_error( "Class '{$args['class']}' does not exist", E_USER_WARNING );
  95. return false;
  96. }
  97. if ( !is_subclass_of( $args['class'], 'FEE_Field_Base' ) ) {
  98. trigger_error( "{$args['class']} must be a subclass of 'FEE_Field_Base", E_USER_WARNING );
  99. return false;
  100. }
  101. if ( isset( self::$fields[$filter] ) )
  102. $args = wp_parse_args( $args, self::$fields[$filter] );
  103. else
  104. $args = wp_parse_args( $args, array(
  105. 'title' => ucfirst( str_replace( '_', ' ', $filter ) ),
  106. 'type' => 'input',
  107. 'priority' => 11,
  108. 'argc' => 1
  109. ) );
  110. self::$fields[$filter] = $args;
  111. return true;
  112. }
  113. static function get_title( $filter ) {
  114. return self::$fields[$filter]['title'];
  115. }
  116. private static function make_instances() {
  117. $disabled = (array) self::$options->disabled;
  118. self::$active_fields = array();
  119. foreach ( self::get_fields() as $filter => $args ) {
  120. if ( in_array( $filter, $disabled ) )
  121. continue;
  122. self::$active_fields[ $filter ] = $args;
  123. extract( $args );
  124. self::$instances[ $filter ] = new $class( $filter, $type );
  125. }
  126. }
  127. static function add_filters() {
  128. self::make_instances();
  129. foreach ( self::$active_fields as $filter => $args ) {
  130. extract( $args );
  131. if ( empty( $title ) )
  132. continue;
  133. $instance = self::$instances[ $filter ];
  134. add_filter( $filter, array( $instance, 'wrap' ), $priority, $argc );
  135. }
  136. }
  137. static function get_fields() {
  138. // Safe hook for new editable fields to be registered
  139. if ( !did_action( 'front_end_editor_fields' ) )
  140. do_action( 'front_end_editor_fields' );
  141. return self::$fields;
  142. }
  143. static function get_args( $filter ) {
  144. return self::$fields[ $filter ];
  145. }
  146. static function ajax_response() {
  147. check_ajax_referer( self::NONCE, 'nonce' );
  148. self::make_instances();
  149. extract( wp_array_slice_assoc( $_POST, array( 'callback', 'data' ) ) );
  150. if ( 'save' == $callback )
  151. $content = stripslashes_deep( $_POST['content'] );
  152. else
  153. $content = null;
  154. if ( isset( $_POST['group'] ) ) {
  155. foreach ( $data as $i => $single_data ) {
  156. if ( isset( $_POST['commonData'] ) )
  157. $single_data = array_merge( $single_data, $_POST['commonData'] );
  158. $r[$i] = self::single_ajax_response( $callback, $single_data, @$content[$i] );
  159. }
  160. if ( isset( $_POST['createPost'] ) ) {
  161. $post_id = $data[0]['post_id'];
  162. wp_publish_post( $post_id );
  163. $r = array( 'permalink' => get_permalink( $post_id ) );
  164. }
  165. } else {
  166. $r = self::single_ajax_response( $callback, $data, $content );
  167. }
  168. die( json_encode( $r ) );
  169. }
  170. private static function single_ajax_response( $callback, $data, $content ) {
  171. $filter = $data['filter'];
  172. // Is the current field defined?
  173. if ( !$instance = self::$instances[ $filter ] )
  174. die( -1 );
  175. // Does the user have the right to do this?
  176. if ( !$instance->check( $data ) || !$instance->allow( $data ) )
  177. die( -1 );
  178. $args = self::get_args( $filter );
  179. try {
  180. if ( 'save' == $callback ) {
  181. $instance->save( $data, $content );
  182. $result = $instance->get_filtered( $data );
  183. }
  184. elseif ( 'get' == $callback ) {
  185. $result = (string) $instance->get( $data );
  186. if ( 'rich' == $data['type'] )
  187. $result = wpautop( $result );
  188. }
  189. $result = array( 'content' => $result );
  190. } catch ( Exception $e ) {
  191. $result = array( 'error' => $e->getMessage() );
  192. }
  193. return $result;
  194. }
  195. }
  196. /**
  197. * Registers a new editable field
  198. *
  199. * @param string $filter
  200. * @param array $args(
  201. * 'class' => string The name of the field handler class ( mandatory )
  202. * 'title' => string The user-friendly title ( optional )
  203. * 'type' => string: 'input' | 'textarea' | 'rich' | 'image' ( default: input )
  204. * 'priority' => integer ( default: 11 )
  205. * 'argc' => integer ( default: 1 )
  206. * )
  207. */
  208. function fee_register_field() {
  209. $args = func_get_args();
  210. return FEE_Core::register( $args );
  211. }