| 1 |
<?php |
| 2 |
/* |
| 3 |
Plugin Name: Edit Flow |
| 4 |
Plugin URI: http://www.copress.org/wiki/Edit_Flow_Project |
| 5 |
Description: Remixing the WordPress admin for better editorial workflow options. |
| 6 |
Author: Daniel Bachhuber, Mohammad Jangda, Andrew Spittle, et al. |
| 7 |
Version: 0.1.5 |
| 8 |
Author URI: http://www.copress.org/ |
| 9 |
|
| 10 |
Copyright 2009 CoPress, 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 |
## Change Log ## |
| 30 |
|
| 31 |
*2009-06-12 / 0.1.2* |
| 32 |
|
| 33 |
* Updated plugin license to GPL |
| 34 |
|
| 35 |
*/ |
| 36 |
|
| 37 |
// Include necessary files |
| 38 |
include_once('php/custom_status.php'); |
| 39 |
include_once('php/dashboard.php'); |
| 40 |
include_once('php/post.php'); |
| 41 |
|
| 42 |
// Define contants |
| 43 |
define(EDIT_FLOW_FILE_PATH, dirname(__FILE__).'/'.basename(__FILE__)); |
| 44 |
define(EDIT_FLOW_URL, plugins_url(plugin_basename(dirname(__FILE__)).'/')); |
| 45 |
define(EDIT_FLOW_SETTINGS_PAGE, 'options-general.php?page=edit_flow'); |
| 46 |
define(EDIT_FLOW_CUSTOM_STATUS_PAGE, 'admin.php?page=Edit-Flow-Project/php/custom_status.php'); |
| 47 |
|
| 48 |
// Core class |
| 49 |
class edit_flow { |
| 50 |
|
| 51 |
// Unique identified added as a prefix to all options |
| 52 |
var $options_group = 'edit_flow_'; |
| 53 |
// Initially stores default option values, but when load_options is run, it is populated with the options stored in the WP db |
| 54 |
var $options = array( |
| 55 |
'custom_statuses_enabled' => 1, |
| 56 |
'custom_status_default_status' => 'draft', |
| 57 |
'dashboard_widgets_enabled' => 1, |
| 58 |
'post_status_widget_enabled' => 1, |
| 59 |
); |
| 60 |
|
| 61 |
// Used to store the names for any custom tables used by the plugin |
| 62 |
var $tables = array(); |
| 63 |
|
| 64 |
// used to create an instance of the various classes |
| 65 |
var $custom_status = null; |
| 66 |
var $dashboard = null; |
| 67 |
var $post_status = null; |
| 68 |
|
| 69 |
|
| 70 |
/** |
| 71 |
* Constructor |
| 72 |
*/ |
| 73 |
function __construct() { |
| 74 |
global $wpdb; |
| 75 |
|
| 76 |
// Define custom tables used here |
| 77 |
// Sample array entry: 'table_name' => $wpdb->prefix.'table_name' |
| 78 |
$this->tables = array(); |
| 79 |
|
| 80 |
// Load plugin options |
| 81 |
$this->load_options(); |
| 82 |
|
| 83 |
// Create the new custom_status object |
| 84 |
$this->custom_status = new custom_status(); |
| 85 |
// Create a new edit_flow_dashboard object |
| 86 |
if($this->get_plugin_option('dashboard_widgets_enabled')) $this->dashboard = new edit_flow_dashboard(); |
| 87 |
|
| 88 |
|
| 89 |
// Create a new post_status object, if custom statuses enabled |
| 90 |
if($this->get_plugin_option('custom_statuses_enabled')==1) $this->post_status = new post_status(); |
| 91 |
|
| 92 |
|
| 93 |
} // END __construct() |
| 94 |
|
| 95 |
/** |
| 96 |
* Inititalizes the plugin |
| 97 |
*/ |
| 98 |
function init() { |
| 99 |
if(is_admin()) { |
| 100 |
//Add the necessary pages for the plugin |
| 101 |
add_action('admin_menu', array(&$this, 'add_menu_items')); |
| 102 |
} |
| 103 |
|
| 104 |
} // END: init() |
| 105 |
|
| 106 |
/** |
| 107 |
* Initialize the plugin for the admin |
| 108 |
*/ |
| 109 |
function admin_init() { |
| 110 |
// Register all plugin settings so that we can change them and such |
| 111 |
foreach($this->options as $option => $value) { |
| 112 |
register_setting($this->options_group, $this->get_plugin_option_fullname($option)); |
| 113 |
} |
| 114 |
} // END: admin_init() |
| 115 |
|
| 116 |
/** |
| 117 |
* This function is called when plugin is activated. |
| 118 |
*/ |
| 119 |
function activate_plugin ( ) { |
| 120 |
// Run function to generate db tables |
| 121 |
$this->build_db_tables(); |
| 122 |
|
| 123 |
// Do other fancy stuff! |
| 124 |
// Like load default values for Custom Status |
| 125 |
|
| 126 |
// Create default statuses |
| 127 |
$default_terms = array( array( 'term' => 'Draft', |
| 128 |
'args' => array( 'slug' => 'draft', |
| 129 |
'description' => 'Post is simply a draft', |
| 130 |
) |
| 131 |
), |
| 132 |
array( 'term' => 'Pending Review', |
| 133 |
'args' => array( 'slug' => 'pending', |
| 134 |
'description' => 'The post needs to be reviewed by an Editor', |
| 135 |
) |
| 136 |
), |
| 137 |
array( 'term' => 'Pitch', |
| 138 |
'args' => array( 'slug' => 'pitch', |
| 139 |
'description' => 'Post idea proposed', |
| 140 |
) |
| 141 |
), |
| 142 |
array( 'term' => 'Assigned', |
| 143 |
'args' => array( 'slug' => 'assigned', |
| 144 |
'description' => 'The post has been assigned to a writer' |
| 145 |
) |
| 146 |
), |
| 147 |
array( 'term' => 'Waiting for Feedback', |
| 148 |
'args' => array( 'slug' => 'waiting-for-feedback', |
| 149 |
'description' => 'The post has been sent to the editor, and is waiting on feedback' |
| 150 |
) |
| 151 |
) |
| 152 |
); |
| 153 |
// Okay, now add the default statuses to the db if they don't already exist |
| 154 |
foreach($default_terms as $term) { |
| 155 |
if(!is_term($term['term'])) $this->custom_status->add_custom_status( $term['term'], $term['args'] ); |
| 156 |
} |
| 157 |
|
| 158 |
|
| 159 |
} // END: activate plugin |
| 160 |
|
| 161 |
/** |
| 162 |
* Creates all necessary db tables for plugin, if they don't exist. |
| 163 |
* @return void |
| 164 |
*/ |
| 165 |
protected function build_db_tables() { |
| 166 |
global $wpdb; |
| 167 |
|
| 168 |
/* |
| 169 |
NOTE: Make sure to add table name to the $this->table array (in the __construct() function). We can then access it plugin-wide by: |
| 170 |
|
| 171 |
global $edit_flow; |
| 172 |
$edit_flow->tables['table_name'] |
| 173 |
|
| 174 |
WordPress wasn't letting me access the table via $wpdb->table_name, which is why I've set this up. |
| 175 |
*/ |
| 176 |
|
| 177 |
} // END: build_db_tables |
| 178 |
|
| 179 |
|
| 180 |
/** |
| 181 |
* Loads options for the plugin. |
| 182 |
* If option doesn't exist in database, it is added |
| 183 |
* |
| 184 |
* Note: default values are stored in the $this->options array |
| 185 |
* Note: a prefix unique to the plugin is appended to all options. Prefix is stored in $this->options_group |
| 186 |
*/ |
| 187 |
protected function load_options ( ) { |
| 188 |
|
| 189 |
$new_options = array(); |
| 190 |
|
| 191 |
foreach($this->options as $option => $value) { |
| 192 |
$name = $this->get_plugin_option_fullname($option); |
| 193 |
$return = get_option($name); |
| 194 |
if($return === false) { |
| 195 |
add_option($name, $value); |
| 196 |
$new_array[$option] = $value; |
| 197 |
} else { |
| 198 |
$new_array[$option] = $return; |
| 199 |
} |
| 200 |
} |
| 201 |
$this->options = $new_array; |
| 202 |
|
| 203 |
} // END: load_options |
| 204 |
|
| 205 |
|
| 206 |
/** |
| 207 |
* Returns option for the plugin specified by $name, e.g. custom_stati_enabled |
| 208 |
* |
| 209 |
* Note: The plugin option prefix does not need to be included in $name |
| 210 |
* |
| 211 |
* @param string name of the option |
| 212 |
* @return option|null if not found |
| 213 |
* |
| 214 |
*/ |
| 215 |
function get_plugin_option ( $name ) { |
| 216 |
if(is_array($this->options) && $option = $this->options[$name]) |
| 217 |
return $option; |
| 218 |
else |
| 219 |
return null; |
| 220 |
} // END: get_option |
| 221 |
|
| 222 |
// Utility function: appends the option prefix and returns the full name of the option as it is stored in the wp_options db |
| 223 |
protected function get_plugin_option_fullname ( $name ) { |
| 224 |
return $this->options_group . $name; |
| 225 |
} |
| 226 |
|
| 227 |
/** |
| 228 |
* Adds menu items for the plugin |
| 229 |
*/ |
| 230 |
function add_menu_items ( ) { |
| 231 |
// Add Top-level Admin Menu |
| 232 |
add_menu_page('Edit Flow', 'Edit Flow', 8, __FILE__, array(&$this, 'toplevel_page')); |
| 233 |
|
| 234 |
// Add sub-menu page for Custom statuses |
| 235 |
add_submenu_page(__FILE__, 'Custom Status', 'Custom Status', 8, 'Edit-Flow-Project/php/custom_status.php', array(&$this->custom_status,'admin_page')); |
| 236 |
|
| 237 |
// Add Options page |
| 238 |
add_options_page('Edit Flow Options', 'Edit Flow', 8, 'edit_flow', array(&$this, 'options_page')); |
| 239 |
} // END: add_menu_items() |
| 240 |
|
| 241 |
/** |
| 242 |
* Add Top-level Admin Menu |
| 243 |
* This should be exported into a separate file (?) |
| 244 |
*/ |
| 245 |
function toplevel_page() { |
| 246 |
?> |
| 247 |
<div class="wrap"> |
| 248 |
<h2>Edit Flow</h2> |
| 249 |
|
| 250 |
<div class="updated"> |
| 251 |
<p>The overall goal of this plugin is to improve WordPress' admin for a multi-user newsroom's editorial workflow.</p> |
| 252 |
|
| 253 |
<p>Through discussions with existing newsrooms that use WordPress as their CMS of choice, we have identified the following weak points within the WordPress Administration interface in the context of a multi-user environment:</p> |
| 254 |
|
| 255 |
<ul> |
| 256 |
<li>-- the editorial workflow is limited and does not scale well where numerous individuals interact with a single Post or where more complex editing workflows are required; |
| 257 |
</li> |
| 258 |
<li>-- the editorial workflow is not conducive to planning of future content (while the Draft feature does facilitate this to some extent, the existing feature set does not scale in scenarios where different users are responsible for different components of a post, or different steps within the workflow. |
| 259 |
</li> |
| 260 |
<li>-- the ability for users to communicate within the Administration interface is limited, both the planning of future Posts/assignments and during the editing process. |
| 261 |
</li> |
| 262 |
</ul> |
| 263 |
</div> |
| 264 |
|
| 265 |
<p>More about <a href="http://www.copress.org/wiki/Edit_Flow_Project">Edit Flow</a></p> |
| 266 |
<p>More about <a href="http://copress.org">CoPress</a></p> |
| 267 |
|
| 268 |
|
| 269 |
</div> |
| 270 |
<?php |
| 271 |
} // END: toplevel_menu() |
| 272 |
|
| 273 |
/** |
| 274 |
* Add options page |
| 275 |
* This should be exported into a separate file |
| 276 |
*/ |
| 277 |
function options_page ( ) { |
| 278 |
|
| 279 |
?> |
| 280 |
<div class="wrap"> |
| 281 |
<h2>Edit Flow</h2> |
| 282 |
|
| 283 |
<form method="post" action="options.php"> |
| 284 |
<?php settings_fields($this->options_group); ?> |
| 285 |
|
| 286 |
<table class="form-table"> |
| 287 |
<tr valign="top"> |
| 288 |
<th scope="row">Custom Statuses</th> |
| 289 |
<td> |
| 290 |
<p> |
| 291 |
<label for="custom_statuses_enabled"> |
| 292 |
<input type="checkbox" name="<?php echo $this->get_plugin_option_fullname('custom_statuses_enabled') ?>" value="1" <?php echo ($this->get_plugin_option('custom_statuses_enabled')) ? 'checked="checked"' : ''; ?> id="custom_statuses_enabled" /> <?php _e('Enable Custom Statuses for Posts') ?> |
| 293 |
</label> <br /> |
| 294 |
<span class="description"><?php _e('Enabling this option allow you to assign custom statuses to your Posts. Custom Statuses can be created and managed here: <a href="'.EDIT_FLOW_CUSTOM_STATUS_PAGE.'">Edit Flow > Custom Status</a>') ?></span> |
| 295 |
</p> |
| 296 |
<p> |
| 297 |
<label for="custom_status_default_status"> |
| 298 |
<?php _e('Default Status for new posts') ?> |
| 299 |
</label> |
| 300 |
<select name="<?php echo $this->get_plugin_option_fullname('custom_status_default_status') ?>" id="custom_status_default_status"> |
| 301 |
|
| 302 |
<?php $statuses = $this->custom_status->get_custom_statuses() ?> |
| 303 |
<?php foreach($statuses as $status) : ?> |
| 304 |
|
| 305 |
<?php $selected = ($this->get_plugin_option('custom_status_default_status')==$status->slug) ? 'selected="selected"' : ''; ?> |
| 306 |
<option value="<?php echo $status->slug ?>" <?php echo $selected ?>> |
| 307 |
<?php echo $status->name; ?> |
| 308 |
</option> |
| 309 |
|
| 310 |
<?php endforeach; ?> |
| 311 |
</select> |
| 312 |
<br /> |
| 313 |
<span class="description"><?php _e('The default status that is applied when a new status is created.') ?></span> |
| 314 |
</p> |
| 315 |
|
| 316 |
|
| 317 |
</td> |
| 318 |
</tr> |
| 319 |
|
| 320 |
<tr valign="top"> |
| 321 |
<th scope="row">Dashboard</th> |
| 322 |
<td> |
| 323 |
<p> |
| 324 |
<label for="dashboard_widgets_enabled"> |
| 325 |
<input type="checkbox" name="<?php echo $this->get_plugin_option_fullname('dashboard_widgets_enabled') ?>" value="1" <?php echo ($this->get_plugin_option('dashboard_widgets_enabled')) ? 'checked="checked"' : ''; ?> id="dashboard_widgets_enabled" /> <?php _e('Enable Dashboard Widgets') ?> |
| 326 |
</label> <br /> |
| 327 |
<span class="description"><?php _e('Enables a special set of dashboard widgets for use with Edit Flow. Enable this setting to view the list of available widgets.') ?></span> |
| 328 |
</p> |
| 329 |
<?php if($this->get_plugin_option('dashboard_widgets_enabled')) : ?> |
| 330 |
<p> |
| 331 |
<label for="post_status_widget_enabled"> |
| 332 |
<input type="checkbox" name="<?php echo $this->get_plugin_option_fullname('post_status_widget_enabled') ?>" value="1" <?php echo ($this->get_plugin_option('post_status_widget_enabled')) ? 'checked="checked"' : ''; ?> id="post_status_widget_enabled" /> <?php _e('Enable Post Status Dashboard Widgets') ?> |
| 333 |
</label> <br /> |
| 334 |
<span class="description"><?php _e('Gives you an at-a-glance view of the current status of your unpublished content.') ?></span> |
| 335 |
</p> |
| 336 |
<?php endif; ?> |
| 337 |
|
| 338 |
</td> |
| 339 |
</tr> |
| 340 |
|
| 341 |
</table> |
| 342 |
|
| 343 |
<p class="submit"> |
| 344 |
<input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" /> |
| 345 |
</p> |
| 346 |
</form> |
| 347 |
</div> |
| 348 |
<?php |
| 349 |
} // END: options_page() |
| 350 |
|
| 351 |
|
| 352 |
} // END: class edit_flow |
| 353 |
|
| 354 |
// Create new instance of the edit_flow object |
| 355 |
global $edit_flow; |
| 356 |
$edit_flow = new edit_flow(); |
| 357 |
|
| 358 |
// Core hooks to initialize the plugin |
| 359 |
add_action('init', array(&$edit_flow,'init')); |
| 360 |
add_action('admin_init', array(&$edit_flow,'admin_init')); |
| 361 |
|
| 362 |
// Hook to perform action when plugin activated |
| 363 |
register_activation_hook( EDIT_FLOW_FILE_PATH, array(&$edit_flow, 'activate_plugin')); |
| 364 |
|
| 365 |
?> |