PageRenderTime 34ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/edit_flow.php

https://gitlab.com/Blueprint-Marketing/Edit-Flow
PHP | 348 lines | 185 code | 53 blank | 110 comment | 33 complexity | 73d52c2f51aeecc4dbbce34a7a85f70a MD5 | raw file
  1. <?php
  2. /*
  3. Plugin Name: Edit Flow
  4. Plugin URI: http://editflow.org/
  5. Description: Remixing the WordPress admin for better editorial workflow options.
  6. Author: Daniel Bachhuber, Scott Bressler, Mohammad Jangda, Automattic, and others
  7. Version: 0.8.1-alpha
  8. Author URI: http://editflow.org/
  9. Copyright 2009-2013 Mohammad Jangda, Daniel Bachhuber, et al.
  10. GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
  11. This program is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; either version 2 of the License, or
  14. (at your option) any later version.
  15. This program is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. GNU General Public License for more details.
  19. You should have received a copy of the GNU General Public License
  20. along with this program; if not, write to the Free Software
  21. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. // Define contants
  24. define( 'EDIT_FLOW_VERSION' , '0.8.1-alpha' );
  25. define( 'EDIT_FLOW_ROOT' , dirname(__FILE__) );
  26. define( 'EDIT_FLOW_FILE_PATH' , EDIT_FLOW_ROOT . '/' . basename(__FILE__) );
  27. define( 'EDIT_FLOW_URL' , plugins_url( '/', __FILE__ ) );
  28. define( 'EDIT_FLOW_SETTINGS_PAGE' , add_query_arg( 'page', 'ef-settings', get_admin_url( null, 'admin.php' ) ) );
  29. // Core class
  30. class edit_flow {
  31. // Unique identified added as a prefix to all options
  32. var $options_group = 'edit_flow_';
  33. var $options_group_name = 'edit_flow_options';
  34. /**
  35. * @var EditFlow The one true EditFlow
  36. */
  37. private static $instance;
  38. /**
  39. * Main EditFlow Instance
  40. *
  41. * Insures that only one instance of EditFlow exists in memory at any one
  42. * time. Also prevents needing to define globals all over the place.
  43. *
  44. * @since EditFlow 0.7.4
  45. * @staticvar array $instance
  46. * @uses EditFlow::setup_globals() Setup the globals needed
  47. * @uses EditFlow::includes() Include the required files
  48. * @uses EditFlow::setup_actions() Setup the hooks and actions
  49. * @see EditFlow()
  50. * @return The one true EditFlow
  51. */
  52. public static function instance() {
  53. if ( ! isset( self::$instance ) ) {
  54. self::$instance = new edit_flow;
  55. self::$instance->setup_globals();
  56. self::$instance->setup_actions();
  57. // Backwards compat for when we promoted use of the $edit_flow global
  58. global $edit_flow;
  59. $edit_flow = self::$instance;
  60. }
  61. return self::$instance;
  62. }
  63. private function __construct() {
  64. /** Do nothing **/
  65. }
  66. private function setup_globals() {
  67. $this->modules = new stdClass();
  68. }
  69. /**
  70. * Include the common resources to Edit Flow and dynamically load the modules
  71. */
  72. private function load_modules() {
  73. // We use the WP_List_Table API for some of the table gen
  74. if ( !class_exists( 'WP_List_Table' ) )
  75. require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
  76. // Edit Flow base module
  77. require_once( EDIT_FLOW_ROOT . '/common/php/class-module.php' );
  78. // Scan the modules directory and include any modules that exist there
  79. $module_dirs = scandir( EDIT_FLOW_ROOT . '/modules/' );
  80. $class_names = array();
  81. foreach( $module_dirs as $module_dir ) {
  82. if ( file_exists( EDIT_FLOW_ROOT . "/modules/{$module_dir}/$module_dir.php" ) ) {
  83. include_once( EDIT_FLOW_ROOT . "/modules/{$module_dir}/$module_dir.php" );
  84. // Prepare the class name because it should be standardized
  85. $tmp = explode( '-', $module_dir );
  86. $class_name = '';
  87. $slug_name = '';
  88. foreach( $tmp as $word ) {
  89. $class_name .= ucfirst( $word ) . '_';
  90. $slug_name .= $word . '_';
  91. }
  92. $slug_name = rtrim( $slug_name, '_' );
  93. $class_names[$slug_name] = 'EF_' . rtrim( $class_name, '_' );
  94. }
  95. }
  96. // Instantiate EF_Module as $helpers for back compat and so we can
  97. // use it in this class
  98. $this->helpers = new EF_Module();
  99. // Other utils
  100. require_once( EDIT_FLOW_ROOT . '/common/php/util.php' );
  101. // Instantiate all of our classes onto the Edit Flow object
  102. // but make sure they exist too
  103. foreach( $class_names as $slug => $class_name ) {
  104. if ( class_exists( $class_name ) ) {
  105. $this->$slug = new $class_name();
  106. }
  107. }
  108. // Supplementary plugins can hook into this, include their own modules
  109. // and add them to the $edit_flow object
  110. do_action( 'ef_modules_loaded' );
  111. }
  112. /**
  113. * Setup the default hooks and actions
  114. *
  115. * @since EditFlow 0.7.4
  116. * @access private
  117. * @uses add_action() To add various actions
  118. */
  119. private function setup_actions() {
  120. add_action( 'init', array( $this, 'action_init' ) );
  121. add_action( 'init', array( $this, 'action_init_after' ), 1000 );
  122. add_action( 'admin_init', array( $this, 'action_admin_init' ) );
  123. do_action_ref_array( 'editflow_after_setup_actions', array( &$this ) );
  124. }
  125. /**
  126. * Inititalizes the Edit Flows!
  127. * Loads options for each registered module and then initializes it if it's active
  128. */
  129. function action_init() {
  130. load_plugin_textdomain( 'edit-flow', null, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
  131. $this->load_modules();
  132. // Load all of the module options
  133. $this->load_module_options();
  134. // Load all of the modules that are enabled.
  135. // Modules won't have an options value if they aren't enabled
  136. foreach ( $this->modules as $mod_name => $mod_data )
  137. if ( isset( $mod_data->options->enabled ) && $mod_data->options->enabled == 'on' )
  138. $this->$mod_name->init();
  139. do_action( 'ef_init' );
  140. }
  141. /**
  142. * Initialize the plugin for the admin
  143. */
  144. function action_admin_init() {
  145. // Upgrade if need be but don't run the upgrade if the plugin has never been used
  146. $previous_version = get_option( $this->options_group . 'version' );
  147. if ( $previous_version && version_compare( $previous_version, EDIT_FLOW_VERSION, '<' ) ) {
  148. foreach ( $this->modules as $mod_name => $mod_data ) {
  149. if ( method_exists( $this->$mod_name, 'upgrade' ) )
  150. $this->$mod_name->upgrade( $previous_version );
  151. }
  152. update_option( $this->options_group . 'version', EDIT_FLOW_VERSION );
  153. } else if ( !$previous_version ) {
  154. update_option( $this->options_group . 'version', EDIT_FLOW_VERSION );
  155. }
  156. // For each module that's been loaded, auto-load data if it's never been run before
  157. foreach ( $this->modules as $mod_name => $mod_data ) {
  158. // If the module has never been loaded before, run the install method if there is one
  159. if ( !isset( $mod_data->options->loaded_once ) || !$mod_data->options->loaded_once ) {
  160. if ( method_exists( $this->$mod_name, 'install' ) )
  161. $this->$mod_name->install();
  162. $this->update_module_option( $mod_name, 'loaded_once', true );
  163. }
  164. }
  165. $this->register_scripts_and_styles();
  166. }
  167. /**
  168. * Register a new module with Edit Flow
  169. */
  170. public function register_module( $name, $args = array() ) {
  171. // A title and name is required for every module
  172. if ( !isset( $args['title'], $name ) )
  173. return false;
  174. $defaults = array(
  175. 'title' => '',
  176. 'short_description' => '',
  177. 'extended_description' => '',
  178. 'img_url' => false,
  179. 'slug' => '',
  180. 'post_type_support' => '',
  181. 'default_options' => array(),
  182. 'options' => false,
  183. 'configure_page_cb' => false,
  184. 'configure_link_text' => __( 'Configure', 'edit-flow' ),
  185. // These messages are applied to modules and can be overridden if custom messages are needed
  186. 'messages' => array(
  187. 'settings-updated' => __( 'Settings updated.', 'edit-flow' ),
  188. 'form-error' => __( 'Please correct your form errors below and try again.', 'edit-flow' ),
  189. 'nonce-failed' => __( 'Cheatin&#8217; uh?', 'edit-flow' ),
  190. 'invalid-permissions' => __( 'You do not have necessary permissions to complete this action.', 'edit-flow' ),
  191. 'missing-post' => __( 'Post does not exist', 'edit-flow' ),
  192. ),
  193. 'autoload' => false, // autoloading a module will remove the ability to enable or disable it
  194. );
  195. if ( isset( $args['messages'] ) )
  196. $args['messages'] = array_merge( (array)$args['messages'], $defaults['messages'] );
  197. $args = array_merge( $defaults, $args );
  198. $args['name'] = $name;
  199. $args['options_group_name'] = $this->options_group . $name . '_options';
  200. if ( !isset( $args['settings_slug'] ) )
  201. $args['settings_slug'] = 'ef-' . $args['slug'] . '-settings';
  202. if ( empty( $args['post_type_support'] ) )
  203. $args['post_type_support'] = 'ef_' . $name;
  204. // If there's a Help Screen registered for the module, make sure we
  205. // auto-load it
  206. if ( !empty( $args['settings_help_tab'] ) )
  207. add_action( 'load-edit-flow_page_' . $args['settings_slug'], array( &$this->$name, 'action_settings_help_menu' ) );
  208. $this->modules->$name = (object) $args;
  209. do_action( 'ef_module_registered', $name );
  210. return $this->modules->$name;
  211. }
  212. /**
  213. * Load all of the module options from the database
  214. * If a given option isn't yet set, then set it to the module's default (upgrades, etc.)
  215. */
  216. function load_module_options() {
  217. foreach ( $this->modules as $mod_name => $mod_data ) {
  218. $this->modules->$mod_name->options = get_option( $this->options_group . $mod_name . '_options', new stdClass );
  219. foreach ( $mod_data->default_options as $default_key => $default_value ) {
  220. if ( !isset( $this->modules->$mod_name->options->$default_key ) )
  221. $this->modules->$mod_name->options->$default_key = $default_value;
  222. }
  223. $this->$mod_name->module = $this->modules->$mod_name;
  224. }
  225. do_action( 'ef_module_options_loaded' );
  226. }
  227. /**
  228. * Load the post type options again so we give add_post_type_support() a chance to work
  229. *
  230. * @see http://dev.editflow.org/2011/11/17/edit-flow-v0-7-alpha2-notes/#comment-232
  231. */
  232. function action_init_after() {
  233. foreach ( $this->modules as $mod_name => $mod_data ) {
  234. if ( isset( $this->modules->$mod_name->options->post_types ) )
  235. $this->modules->$mod_name->options->post_types = $this->helpers->clean_post_type_options( $this->modules->$mod_name->options->post_types, $mod_data->post_type_support );
  236. $this->$mod_name->module = $this->modules->$mod_name;
  237. }
  238. }
  239. /**
  240. * Get a module by one of its descriptive values
  241. */
  242. function get_module_by( $key, $value ) {
  243. $module = false;
  244. foreach ( $this->modules as $mod_name => $mod_data ) {
  245. if ( $key == 'name' && $value == $mod_name ) {
  246. $module = $this->modules->$mod_name;
  247. } else {
  248. foreach( $mod_data as $mod_data_key => $mod_data_value ) {
  249. if ( $mod_data_key == $key && $mod_data_value == $value )
  250. $module = $this->modules->$mod_name;
  251. }
  252. }
  253. }
  254. return $module;
  255. }
  256. /**
  257. * Update the $edit_flow object with new value and save to the database
  258. */
  259. function update_module_option( $mod_name, $key, $value ) {
  260. $this->modules->$mod_name->options->$key = $value;
  261. $this->$mod_name->module = $this->modules->$mod_name;
  262. return update_option( $this->options_group . $mod_name . '_options', $this->modules->$mod_name->options );
  263. }
  264. function update_all_module_options( $mod_name, $new_options ) {
  265. if ( is_array( $new_options ) )
  266. $new_options = (object)$new_options;
  267. $this->modules->$mod_name->options = $new_options;
  268. $this->$mod_name->module = $this->modules->$mod_name;
  269. return update_option( $this->options_group . $mod_name . '_options', $this->modules->$mod_name->options );
  270. }
  271. /**
  272. * Registers commonly used scripts + styles for easy enqueueing
  273. */
  274. function register_scripts_and_styles() {
  275. wp_enqueue_style( 'ef-admin-css', EDIT_FLOW_URL . 'common/css/edit-flow-admin.css', false, EDIT_FLOW_VERSION, 'all' );
  276. wp_register_script( 'jquery-listfilterizer', EDIT_FLOW_URL . 'common/js/jquery.listfilterizer.js', array( 'jquery' ), EDIT_FLOW_VERSION, true );
  277. wp_register_style( 'jquery-listfilterizer', EDIT_FLOW_URL . 'common/css/jquery.listfilterizer.css', false, EDIT_FLOW_VERSION, 'all' );
  278. wp_register_script( 'jquery-quicksearch', EDIT_FLOW_URL . 'common/js/jquery.quicksearch.js', array( 'jquery' ), EDIT_FLOW_VERSION, true );
  279. // @compat 3.3
  280. // Register jQuery datepicker plugin if it doesn't already exist. Datepicker plugin was added in WordPress 3.3
  281. global $wp_scripts;
  282. if ( !isset( $wp_scripts->registered['jquery-ui-datepicker'] ) )
  283. wp_register_script( 'jquery-ui-datepicker', EDIT_FLOW_URL . 'common/js/jquery.ui.datepicker.min.js', array( 'jquery', 'jquery-ui-core'), '1.8.16', true );
  284. }
  285. }
  286. function EditFlow() {
  287. return edit_flow::instance();
  288. }
  289. add_action( 'plugins_loaded', 'EditFlow' );