Changeset 1047420
- Timestamp:
- 12/17/2014 07:23:05 PM (11 years ago)
- Location:
- content-scheduler/trunk
- Files:
-
- 1 added
- 2 edited
-
content-scheduler-settings.php (added)
-
content-scheduler.php (modified) (12 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
content-scheduler/trunk/content-scheduler.php
r706934 r1047420 4 4 Plugin URI: http://paulekaiser.com/wordpress-plugins/content-scheduler/ 5 5 Description: Set Posts and Pages to automatically expire. Upon expiration, delete, change categories, status, or unstick posts. Also notify admin and author of expiration. 6 Version: 1.0.06 Version: 2.0.0 7 7 Author: Paul Kaiser 8 8 Author URI: http://paulekaiser.com 9 9 License: GPL2 10 10 */ 11 /* Copyright 201 1Paul Kaiser (email : paul.kaiser@gmail.com)11 /* Copyright 2014 Paul Kaiser (email : paul.kaiser@gmail.com) 12 12 This program is free software; you can redistribute it and/or modify 13 13 it under the terms of the GNU General Public License, version 2, as … … 22 22 */ 23 23 // avoid direct calls to this file, because now WP core and framework have been used 24 if ( !function_exists(' add_action') ) {24 if ( !function_exists('is_admin') ) { 25 25 header('Status: 403 Forbidden'); 26 26 header('HTTP/1.1 403 Forbidden'); 27 27 exit(); 28 28 } 29 30 31 32 33 29 34 // assign some constants if they didn't already get taken care of 35 define( 'PEK_CONTENT_SCHEDULER_VERSION', '2.0.0' ); 36 define( 'PEK_CONTENT_SCHEDULER_DIR', plugin_dir_path( __FILE__ ) ); 37 define( 'PEK_CONTENT_SCHEDULER_URL', plugin_dir_url( __FILE__ ) ); 30 38 if ( ! defined( 'WP_CONTENT_URL' ) ) 31 39 define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' ); … … 36 44 if ( ! defined( 'WP_PLUGIN_DIR' ) ) 37 45 define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' ); 46 47 48 49 50 38 51 // Define our plugin's wrapper class 39 if ( !class_exists( "ContentScheduler" ) ) 40 { 41 class ContentScheduler 42 { 43 function ContentScheduler() 44 { 45 // Constructor 46 register_activation_hook( __FILE__, array($this, 'run_on_activate') ); 47 register_deactivation_hook( __FILE__, array($this, 'run_on_deactivate') ); 48 // ============================================================= 49 // Actions 50 // ============================================================= 52 if ( !class_exists( "ContentScheduler" ) ) { 53 class ContentScheduler { 54 var $settings, $options_page; 55 56 function __construct() { 57 if ( is_admin() ) { 58 // Load settings page 59 // but do we really need this, unless we are in admin?? 60 if ( !class_exists( "Content_Scheduler_Settings" ) ) { 61 require( PEK_CONTENT_SCHEDULER_DIR . 'content-scheduler-settings.php' ); 62 } 63 $this->settings = new Content_Scheduler_Settings(); 64 } 65 51 66 add_action( 'init', array($this, 'content_scheduler_init') ); 52 // Adding Admin inits 53 add_action('admin_init', array($this, 'init_admin')); 67 54 68 // Add any JavaScript and CSS needed just for my plugin 69 // for the post editing screen 55 70 add_action( "admin_print_scripts-post-new.php", array($this, 'cs_edit_scripts') ); 56 71 add_action( "admin_print_scripts-post.php", array($this, 'cs_edit_scripts') ); 57 72 add_action( "admin_print_styles-post-new.php", array($this, 'cs_edit_styles') ); 58 73 add_action( "admin_print_styles-post.php", array($this, 'cs_edit_styles') ); 59 // adds our plugin options page 60 add_action('admin_menu', array($this, 'ContentScheduler_addoptions_page_fn')); 74 61 75 // add a cron action for expiration check 62 76 // I think this is still valid, even after 3.4 changes 77 // TODO Check on this 78 // for debug 79 error_log( __FILE__ . " We need to check for network site and then register cron action appropriately." ); 80 // for now assume it is not a multisite 81 add_action ('content_scheduler', array( $this, 'answer_expiration_event') ); 82 83 /* 63 84 if ( $this->is_network_site() ) 64 85 { … … 69 90 add_action ('content_scheduler', array( $this, 'answer_expiration_event') ); 70 91 } 71 // ========== 92 */ 93 72 94 // Adding Custom boxes (Meta boxes) to Write panels (for Post, Page, and Custom Post Types) 73 95 add_action('add_meta_boxes', array($this, 'ContentScheduler_add_custom_box_fn')); 74 // Do something with the data entered in the Write panels fields75 96 add_action('save_post', array($this, 'ContentScheduler_save_postdata_fn')); 76 // ==========77 97 // Add column to Post / Page lists 78 98 add_action ( 'manage_posts_custom_column', array( $this, 'cs_show_expdate' ) ); 79 99 add_action ( 'manage_pages_custom_column', array( $this, 'cs_show_expdate' ) ); 80 // ============================================================= 100 81 101 // Shortcodes 82 // =============================================================83 102 add_shortcode('cs_expiration', array( $this, 'handle_shortcode' ) ); 84 // ============================================================= 103 85 104 // Filters 86 // =============================================================87 105 add_filter('cron_schedules', array( $this, 'add_cs_cron_fn' ) ); 106 88 107 // Showing custom columns in list views 89 108 add_filter ('manage_posts_columns', array( $this, 'cs_add_expdate_column' ) ); 90 109 add_filter ('manage_pages_columns', array( $this, 'cs_add_expdate_column' ) ); 110 111 register_activation_hook( __FILE__, array($this, 'run_on_activate') ); 112 register_deactivation_hook( __FILE__, array($this, 'run_on_deactivate') ); 91 113 } // end ContentScheduler Constructor 92 // ============================================================= 93 // == Administration Init Stuff 94 // ============================================================= 95 function init_admin() 96 { 97 // register_setting 98 // add_settings_section 99 // add_settings_field 100 // form field drawing callback functions 101 include "includes/init-admin.php"; 102 } // end init_admin() 103 function content_scheduler_init() 104 { 105 $plugin_dir = basename(dirname(__FILE__)) . '/lang'; 106 load_plugin_textdomain( 'contentscheduler', null, $plugin_dir ); 107 } 108 // ======================================================================== 109 // == Options Field Drawing Functions for add_settings 110 // ======================================================================== 111 // Determine expiration status: are we doing it, or not? 112 // exp-status 113 function draw_set_expstatus_fn() 114 { 115 // get this plugin's options from the database 116 $options = get_option('ContentScheduler_Options'); 117 // make array of radio button items 118 $items = array( 119 array('0', __("Hold", 'contentscheduler'), __("Do nothing upon expiration.", 'contentscheduler') ), 120 array('2', __("Delete", 'contentscheduler'), __("Move to trash upon expiration.", 'contentscheduler') ), 121 array('1', __("Apply changes", 'contentscheduler'), __("Apply the changes below upon expiration.", 'contentscheduler') ) 122 ); 123 // Step through and spit out each item as radio button 124 foreach( $items as $item ) 125 { 126 $checked = ($options['exp-status'] == $item[0] ) ? ' checked="checked" ' : ''; 127 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[exp-status]' type='radio' /> $item[1] — $item[2]</label><br />"; 128 } // end foreach 129 } // end draw_set_expstatus_fn() 130 // 12/30/2010 3:03:11 PM -pk 131 // Get the number of minutes they want wp-cron to wait between expiration checks. 132 function draw_set_expperiod_fn() 133 { 134 // get this plugin's options from the database 135 // This should have a default value of '1' 136 $options = get_option('ContentScheduler_Options'); 137 $input_field = "<input id='exp-period' name='ContentScheduler_Options[exp-period]' size='10' type='text' value='{$options['exp-period']}' />"; 138 printf( __("Wait %s minutes between expiration checks.", 'contentscheduler'), $input_field); 139 echo "<br />\n"; 140 } // end draw_set_expperiod_fn() 141 // 4/28/2011 3:47:22 PM -pk 142 // Get default expiration time. 143 // This will be added to the publish time and used for expiration, if "DEFAULT" (case insensitive) is used in the date field 144 function draw_set_expdefault_fn() 145 { 146 $options = get_option('ContentScheduler_Options'); 147 // This is stored as a string 148 // does update options or whatever... does it serialize and unserialize? I'm guessing not. 149 if( !isset( $options['exp-default'] ) ) 150 { 151 // no default is in the database for some reason, so let's call it empty and move on 152 $default_hours = '0'; 153 $default_days = '0'; 154 $default_weeks = '0'; 155 } 156 else 157 { 158 // get the saved default and split it up 159 $default_expiration_array = $options['exp-default']; 160 $default_hours = $default_expiration_array['def-hours']; 161 $default_days = $default_expiration_array['def-days']; 162 $default_weeks = $default_expiration_array['def-weeks']; 163 } 164 // Spit it all out 165 _e( 'For default expirations, add the following amount of time to publication time.', 'contentscheduler' ); 166 echo "<br />\n"; 167 echo "<table>\n"; 168 echo "<thead>\n<tr>\n"; 169 echo "<th scope='col'>Hours:</th><th scope='col'>Days:</th><th scope='col'>Weeks:</th>\n"; 170 echo "</thead>\n</tr>\n"; 171 echo "<tr>\n"; 172 echo "<td><input id='def-hours' name='ContentScheduler_Options[def-hours] size='4' type='text' value='$default_hours' /></td>\n"; 173 echo "<td><input id='def-days' name='ContentScheduler_Options[def-days] size='4' type='text' value='$default_days' /></td>\n"; 174 echo "<td><input id='def-weeks' name='ContentScheduler_Options[def-weeks] size='4' type='text' value='$default_weeks' /></td>\n"; 175 echo "</tr>\n</table>\n"; 176 } // end draw_set_expdefault_fn() 177 // How do we change "Status?" 178 // chg-status 179 function draw_set_chgstatus_fn() 180 { 181 // get this plugin's options from the database 182 $options = get_option('ContentScheduler_Options'); 183 // make array of radio button items 184 $items = array( 185 array('0', __("No Change", 'contentscheduler'), __("Do not change status.", 'contentscheduler') ), 186 array('1', __("Pending", 'contentscheduler'), __("Change status to Pending.", 'contentscheduler') ), 187 array('2', __("Draft", 'contentscheduler'), __("Change status to Draft.", 'contentscheduler') ), 188 array('3', __("Private", 'contentscheduler'), __("Change visibility to Private.", 'contentscheduler') ) 189 ); 190 // Step through and spit out each item as radio button 191 foreach( $items as $item ) 192 { 193 $checked = ($options['chg-status'] == $item[0] ) ? ' checked="checked" ' : ''; 194 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[chg-status]' type='radio' /> $item[1] — $item[2]</label><br />"; 195 } // end foreach 196 } // end draw_set_chgstatus_fn() 197 // How do we change "Stickiness" (Stick post to home page) 198 // chg-sticky 199 function draw_set_chgsticky_fn() 200 { 201 // get this plugin's options from the database 202 $options = get_option('ContentScheduler_Options'); 203 // make array of radio button items 204 $items = array( 205 array('0', __("No Change", 'contentscheduler'), __("Do not unstick posts.", 'contentscheduler')), 206 array('1', __("Unstick", 'contentscheduler'), __("Unstick posts.", 'contentscheduler')) 207 ); 208 // Step through and spit out each item as radio button 209 foreach( $items as $item ) 210 { 211 $checked = ($options['chg-sticky'] == $item[0] ) ? ' checked="checked" ' : ''; 212 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[chg-sticky]' type='radio' /> $item[1] — $item[2]</label><br />"; 213 } // end foreach 214 } // end draw_set_chgsticky_fn() 215 // How do we apply the category changes below? 216 // chg-cat-method 217 function draw_set_chgcatmethod_fn() 218 { 219 // get this plugin's options from the database 220 $options = get_option('ContentScheduler_Options'); 221 // make array of radio button items 222 $items = array( 223 array('0', __("No Change", 'contentscheduler'), __("Make no category changes.", 'contentscheduler')), 224 array('1', __("Add selected", 'contentscheduler'), __("Add posts to selected categories.", 'contentscheduler')), 225 array('2', __("Remove selected", 'contentscheduler'), __("Remove posts from selected categories.", 'contentscheduler')), 226 array('3', __("Match selected", 'contentscheduler'), __("Make posts exist only in selected categories.", 'contentscheduler')) 227 ); 228 // Step through and spit out each item as radio button 229 foreach( $items as $item ) 230 { 231 $checked = ($options['chg-cat-method'] == $item[0] ) ? ' checked="checked" ' : ''; 232 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[chg-cat-method]' type='radio' /> $item[1] — $item[2]</label><br />"; 233 } // end foreach 234 } // end draw_set_chgcatmethod_fn() 235 // What categories do we have available to change to? 236 // chg-categories 237 function draw_set_categories_fn() 238 { 239 // get this plugin's options from the database 240 $options = get_option('ContentScheduler_Options'); 241 // Draw a checkbox for each category 242 $categories = get_categories( array('hide_empty' => 0) ); 243 foreach ( $categories as $category ) 244 { 245 // See if we need a checkbox or not 246 if( !empty( $options['selcats'] ) ) 247 { 248 $checked = checked( 1, in_array( $category->term_id, $options['selcats'] ), false ); 249 } 250 else 251 { 252 $checked = ''; 253 } 254 $box = "<input name='ContentScheduler_Options[selcats][]' id='$category->category_nicename' type='checkbox' value='$category->term_id' class='' ".$checked." /> $category->name<br />\n"; 255 echo $box; 256 } // end foreach 257 } // end draw_set_categories_fn() 258 // What tags do we want added to content types that support tags? 259 // tags-to-add 260 // Be sure to check the content type for post_tags support before attempting to add 261 function draw_add_tags_fn() 262 { 263 // get this plugin's options from the database 264 // This should have a default value of '1' 265 $options = get_option('ContentScheduler_Options'); 266 /* translators: example list of tags */ 267 _e( "Comma-delimited list, e.g., '+news, -martial arts, +old content'" ); 268 echo "<br \>\n<input id='tags-to-add' name='ContentScheduler_Options[tags-to-add]' size='40' type='text' value='{$options['tags-to-add']}' /><br />"; 269 _e( "(leave blank to change no tags.)" ); 270 } // end draw_add_tags_fn() 271 // Notification Settings 272 // Notification on or off? 273 function draw_notify_on_fn() 274 { 275 // get this plugin's options from the database 276 $options = get_option('ContentScheduler_Options'); 277 // make array of radio button items 278 $items = array( 279 array('1', __("Notification on", 'contentscheduler'), __("Notify when expiration date is reached, even if 'Expiration status' is set to 'Hold.'", 'contentscheduler')), 280 array('0', __("Notification off", 'contentscheduler'), __("Do not notify.", 'contentscheduler')) 281 ); 282 // Step through and spit out each item as radio button 283 foreach( $items as $item ) 284 { 285 $checked = ($options['notify-on'] == $item[0] ) ? ' checked="checked" ' : ''; 286 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[notify-on]' type='radio' /> $item[1] — $item[2]</label><br />"; 287 } // end foreach 288 } // draw_notify_on_fn() 289 // Notify the site admin? 290 function draw_notify_admin_fn() 291 { 292 // get this plugin's options from the database 293 $options = get_option('ContentScheduler_Options'); 294 // make array of radio button items 295 $items = array( 296 array('1', __("Notify Admin", 'contentscheduler') ), 297 array('0', __("Do not notify Admin", 'contentscheduler') ) 298 ); 299 // Step through and spit out each item as radio button 300 foreach( $items as $item ) 301 { 302 $checked = ($options['notify-admin'] == $item[0] ) ? ' checked="checked" ' : ''; 303 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[notify-admin]' type='radio' /> $item[1]</label><br />"; 304 } // end foreach 305 } // end draw_notify_admin_fn() 306 // Notify the content author? 307 function draw_notify_author_fn() 308 { 309 // get this plugin's options from the database 310 $options = get_option('ContentScheduler_Options'); 311 // make array of radio button items 312 $items = array( 313 array('1', __("Notify Author", 'contentscheduler') ), 314 array('0', __("Do not notify Author", 'contentscheduler') ) 315 ); 316 // Step through and spit out each item as radio button 317 foreach( $items as $item ) 318 { 319 $checked = ($options['notify-author'] == $item[0] ) ? ' checked="checked" ' : ''; 320 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[notify-author]' type='radio' /> $item[1]</label><br />"; 321 } // end foreach 322 } // end draw_notify_author_fn 323 // Set minimum level to see Content Scheduler fields and shortcodes 324 // http://codex.wordpress.org/Roles_and_Capabilities#Roles 325 function draw_min_level_fn() 326 { 327 $options = get_option('ContentScheduler_Options'); 328 $items = array( 329 array("super_admin", 'level_10'), 330 array("administrator", 'level_8'), 331 array("editor", 'level_5'), 332 array("author", 'level_2'), 333 array("contributor", 'level_1'), 334 array("subscriber", 'level_0') 335 ); 336 echo "<select id='min-level' name='ContentScheduler_Options[min-level]'>\n"; 337 foreach( $items as $item ) 338 { 339 $checked = ($options['min-level'] == $item[1] ) ? ' selected="selected" ' : ' '; 340 echo "<option".$checked." value='$item[1]'>$item[0]</option>\n"; 341 } 342 echo "</select>\n"; 343 } // end draw_min_level_fn() 344 345 // Show expiration date in columnar lists? 346 function draw_show_columns_fn() 347 { 348 // get this plugin's options from the database 349 $options = get_option('ContentScheduler_Options'); 350 // make array of radio button items 351 $items = array( 352 array('1', __("Show expiration in columns", 'contentscheduler') ), 353 array('0', __("Do not show expiration in columns", 'contentscheduler') ) 354 ); 355 // Step through and spit out each item as radio button 356 foreach( $items as $item ) 357 { 358 $checked = ($options['show-columns'] == $item[0] ) ? ' checked="checked" ' : ''; 359 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[show-columns]' type='radio' /> $item[1]</label><br />"; 360 } // end foreach 361 } // end draw_show_columns_fn 362 // Use jQuery datepicker for the date field? 363 function draw_show_datepicker_fn() 364 { 365 // get this plugin's options from the database 366 $options = get_option('ContentScheduler_Options'); 367 // make array of radio button items 368 $items = array( 369 array('1', __("Use datepicker", 'contentscheduler') ), 370 array('0', __("Do not use datepicker", 'contentscheduler') ) 371 ); 372 // Step through and spit out each item as radio button 373 foreach( $items as $item ) 374 { 375 $checked = ($options['datepicker'] == $item[0] ) ? ' checked="checked" ' : ''; 376 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[datepicker]' type='radio' /> $item[1]</label><br />"; 377 } // end foreach 378 } // end draw_show_datepicker_fn 379 // Remove all CS data upon uninstall? 380 function draw_remove_data_fn() 381 { 382 // get this plugin's options from the database 383 $options = get_option('ContentScheduler_Options'); 384 // make array of radio button items 385 $items = array( 386 array('1', __("Remove all data", 'contentscheduler') ), 387 array('0', __("Do not remove data", 'contentscheduler') ) 388 ); 389 // Step through and spit out each item as radio button 390 foreach( $items as $item ) 391 { 392 $checked = ($options['remove-cs-data'] == $item[0] ) ? ' checked="checked" ' : ''; 393 echo "<label><input ".$checked." value='$item[0]' name='ContentScheduler_Options[remove-cs-data]' type='radio' /> $item[1]</label><br />"; 394 } // end foreach 395 } // end draw_remove_data_fn() 396 // version as read-only? 397 function draw_plugin_version() 398 { 399 $options = get_option('ContentScheduler_Options'); 400 echo "<input type='text' name='ContentScheduler_Options[version]' value='$options[version]' readonly='readonly' />"; 401 } // end draw_plugin_version() 114 115 116 117 118 /* 119 Propagates pfunction to all blogs within our multisite setup. 120 http://shibashake.com/wordpress-theme/write-a-plugin-for-wordpress-multi-site 121 If not multisite, then we just run pfunction for our single blog. 122 */ 123 function network_propagate($pfunction, $networkwide) { 124 global $wpdb; 125 126 if (function_exists('is_multisite') && is_multisite()) { 127 // check if it is a network activation - if so, run the activation function 128 // for each blog id 129 if ($networkwide) { 130 $old_blog = $wpdb->blogid; 131 // Get all blog ids 132 $blogids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->blogs}"); 133 foreach ($blogids as $blog_id) { 134 switch_to_blog($blog_id); 135 call_user_func($pfunction, $networkwide); 136 } 137 switch_to_blog($old_blog); 138 return; 139 } 140 } 141 call_user_func($pfunction, $networkwide); 142 } 143 144 145 146 147 function run_on_activate( $network_wide ) 148 { 149 $this->network_propagate( array( $this, '_activate' ), $networkwide ); 150 } 151 152 // TODO: Still need to review what we do during activation 153 function _activate() { 154 $this->setup_timezone(); 155 // Let's see about setting some default options 156 $options = get_option('ContentScheduler_Options'); 157 // 4/26/2011 3:58:08 PM -pk 158 // If version newer than 0.9.7, we need to alter the name of our postmeta variables if there are earlier version settings in options 159 if( is_array( $options ) ) 160 { 161 // The plugin has at least been installed before, so it could be older 162 if( !isset( $options['version'] ) || $options['version'] < '0.9.7' ) 163 { 164 // we do need to change existing postmeta variable names in the database 165 include 'includes/update-postmeta-names.php'; 166 } 167 } 168 // 12/23/2011 -pk 169 // If version newer tha 0.9.8, we need to alter the name of our user_level values 170 if( is_array( $options ) ) 171 { 172 // The plugin has at least been installed before, so it could be older and need changes 173 if( !isset( $options['version'] ) || $options['version'] < '0.9.8' ) 174 { 175 // we do need to change existing user-level access values in the database 176 include 'includes/update-minlevel-options.php'; 177 } 178 } 179 // Build an array of each option and its default setting 180 // exp-default is supposed to be a serialized array of hours, days, weeks 181 $expiration_default = array( 'exp-hours' => '0', 'exp-days' => '0', 'exp-weeks' => '0' ); 182 // $expiration_default = serialize( $expiration_default ); 183 $arr_defaults = array 184 ( 185 "version" => "1.0.0", 186 "exp-status" => "1", 187 "exp-period" => "1", 188 "chg-status" => "2", 189 "chg-sticky" => "0", 190 "chg-cat-method" => "0", 191 "selcats" => "", 192 "tags-to-add" => "", 193 "notify-on" => "0", 194 "notify-admin" => "0", 195 "notify-author" => "0", 196 "notify-expire" => "0", 197 "min-level" => "level_1", 198 "show-columns" => "0", 199 "datepicker" => "0", 200 "remove-cs-data" => "0", 201 "exp-default" => $expiration_default 202 ); 203 // check to see if we need to set defaults 204 // first condition is that the 'restore defaults' checkbox is on (we don't have that yet.) 205 // OR condition is that defaults haven't even been set 206 if( !is_array( $options ) ) 207 { 208 // We can safely set options to defaults 209 update_option('ContentScheduler_Options', $arr_defaults); 210 } 211 else 212 { 213 // we found some ContentScheduler_Options in the database 214 // We need to check the "version" and, if it is less than 0.9.5 or non-existent, we need to convert english string values to numbers 215 if( !isset( $options['version'] ) || $options['version'] < '0.9.5' ) 216 { 217 // we want to change options from english strings to numbers - this happened from 0.9.4 to 0.9.5 218 switch( $options['exp-status'] ) 219 { 220 case 'Hold': 221 $options['exp-status'] = '0'; 222 break; 223 case 'Delete': 224 $options['exp-status'] = '2'; 225 break; 226 default: 227 $options['exp-status'] = '1'; 228 } // end switch 229 switch( $options['chg-status'] ) 230 { 231 case 'No Change': 232 $options['chg-status'] = '0'; 233 break; 234 case 'Pending': 235 $options['chg-status'] = '1'; 236 break; 237 case 'Private': 238 $options['chg-status'] = '3'; 239 break; 240 default: 241 $options['chg-status'] = '2'; 242 } 243 /* 244 $r = (1 == $v) ? 'Yes' : 'No'; // $r is set to 'Yes' 245 $r = (3 == $v) ? 'Yes' : 'No'; // $r is set to 'No' 246 */ 247 $options['chg-sticky'] = ( 'No Change' == $options['chg-sticky'] ) ? '0' : '1'; 248 switch( $options['chg-cat-method'] ) 249 { 250 case 'Add selected': 251 $options['chg-cat-method'] = '1'; 252 break; 253 case 'Remove selected': 254 $options['chg-cat-method'] = '2'; 255 break; 256 case 'Match selected': 257 $options['chg-cat-method'] = '3'; 258 break; 259 default: 260 $options['chg-cat-method'] = '0'; 261 } 262 $options['notify-on'] = ( 'Notification off' == $options['notify-on'] ) ? '0' : '1'; 263 $options['notify-admin'] = ( 'Do not notify admin' == $options['notify-admin'] ) ? '0' : '1'; 264 $options['notify-author'] = ( 'Do not notify author' == $options['notify-author'] ) ? '0' : '1'; 265 $options['notify-expire'] = ( 'Do not notify on expiration' == $options['notify-expire'] ) ? '0' : '1'; 266 $options['show-columns'] = ( 'Do not show expiration in columns' == $options['show-columns'] ) ? '0' : '1'; 267 $options['datepicker'] = ( 'Do not use datepicker' == $options['datepicker'] ) ? '0' : '1'; 268 $options['remove-cs-data'] = ( 'Do not remove data' == $options['remove-cs-data'] ) ? '0' : '1'; 269 // don't forget to do array_replace when we're done?? Or what? 270 // This whole block should perhaps be placed in a function 271 } 272 // We need to update the version string to our current version 273 $options['version'] = "1.0.0"; 274 // make sure we have added any updated options 275 if (!function_exists('array_replace')) 276 { 277 // we're before php 5.3.0, and need to use our array_replace 278 $new_options = $this->array_replace( $arr_defaults, $options ); 279 } 280 else 281 { 282 // go ahead and use php 5.3.0 array_replace 283 $new_options = array_replace( $arr_defaults, $options ); 284 } 285 update_option('ContentScheduler_Options', $new_options); 286 } 287 // We need to get our expiration event into the wp-cron schedules somehow 288 if( $current_blog_id != '' ) 289 { 290 // it is a networked site activation 291 // Test for the event already existing before you schedule the event again 292 // for expirations 293 if( !wp_next_scheduled( 'content_scheduler_'.$current_blog_id ) ) 294 { 295 wp_schedule_event( time(), 'contsched_usertime', 'content_scheduler_'.$current_blog_id ); 296 // wp_schedule_event( time(), 'hourly', 'content_scheduler_'.$current_blog_id ); 297 } 298 } 299 else 300 { 301 // it is not a networked site activation, or a single site within a network 302 // for expirations 303 if( !wp_next_scheduled( 'content_scheduler' ) ) 304 { 305 wp_schedule_event( time(), 'contsched_usertime', 'content_scheduler' ); 306 // wp_schedule_event( time(), 'hourly', 'content_scheduler' ); 307 } 308 } 309 } // end activate_function 310 311 function run_on_deactivate( $network_wide ) { 312 $this->network_propagate( array( $this, '_deactivate' ), $networkwide ); 313 } // end run_on_activate() 314 315 // TODO: Still need to review what we do during deactivation 316 function _deactivate() { 317 if( $current_blog_id != '' ) 318 { 319 // it is a networked site activation 320 // for expirations 321 wp_clear_scheduled_hook('content_scheduler_'.$current_blog_id); 322 // for notifications 323 wp_clear_scheduled_hook('content_scheduler_notify_'.$current_blog_id); 324 } 325 else 326 { 327 // for expirations 328 wp_clear_scheduled_hook('content_scheduler'); 329 // for notifications 330 wp_clear_scheduled_hook('content_scheduler_notify'); 331 } 332 } // end deactivate_function() 333 334 function content_scheduler_init() { 335 // load language translation files 336 $plugin_dir = basename(dirname(__FILE__)) . '/lang'; 337 load_plugin_textdomain( 'contentscheduler', PEK_CONTENT_SCHEDULER_DIR . 'lang', basename( dirname( __FILE__ ) ) .'/lang' ); 338 } 339 340 // I think this is not needed now that we broke settings out into its own class 341 /* 342 // TODO: Still need to review what happens during admin_init 343 function admin_init() 344 { 345 include "includes/init-admin.php"; 346 } // end admin_init() 347 348 // TODO: Still need to review what happens during admin_menu 349 function admin_menu() 350 { 351 // Make sure we should be here 352 if (!function_exists('current_user_can') || !current_user_can('manage_options') ) 353 return; 354 // Add our plugin options page 355 if ( function_exists( 'add_options_page' ) ) 356 { 357 add_options_page( 358 __('Content Scheduler Options Page', 'contentscheduler'), 359 __('Content Scheduler', 'contentscheduler'), 360 'manage_options', 361 'ContentScheduler_options', 362 array('ContentScheduler', 'ContentScheduler_drawoptions_fn' ) ); 363 } 364 } // end admin_menus() 365 */ 366 367 368 369 370 402 371 // ======================================================================== 403 372 // == JavaScript and CSS Enqueueing? … … 441 410 } 442 411 } // end cs_edit_styles() 443 // ==================================================================== 444 // == Administration Menus Stuff 445 // ==================================================================== 446 function ContentScheduler_addoptions_page_fn() 447 { 448 // Make sure we should be here 449 if (!function_exists('current_user_can') || !current_user_can('manage_options') ) 450 return; 451 // Add our plugin options page 452 if ( function_exists( 'add_options_page' ) ) 453 { 454 add_options_page( 455 __('Content Scheduler Options Page', 'contentscheduler'), 456 __('Content Scheduler', 'contentscheduler'), 457 'manage_options', 458 'ContentScheduler_options', 459 array('ContentScheduler', 'ContentScheduler_drawoptions_fn' ) ); 460 } 461 } // end admin_menus() 462 // Show our Options page in Admin 463 function ContentScheduler_drawoptions_fn() 464 { 465 // Get our current options out of the database? -pk 466 $ContentScheduler_Options = get_option('ContentScheduler_Options'); 467 ?> 468 <div class="wrap"> 469 <?php screen_icon("options-general"); ?> 470 <h2>Content Scheduler <?php echo $ContentScheduler_Options['version']; ?></h2> 471 <form action="options.php" method="post"> 472 <?php 473 // nonces - hidden fields - auto via the SAPI 474 settings_fields('ContentScheduler_Options_Group'); 475 // spits out fields defined by settings_fields and settings_sections 476 do_settings_sections('ContentScheduler_Page_Title'); 477 ?> 478 <p class="submit"> 479 <input name="Submit" type="submit" class="button-primary" value="<?php esc_attr_e('Save Changes', 'contentscheduler'); ?>" /> 480 </p> 481 </form> 482 </div> 483 <?php 484 } // end sample_form() 485 // Prints an overview under the Settings Section Title 486 // Could be used for help strings, whatever. 487 // I think I've seen some plugins do jQuery accordian to hide / show help. 488 function draw_overview() 489 { 490 // This shows things under the title of Expiration Settings 491 echo "<p>"; 492 _e( 'Indicate whether to process content on expiration, and whether to delete it or make certain changes to it.', 'contentscheduler' ); 493 echo "</p>\n"; 494 } // end overview_settings() 495 function draw_overview_not() 496 { 497 // This shows things under the title of Notification Settings 498 echo "<p>"; 499 _e( 'Indicate whether to send notifications about content expiration, who to notify, and when they should be notified.', 'contentscheduler' ); 500 echo "</p>\n"; 501 } // end draw_overview_not() 502 function draw_overview_disp() 503 { 504 // This shows things under the title of Display Settings 505 echo "<p>"; 506 _e( 'Control how Content Scheduler custom input areas display in the WordPress admin area. Also indicate if deleting the plugin should remove its options and post metadata.', 'contentscheduler' ); 507 echo "</p>\n"; 508 } // end draw_overview_disp() 509 // ========================================================================== 510 // == Set options to defaults - used during plugin activation 511 // ========================================================================== 512 // == NOTE that activations do not run since 3.1 upon UPDATES. 513 // Talk of an update hook, not sure where that is. 514 // When update happens, if we need to change anything in database... how do we trigger that?? 515 // define default option settings 516 // ==================== 517 function run_on_activate( $network_wide ) 518 { 519 global $wpdb; 520 521 // See if the plugin is being activated for the entire network of blogs 522 if ( $network_wide ) 523 { 524 // Save the current blog id 525 $orig_blog = $wpdb->blogid; 526 // Loop through all existing blogs (by id) 527 $all_blogs = $wpdb->get_col( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs") ); 528 foreach ($all_blogs as $blog_id) 529 { 530 switch_to_blog( $blog_id ); 531 $this->activate_function( $blog_id ); 532 } // end foreach 533 // switch back to the original blog 534 switch_to_blog( $orig_blog ); 535 return; 536 } else { 537 // Seems like it is not a multisite install OR it is a single blog of a multisite 538 $this->activate_function(''); 539 } // end if 540 } // end run_on_activate() 541 // tied to the run_on_activate function above 542 function activate_function( $current_blog_id = '' ) 543 { 544 $this->setup_timezone(); 545 // Let's see about setting some default options 546 $options = get_option('ContentScheduler_Options'); 547 // 4/26/2011 3:58:08 PM -pk 548 // If version newer than 0.9.7, we need to alter the name of our postmeta variables if there are earlier version settings in options 549 if( is_array( $options ) ) 550 { 551 // The plugin has at least been installed before, so it could be older 552 if( !isset( $options['version'] ) || $options['version'] < '0.9.7' ) 553 { 554 // we do need to change existing postmeta variable names in the database 555 include 'includes/update-postmeta-names.php'; 556 } 557 } 558 // 12/23/2011 -pk 559 // If version newer tha 0.9.8, we need to alter the name of our user_level values 560 if( is_array( $options ) ) 561 { 562 // The plugin has at least been installed before, so it could be older and need changes 563 if( !isset( $options['version'] ) || $options['version'] < '0.9.8' ) 564 { 565 // we do need to change existing user-level access values in the database 566 include 'includes/update-minlevel-options.php'; 567 } 568 } 569 // Build an array of each option and its default setting 570 // exp-default is supposed to be a serialized array of hours, days, weeks 571 $expiration_default = array( 'exp-hours' => '0', 'exp-days' => '0', 'exp-weeks' => '0' ); 572 // $expiration_default = serialize( $expiration_default ); 573 $arr_defaults = array 574 ( 575 "version" => "1.0.0", 576 "exp-status" => "1", 577 "exp-period" => "1", 578 "chg-status" => "2", 579 "chg-sticky" => "0", 580 "chg-cat-method" => "0", 581 "selcats" => "", 582 "tags-to-add" => "", 583 "notify-on" => "0", 584 "notify-admin" => "0", 585 "notify-author" => "0", 586 "notify-expire" => "0", 587 "min-level" => "level_1", 588 "show-columns" => "0", 589 "datepicker" => "0", 590 "remove-cs-data" => "0", 591 "exp-default" => $expiration_default 592 ); 593 // check to see if we need to set defaults 594 // first condition is that the 'restore defaults' checkbox is on (we don't have that yet.) 595 // OR condition is that defaults haven't even been set 596 if( !is_array( $options ) ) 597 { 598 // We can safely set options to defaults 599 update_option('ContentScheduler_Options', $arr_defaults); 600 } 601 else 602 { 603 // we found some ContentScheduler_Options in the database 604 // We need to check the "version" and, if it is less than 0.9.5 or non-existent, we need to convert english string values to numbers 605 if( !isset( $options['version'] ) || $options['version'] < '0.9.5' ) 606 { 607 // we want to change options from english strings to numbers - this happened from 0.9.4 to 0.9.5 608 switch( $options['exp-status'] ) 609 { 610 case 'Hold': 611 $options['exp-status'] = '0'; 612 break; 613 case 'Delete': 614 $options['exp-status'] = '2'; 615 break; 616 default: 617 $options['exp-status'] = '1'; 618 } // end switch 619 switch( $options['chg-status'] ) 620 { 621 case 'No Change': 622 $options['chg-status'] = '0'; 623 break; 624 case 'Pending': 625 $options['chg-status'] = '1'; 626 break; 627 case 'Private': 628 $options['chg-status'] = '3'; 629 break; 630 default: 631 $options['chg-status'] = '2'; 632 } 633 /* 634 $r = (1 == $v) ? 'Yes' : 'No'; // $r is set to 'Yes' 635 $r = (3 == $v) ? 'Yes' : 'No'; // $r is set to 'No' 636 */ 637 $options['chg-sticky'] = ( 'No Change' == $options['chg-sticky'] ) ? '0' : '1'; 638 switch( $options['chg-cat-method'] ) 639 { 640 case 'Add selected': 641 $options['chg-cat-method'] = '1'; 642 break; 643 case 'Remove selected': 644 $options['chg-cat-method'] = '2'; 645 break; 646 case 'Match selected': 647 $options['chg-cat-method'] = '3'; 648 break; 649 default: 650 $options['chg-cat-method'] = '0'; 651 } 652 $options['notify-on'] = ( 'Notification off' == $options['notify-on'] ) ? '0' : '1'; 653 $options['notify-admin'] = ( 'Do not notify admin' == $options['notify-admin'] ) ? '0' : '1'; 654 $options['notify-author'] = ( 'Do not notify author' == $options['notify-author'] ) ? '0' : '1'; 655 $options['notify-expire'] = ( 'Do not notify on expiration' == $options['notify-expire'] ) ? '0' : '1'; 656 $options['show-columns'] = ( 'Do not show expiration in columns' == $options['show-columns'] ) ? '0' : '1'; 657 $options['datepicker'] = ( 'Do not use datepicker' == $options['datepicker'] ) ? '0' : '1'; 658 $options['remove-cs-data'] = ( 'Do not remove data' == $options['remove-cs-data'] ) ? '0' : '1'; 659 // don't forget to do array_replace when we're done?? Or what? 660 // This whole block should perhaps be placed in a function 661 } 662 // We need to update the version string to our current version 663 $options['version'] = "1.0.0"; 664 // make sure we have added any updated options 665 if (!function_exists('array_replace')) 666 { 667 // we're before php 5.3.0, and need to use our array_replace 668 $new_options = $this->array_replace( $arr_defaults, $options ); 669 } 670 else 671 { 672 // go ahead and use php 5.3.0 array_replace 673 $new_options = array_replace( $arr_defaults, $options ); 674 } 675 update_option('ContentScheduler_Options', $new_options); 676 } 677 // We need to get our expiration event into the wp-cron schedules somehow 678 if( $current_blog_id != '' ) 679 { 680 // it is a networked site activation 681 // Test for the event already existing before you schedule the event again 682 // for expirations 683 if( !wp_next_scheduled( 'content_scheduler_'.$current_blog_id ) ) 684 { 685 wp_schedule_event( time(), 'contsched_usertime', 'content_scheduler_'.$current_blog_id ); 686 // wp_schedule_event( time(), 'hourly', 'content_scheduler_'.$current_blog_id ); 687 } 688 } 689 else 690 { 691 // it is not a networked site activation, or a single site within a network 692 // for expirations 693 if( !wp_next_scheduled( 'content_scheduler' ) ) 694 { 695 wp_schedule_event( time(), 'contsched_usertime', 'content_scheduler' ); 696 // wp_schedule_event( time(), 'hourly', 'content_scheduler' ); 697 } 698 } 699 } // end activate_function 700 // ==================== 701 function run_on_deactivate( $network_wide ) 702 { 703 global $wpdb; 704 // See if the plugin is being deactivated for the entire network of blogs 705 if ( $network_wide ) 706 { 707 // Save the current blog id 708 $orig_blog = $wpdb->blogid; 709 // Loop through all existing blogs (by id) 710 $all_blogs = $wpdb->get_col( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs") ); 711 foreach ($all_blogs as $blog_id) 712 { 713 switch_to_blog( $blog_id ); 714 $this->deactivate_function( $blog_id ); 715 } // end foreach 716 // switch back to the original blog 717 switch_to_blog( $orig_blog ); 718 return; 719 } else { 720 // Seems like it is not a multisite install OR it is a single blog of a multisite 721 $this->deactivate_function(''); 722 } // end if 723 } // end run_on_activate() 724 function deactivate_function( $current_blog_id ) 725 { 726 if( $current_blog_id != '' ) 727 { 728 // it is a networked site activation 729 // for expirations 730 wp_clear_scheduled_hook('content_scheduler_'.$current_blog_id); 731 // for notifications 732 wp_clear_scheduled_hook('content_scheduler_notify_'.$current_blog_id); 733 } 734 else 735 { 736 // for expirations 737 wp_clear_scheduled_hook('content_scheduler'); 738 // for notifications 739 wp_clear_scheduled_hook('content_scheduler_notify'); 740 } 741 } // end deactivate_function() 742 // ========================================================================== 743 // == Validation Function for Options 744 // ==================================================== 745 // Validates values from the ADMIN ContentScheduler_Options group 746 function validate_settings($input) 747 { 748 global $blog_id; 749 // get current plugin options 750 $options = get_option('ContentScheduler_Options'); 751 // We need a value for exp-period 752 if ( empty( $input['exp-period'] ) ) 753 { 754 $input['exp-period'] = 1; // 1 minute 755 } 756 else 757 { 758 // exp-period was not empty, so we need to make sure it is an integer 759 if ( ! sprintf("%u", $input['exp-period']) == $input['exp-period'] ) 760 { 761 // exp-period was not an integer, so let's return an error 762 // First, let's set it to an acceptable value 763 $input['exp-period'] = 1; // 1 minute 764 add_settings_error('ContentScheduler_Options', 765 'settings_updated', 766 __('Only positive integers are accepted for "Expiration period".', 'contentscheduler'), 767 'error'); 768 } 769 } 770 // Make sure tags are alphanumeric and that is all 771 // Testing tags-to-add, which should be a comma-delimited list of alphanumerics 772 // trim out space from tags string 773 $input['tags-to-add'] = trim( $input['tags-to-add'] ); 774 if ( !empty( $input['tags-to-add'] ) ) 775 { 776 $input['tags-to-add'] = filter_var( $input['tags-to-add'], FILTER_SANITIZE_STRING ); 777 } 778 // We need to take inputs from the default expiration time and pack it up into an array. 779 $default_hours = $input['def-hours']; 780 $default_days = $input['def-days']; 781 $default_weeks = $input['def-weeks']; 782 // First, let's assume everything was entered as integers. We'll work this out later before distributing. 783 $default_days = $default_days + floor( $default_hours / 24); 784 $default_hours = $default_hours % 24; // remainder 785 $default_weeks = $default_weeks + floor( $default_days / 7); 786 $default_days = $default_days % 7; // remainder 787 unset( $input['def-hours'] ); 788 unset( $input['def-days'] ); 789 unset( $input['def-weeks'] ); 790 $input['exp-default'] = array( 'def-hours' => $default_hours, 'def-days' => $default_days, 'def-weeks' => $default_weeks ); 791 // we need to update wp_schedules for expiration and notification 792 // See if this is a multisite install 793 if ( function_exists( 'is_multisite' ) && is_multisite() ) 794 { 795 // it is a networked site activation 796 // Clear out what is there now 797 // for expirations 798 wp_clear_scheduled_hook('content_scheduler_'.$blog_id); 799 wp_schedule_event( time(), 'contsched_usertime', 'content_scheduler_'.$blog_id ); 800 } 801 else 802 { 803 // it is not a networked site 804 // for expirations 805 wp_clear_scheduled_hook('content_scheduler'); 806 wp_schedule_event( time(), 'contsched_usertime', 'content_scheduler' ); 807 } 808 // if we had an error, do we still return? Or not? 809 return $input; 810 } // end validate_settings() 412 811 413 // ================================================================= 812 414 // == Functions for using Custom Controls / Panels … … 1023 625 return true; 1024 626 } // end ContentScheduler_save_postdata() 627 628 629 630 631 1025 632 // ======================================================================= 1026 633 // == SCHEDULING FUNCTIONS … … 1179 786 } // end process_custom() 1180 787 788 789 790 791 1181 792 // ================================================================ 1182 793 // == Conditionally Add Expiration date to Column views 1183 794 // ================================================================ 1184 795 // add our column to the table 1185 function cs_add_expdate_column ($columns) 1186 { 796 function cs_add_expdate_column ($columns) { 1187 797 global $current_user; 1188 798 // Check to see if we really want to add our column … … 1207 817 return $columns; 1208 818 } // end cs_add_expdate_column() 819 1209 820 // fill our column in the table, for each item 1210 function cs_show_expdate ($column_name) 1211 { 821 function cs_show_expdate ($column_name) { 1212 822 global $wpdb, $post, $current_user; 1213 823 // Check to see if we really want to add our column 1214 824 $options = get_option('ContentScheduler_Options'); 1215 if( $options['show-columns'] == '1' ) 1216 { 825 if( $options['show-columns'] == '1' ) { 1217 826 // Check to see if current user has permissions to see 1218 827 // What is minimum level required to see CS? … … 1244 853 } // end if 1245 854 } // end cs_show_expdate() 855 856 857 858 859 1246 860 // ================================================================== 1247 861 // == SHORTCODES … … 1255 869 // === TEMPLATE TAG NOTE === 1256 870 // We'll add a template tag that will also call this function for output. 1257 // [cs_expiration] 1258 function handle_shortcode( $attributes ) 1259 { 1260 global $post; 1261 global $current_user; 1262 // Check to see if we have rights to see stuff 1263 $options = get_option('ContentScheduler_Options'); 1264 $min_level = $options['min-level']; 1265 get_currentuserinfo(); 1266 $allcaps = $current_user->allcaps; 1267 if( 1 != $allcaps[$min_level] ) 1268 { 1269 return; // not authorized to see CS 1270 } 1271 // else - continue 1272 // get the expiration timestamp 1273 $expirationdt = get_post_meta( $post->ID, '_cs-expire-date', true ); 1274 if ( empty( $expirationdt ) ) 1275 { 1276 return false; 1277 } 1278 // We'll need the following if / when we allow formatting of the timestamp 1279 /* 1280 // we'll default to formats selected in Settings > General 1281 extract( shortcode_atts( array( 1282 'dateformat' => get_option('date_format'), 1283 'timeformat' => get_option('time_format') 1284 ), $attributes ) ); 1285 // We always show date and time together 1286 $format = $dateformat . ' ' . $timeformat; 1287 return date( "$format", $expirationdt ); 1288 */ 1289 $return_string = sprintf( __("Expires: %s", 'contentscheduler'), $expirationdt ); 1290 return $return_string; 1291 } 1292 // ======================================================================= 1293 // == GENERAL UTILITY FUNCTIONS 1294 // ======================================================================= 1295 // 3/28/2011 12:21:31 AM -pk 1296 // Added for pre 5.3 php compatibility 1297 // NOTE there is a function of the same name in php 5.3.0+, but this one is within our Class 1298 function array_replace( &$array, &$array1 ) 1299 { 1300 $args = func_get_args(); 1301 $count = func_num_args(); 1302 for ($i = 0; $i < $count; ++$i) { 1303 if (is_array($args[$i])) { 1304 foreach ($args[$i] as $key => $val) { 1305 $array[$key] = $val; 1306 } 1307 } 1308 else { 1309 trigger_error( 1310 __FUNCTION__ . '(): Argument #' . ($i+1) . ' is not an array', 1311 E_USER_WARNING 1312 ); 1313 return NULL; 1314 } 1315 } 1316 return $array; 1317 } 871 // [cs_expiration] 872 function handle_shortcode( $attributes ) 873 { 874 global $post; 875 global $current_user; 876 // Check to see if we have rights to see stuff 877 $options = get_option('ContentScheduler_Options'); 878 $min_level = $options['min-level']; 879 get_currentuserinfo(); 880 $allcaps = $current_user->allcaps; 881 if( 1 != $allcaps[$min_level] ) 882 { 883 return; // not authorized to see CS 884 } 885 // else - continue 886 // get the expiration timestamp 887 $expirationdt = get_post_meta( $post->ID, '_cs-expire-date', true ); 888 if ( empty( $expirationdt ) ) 889 { 890 return false; 891 } 892 // We'll need the following if / when we allow formatting of the timestamp 893 /* 894 // we'll default to formats selected in Settings > General 895 extract( shortcode_atts( array( 896 'dateformat' => get_option('date_format'), 897 'timeformat' => get_option('time_format') 898 ), $attributes ) ); 899 // We always show date and time together 900 $format = $dateformat . ' ' . $timeformat; 901 return date( "$format", $expirationdt ); 902 */ 903 $return_string = sprintf( __("Expires: %s", 'contentscheduler'), $expirationdt ); 904 return $return_string; 905 } 906 907 908 909 910 911 // ======================================================================= 912 // == GENERAL UTILITY FUNCTIONS 913 // ======================================================================= 1318 914 // 11/17/2010 3:06:27 PM -pk 1319 915 // NOTE: We could add another parameter, '$format,' to support different date formats 1320 function check_date_format($date) 1321 { 916 function check_date_format($date) { 1322 917 // match the format of the date 1323 918 // in this case, it is ####-##-## … … 1352 947 } 1353 948 } 1354 // ================================================================ 1355 // Detect WordPress Network Install 1356 function is_network_site() 1357 { 1358 if ( function_exists( 'is_multisite' ) && is_multisite() ) 1359 { 1360 return true; 1361 } 1362 else 1363 { 1364 return false; 1365 } 1366 } 1367 // =============================================================== 1368 // Logging for development 1369 /* 1370 function log_to_file($filename, $msg) 1371 { 1372 // open file 1373 $fd = fopen($filename, "a"); 1374 // append date/time to message 1375 $this->setup_timezone(); 1376 $str = "[" . date("Y/m/d H:i:s") . "] " . $msg; 1377 // write string 1378 fwrite($fd, $str . "\n"); 1379 // close file 1380 fclose($fd); 1381 } 1382 */ 949 1383 950 // ================================================================ 1384 951 // handle timezones … … 1394 961 } // end ContentScheduler Class 1395 962 } // End IF Class ContentScheduler 1396 // Instantiating the Class 1397 // 10/27/2010 8:27:59 AM -pk 1398 // NOTE that instantiating is OUTSIDE of the Class 963 964 965 966 967 global $pk_ContentScheduler; 1399 968 if (class_exists("ContentScheduler")) { 1400 969 $pk_ContentScheduler = new ContentScheduler(); 1401 970 } 971 1402 972 // ======================================================================== 1403 973 // == TEMPLATE TAG -
content-scheduler/trunk/readme.txt
r706934 r1047420 2 2 Contributors: freakingid 3 3 Plugin Name: Content Scheduler 4 Plugin URI: http:// structurewebdev.com/wordpress-plugins/content-scheduler/4 Plugin URI: http://paulekaiser.com/wordpress-plugins/content-scheduler/ 5 5 Tags: expire posts, expire, expiring, scheduling, sticky 6 6 Author URI: http://profiles.wordpress.org/users/freakingid/ 7 7 Author: Paul Kaiser (freakingid) 8 8 Requires at least: 2.9 9 Tested up to: 3.5.110 Stable tag: 1.0.09 Tested up to: 4.0.1 10 Stable tag: 2.0.0 11 11 12 12 Schedule content to automatically expire and change at a certain time, and notify people of expiration. … … 39 39 40 40 == Frequently Asked Questions == 41 42 = Where did you get the datepicker used in this plugin? =43 44 That's the ["Any+Time" date / time picker:](http://www.ama3.com/anytime/)45 46 = Why isn't the datepicker showing up for me? =47 48 1. Make sure you have enabled the datepicker in the plugin's settings.49 50 1. You may have another plugin installed that uses JavaScript in the backend that conflicts with the Any+Time datepicker. Try disabling other plugins, one at a time, and checking for the datepicker working.51 41 52 42 = Does Content Scheduler work with Network / Multisite installations? =
Note: See TracChangeset
for help on using the changeset viewer.