PluginProbe
Edit Flow / 0.7.4
Edit Flow v0.7.4
0.11.1 0.11.0 0.7.2 0.7.3 0.7.4 0.7.5 0.7.6 0.8 0.8.1 0.8.2 0.9 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 trunk 0.1.5 0.10.0 0.10.1 0.10.2 All 44 releases
edit-flow / edit_flow.php

edit_flow.php in Edit Flow 0.7.4, at edit_flow.php

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