Changeset 730151
- Timestamp:
- 06/23/2013 12:36:31 AM (13 years ago)
- Location:
- post-sorter
- Files:
-
- 1 added
- 6 edited
-
assets/screenshot-4.jpg (added)
-
trunk/css/style.css (modified) (1 diff)
-
trunk/js/common.js (modified) (1 diff)
-
trunk/page/general.php (modified) (2 diffs)
-
trunk/post_sorter.php (modified) (1 diff)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/uninstall.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
post-sorter/trunk/css/style.css
r620244 r730151 28 28 margin-right: 16px; 29 29 } 30 31 .post_sorter_form textarea {} 32 .post_sorter_form textarea[readonly="readonly"] { background-color: #eee; } -
post-sorter/trunk/js/common.js
r620244 r730151 56 56 57 57 function post_sorter_onMove(res) { 58 //window.location.href = window.location;58 window.location.href = window.location; 59 59 } -
post-sorter/trunk/page/general.php
r620244 r730151 2 2 global $post_sorter; 3 3 4 if( !empty($_POST))4 if( !empty( $_POST ) ) 5 5 $post_sorter->save_settings(); 6 6 ?> … … 12 12 13 13 <form id="post_sorter_settings" action="" method="post" class="post_sorter_form"> 14 <input name="post_sorter_enabled" id="post_sorter_enabled" type="checkbox" <?php checked(1, get_option('post_sorter_enabled'))?> /> <label for="post_sorter_enabled"><?php _e('Enable Post Sorter', 'post_sorter') ?></label><br /><br /> 15 16 <input name="post_sorter_direction" id="post_sorter_direction_asc" type="radio" value="ASC" <?php checked('', get_option('post_sorter_direction'))?> /> <label for="post_sorter_direction_asc"><?php _e('Sort Ascending', 'post_sorter') ?></label><br /> 17 <input name="post_sorter_direction" id="post_sorter_direction_desc" type="radio" value="DESC" <?php checked('DESC', get_option('post_sorter_direction'))?> /> <label for="post_sorter_direction_desc"><?php _e('Sort Descending', 'post_sorter') ?></label> 14 <h3><?php _e( 'Basic Settings', 'post_sorter' ) ?></h3> 15 16 <table class="form-table"> 17 <tbody> 18 <tr valign="top"> 19 <th scope="row"><label for="post_sorter_enabled"><?php _e( 'Enable Post Sorter', 'post_sorter' ) ?></label>:</th> 20 <td> 21 <input name="post_sorter_enabled" id="post_sorter_enabled" type="checkbox" <?php checked( 1, get_option( 'post_sorter_enabled' ) )?> /> 22 <span class="hint"><?php _e( 'The plugin will only work on the client side, if it is enabled', 'post_sorter' ) ?></span> 23 </td> 24 </tr> 25 26 <tr valign="top"> 27 <th scope="row"><label for="post_sorter_direction_asc"><?php _e( 'Sort Ascending', 'post_sorter' ) ?></label>:</th> 28 <td> 29 <input name="post_sorter_direction" id="post_sorter_direction_asc" type="radio" value="ASC" <?php checked( '', get_option( 'post_sorter_direction' ) )?> /> 30 <span class="hint"><?php _e( 'If selected all posts will be sorted in ascending order', 'post_sorter' ) ?></span> 31 </td> 32 </tr> 33 34 <tr valign="top"> 35 <th scope="row"><label for="post_sorter_direction_desc"><?php _e( 'Sort Descending', 'post_sorter' ) ?></label>:</th> 36 <td> 37 <input name="post_sorter_direction" id="post_sorter_direction_desc" type="radio" value="DESC" <?php checked( 'DESC', get_option( 'post_sorter_direction' ) )?> /> 38 <span class="hint"><?php _e( 'If selected all posts will be sorted in descending order', 'post_sorter' ) ?></span> 39 </td> 40 </tr> 41 </tbody> 42 </table> 18 43 19 <div class="controller"> 20 <a href="#"class="button-primary" onclick="jQuery('#post_sorter_settings').trigger('submit'); return false;"><?php _e('Save', 'post_sorter') ?></a> 21 </div> 44 <br class="clear" /> 45 <br class="clear" /> 46 47 <h3><?php _e( 'Advanced', 'post_sorter' ) ?></h3> 48 49 <table class="form-table"> 50 <tbody> 51 <tr valign="top"> 52 <th scope="row"><label for="post_sorter_arrows_enabled"><?php _e( 'Enable Arrows', 'post_sorter' ) ?></label>:</th> 53 <td> 54 <input name="post_sorter_arrows_enabled" id="post_sorter_arrows_enabled" type="checkbox" <?php checked( 1, get_option( 'post_sorter_arrows_enabled' ) )?> /> 55 <span class="hint"><?php _e( 'Allows quick sorting with arrow buttons in the sorting column', 'post_sorter' ) ?></span> 56 </td> 57 </tr> 58 </tbody> 59 </table> 60 61 <br class="clear" /> 62 <br class="clear" /> 63 64 <h3><?php _e( 'Expert Settings', 'post_sorter' ) ?></h3> 65 66 <p><b>Note</b>: From this section you will be able to customize sorting for your needs. However, good understanding of SQL and WordPress database architecture is needed.</p> 67 68 <p> 69 <b>Important:</b> 70 Before you do anything in this section, you have to unlock it by declaring you are doing any changes by your own risk and you understand 71 that any mistake here could bring your site down. 72 </p> 73 74 <p> 75 <b>Important:</b> 76 If any error occur you should be still able to reach this page and to remote any custom query statements below. This should return you site to previous working state. 77 </p> 78 79 <table class="form-table"> 80 <tbody> 81 <tr valign="top"> 82 <th scope="row"><label for="post_sorter_custom_enabled"><?php _e( 'I do changes at my own risk', 'post_sorter' ) ?></label>:</th> 83 <td> 84 <input name="post_sorter_custom_enabled" id="post_sorter_custom_enabled" type="checkbox" <?php checked( 1, get_option( 'post_sorter_custom_enabled' ) )?> /> 85 <span class="hint"><?php _e( 'You declare by checking this checkbox that you understand the risks and you are doing changes on your own risk.', 'post_sorter' ) ?></span> 86 </td> 87 </tr> 88 <tr valign="top"> 89 <th scope="row"><label for="post_sorter_join_clause"><?php _e( 'JOIN Clause', 'post_sorter' ) ?></label>:</th> 90 <td valign="top"> 91 <textarea name="post_sorter_join_clause" id="post_sorter_join_clause" rows="8" cols="80"><?php echo get_option('post_sorter_join_clause') ?></textarea> 92 <br /> 93 <span class="hint"><?php _e( 'Your custom join clause that would be applied on the post list SQL query.', 'post_sorter' ) ?></span> 94 </td> 95 </tr> 96 <tr valign="top"> 97 <th scope="row"><label for="post_sorter_order_by_clause"><?php _e( 'ORDER BY Clause', 'post_sorter' ) ?></label>:</th> 98 <td valign="top"> 99 <textarea name="post_sorter_order_by_clause" id="post_sorter_order_by_clause" rows="8" cols="80"><?php echo get_option('post_sorter_order_by_clause') ?></textarea> 100 <br /> 101 <span class="hint"><?php _e( 'Your custom order by clause that would be applied on the post list SQL query.', 'post_sorter' ) ?></span> 102 </td> 103 </tr> 104 <tr valign="bottom"> 105 <th scope="row"> </th> 106 <td> 107 <div class="controller"> 108 <a href="#" class="button-primary" onclick="jQuery('#post_sorter_settings').trigger('submit'); return false;"><?php _e( 'Save', 'post_sorter' ) ?></a> 109 <a href="#" class="button" onclick="jQuery('#post_sorter_settings').trigger('reset'); return false;"><?php _e( 'Cancel', 'post_sorter' ) ?></a> 110 </div> 111 </td> 112 </tr> 113 </tbody> 114 </table> 22 115 </form> 23 116 </div> 117 118 <script type="text/javascript"> 119 jQuery(document).ready(function() { 120 if(!jQuery("#post_sorter_custom_enabled").is(":checked")) { 121 jQuery("#post_sorter_join_clause").attr("readonly", "readonly"); 122 jQuery("#post_sorter_order_by_clause").attr("readonly", "readonly"); 123 jQuery("#post_sorter_join_clause").val(); 124 jQuery("#post_sorter_order_by_clause").val(); 125 } 126 127 jQuery("#post_sorter_custom_enabled").change(function() { 128 if(!jQuery("#post_sorter_custom_enabled").is(":checked")) { 129 jQuery("#post_sorter_join_clause").attr("readonly", true); 130 jQuery("#post_sorter_order_by_clause").attr("readonly", true); 131 132 jQuery("#post_sorter_join_clause").val(""); 133 jQuery("#post_sorter_order_by_clause").val(""); 134 135 return; 136 } 137 138 jQuery("#post_sorter_join_clause").removeAttr("readonly"); 139 jQuery("#post_sorter_order_by_clause").removeAttr("readonly"); 140 }); 141 }); 142 </script> -
post-sorter/trunk/post_sorter.php
r620244 r730151 4 4 Plugin URI: http://intellisys.org/ 5 5 Description: Plugin for easy sorting of posts and pages by numeric value, both ascending and descending. 6 Version: 1. 06 Version: 1.2 7 7 Author: Lyubomir Gardev 8 8 Author URI: http://rolice.intellisys.info/ 9 9 Text Domain: post_sorter 10 10 License: GPLv2 or later 11 */12 13 define( 'POST_SORTER_META_KEY', 'post_sorter_order');11 */ 12 13 define( 'POST_SORTER_META_KEY', 'post_sorter_order' ); 14 14 15 15 class PostSorter { 16 17 public function __construct() { 18 $this->init(); 19 } 20 21 public function init() { 22 load_plugin_textdomain('post_sorter', false, plugin_dir_path( __FILE__ )); 23 24 add_filter('manage_posts_columns', array($this, 'add_sorter_column')); 25 add_filter('manage_pages_columns', array($this, 'add_sorter_column')); 26 27 add_action('manage_posts_custom_column', array($this, 'show_sorter_column')); 28 add_action('manage_pages_custom_column', array($this, 'show_sorter_column')); 29 30 add_filter('manage_edit-post_sortable_columns', array($this, 'add_sorter_sort')); 31 add_filter('manage_edit-page_sortable_columns', array($this, 'add_sorter_sort')); 32 33 add_filter('request', array($this, 'order_by')); 34 35 add_action('add_meta_boxes', array($this, 'add_meta_box')); 36 add_action('save_post', array($this, 'attach_on_save')); 37 38 add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts')); 39 40 add_action('wp_ajax_save_sort_position', array($this, 'save_sort_position')); 41 add_action('wp_ajax_move_sort_post', array($this, 'move_post')); 42 43 add_filter('posts_join', array($this, 'join_front')); 44 add_filter('posts_orderby', array($this, 'order_by_front')); 45 46 47 48 /* == = = = = = = = = = = ADMIN STUFF = = = = = = = = = = == */ 49 50 if(!is_admin()) 51 return; 52 53 add_action('admin_menu', array($this, 'add_menu')); 54 add_action('admin_init', array($this, 'register_settings')); 55 } 56 57 public function activate() { 58 update_option('post_sorter_enabled', true); 59 update_option('post_sorter_direction', 'ASC'); 60 61 $args = array( 62 'numberposts' => -1, 63 'post_type' => array('post', 'page'), 64 'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash') 65 ); 66 67 $posts = get_posts($args); 68 69 foreach ($posts as $post) { 70 $current = get_post_meta($post->ID, POST_SORTER_META_KEY, true); 71 72 if($current || $current === 0) 73 continue; 74 75 update_post_meta($post->ID, POST_SORTER_META_KEY, 0); 76 } 77 } 78 79 public function deactivate() { 80 } 81 82 public function enqueue_scripts() { 83 wp_register_style('post_sorter', plugin_dir_url( __FILE__ ) . 'css/style.css'); 84 wp_enqueue_style('post_sorter'); 85 86 wp_enqueue_script('post_sorter', plugin_dir_url( __FILE__ ) . 'js/common.js'); 87 } 88 89 public function add_sorter_column($columns) { 90 $columns['sort'] = 'Sorting'; 91 return $columns; 92 } 93 94 public function show_sorter_column($name) { 95 global $post; 96 97 switch($name) 98 { 99 case 'sort': 100 $this->render_sort_cell(); 101 break; 102 } 103 } 104 105 public function render_sort_cell() { 106 global $post; 107 108 $html = '<div class="post_sorter">'; 109 $val = (int) get_post_meta($post->ID, POST_SORTER_META_KEY, true); 110 111 $html .= '<a href="#" title="' . __( 'Move this element up', 'post_sorter' ) . '" class="up icon_button" 112 onclick="post_sorter_moveUp(' . $post->ID . '); return false;"></a>'; 113 $html .= '<a href="#" title="' . __( 'Move this element down', 'post_sorter' ) . '" class="down icon_button" 114 onclick="post_sorter_moveDown(' . $post->ID . '); return false;"></a>'; 115 116 $html .= '<input name="post_sorter_inline[]" id="post_sorter_inline_' . $post->ID . '" type="text" value="' . $val . '" class="inline_field" 117 onkeyup="return post_sorter_saveOnKeyUp(event, this, ' . $post->ID . ')" onblur="post_sorter_save(this, ' . $post->ID . ')" />'; 118 119 $html .= '</div>'; 120 121 echo $html; 122 } 123 124 public function add_sorter_sort($columns) { 125 $columns['sort'] = 'sort'; 126 127 return $columns; 128 } 129 130 public function order_by($vars) { 131 if(!isset($vars['orderby']) || 'sort' != $vars['orderby']) 132 return $vars; 133 134 $direction = mb_strtoupper(get_option('post_sorter_direction')) == 'DESC' ? ' DESC' : ''; 135 136 $vars = array_merge($vars, array( 137 'meta_key' => POST_SORTER_META_KEY, 138 'order_by' => 'meta_value_num' . $direction 139 140 )); 141 142 return $vars; 143 } 144 145 public function join_front($sql) { 146 global $wpdb; 147 148 if(!get_option('post_sorter_enabled')) 149 return $sql; 150 151 $sql .= "INNER JOIN {$wpdb->postmeta} AS post_sorter ON ({$wpdb->posts}.ID = post_sorter.post_id AND post_sorter.meta_key = '" . POST_SORTER_META_KEY . "')"; 152 153 return $sql; 154 155 } 156 157 public function order_by_front($sql) { 158 global $wpdb; 159 160 if(!get_option('post_sorter_enabled')) 161 return $sql; 162 163 $direction = mb_strtoupper(get_option('post_sorter_direction')) == 'DESC' ? ' DESC' : ''; 164 165 return 'post_sorter.meta_value' . $direction . ($sql ? ', ' . $sql : ''); 166 } 167 168 public function save($post_id, $position) { 169 $post_id = (int) $post_id; 170 $position = (int) $position; 171 172 if($post_id <= 0 || $position == 0) 173 return; 174 175 $result = new stdClass(); 176 177 $result->result = update_post_meta($post_id, POST_SORTER_META_KEY, $position); 178 179 if($result->result) { 180 $result->post_id = $post_id; 181 $result->position = $position; 182 } 183 184 die(json_encode($result)); 185 } 186 187 public function add_menu() { 188 add_menu_page('Page Sorter :: General', 'Page Sorter', 'administrator', 'page-sorter', array($this, 'render_menu')); 189 } 190 191 public function render_menu() { 192 include(plugin_dir_path( __FILE__ ) . 'page/general.php'); 193 } 194 195 public function register_settings() { 196 } 197 198 public function save_sort_position() { 199 $post_id = (int) $_POST['post_id']; 200 $position = (int) $_POST['position']; 201 202 $this->save($post_id, $position); 203 } 204 205 public function add_meta_box() { 206 add_meta_box('post_sorter', __( 'Post Sorter', 'post_sorter' ), array($this, 'render_meta_box'), null, 'side', 'core'); 207 } 208 209 public function render_meta_box( $post ) { 210 wp_nonce_field( plugin_basename( __FILE__ ), 'post_sorter' ); 211 212 $html = '<div class="post_sorter">'; 213 $val = (int) get_post_meta($post->ID, POST_SORTER_META_KEY, true); 214 215 $html .= __( 'Position Factor', 'post_sorter' ) . ': '; 216 217 $html .= '<input name="post_sorter_inline[]" id="post_sorter_inline_' . $post->ID . '" type="text" value="' . $val . '" class="inline_field" 218 onkeyup="return post_sorter_saveOnKeyUp(event, this, ' . $post->ID . ');" onblur="post_sorter_save(this, ' . $post->ID . ')" />'; 219 220 $html .= '</div>'; 221 222 echo $html; 223 } 224 225 public function save_settings() { 226 if(!current_user_can('manage_options')) 227 return; 228 229 if(empty($_POST)) 230 return; 231 232 update_option('post_sorter_enabled', isset($_POST['post_sorter_enabled'])); 233 update_option( 234 'post_sorter_direction', 235 isset($_POST['post_sorter_direction']) && mb_strtoupper($_POST['post_sorter_direction'] == 'DESC') 236 ? 'DESC' 237 : '' 238 ); 239 } 240 241 private function move($post_id, $direction = 'down') { 242 global $wpdb; 243 244 $post_id = (int) $post_id; 245 246 if($post_id <= 0) 247 return false; 248 249 $sort_direction = mb_strtoupper(get_option('post_sorter_direction')) == 'DESC' ? ' DESC' : ''; 250 $current = (int) get_post_meta($post_id, POST_SORTER_META_KEY, true); 251 252 $factor = (bool) $sort_direction ^ $direction == 'down'; 253 254 $sign_compare = $factor ? '>' : '<'; 255 $sign_modify = $factor ? '+' : '-'; 256 257 $post = get_post($post_id); 258 259 $sql = " 260 SELECT 261 pm.meta_value {$sign_modify} 1 262 FROM {$wpdb->posts} AS p 263 INNER JOIN {$wpdb->postmeta} AS pm ON (p.ID = pm.post_id AND pm.meta_key = '" . POST_SORTER_META_KEY . "') 264 WHERE 265 p.post_type = '{$post->post_type}' 266 AND 267 p.post_status = '{$post->post_status}' 268 AND 269 pm.meta_value {$sign_compare} {$current} 270 GROUP BY 271 pm.meta_value 272 ORDER BY 273 (pm.meta_value {$sign_modify} 1) {$sort_direction}, 274 pm.meta_value{$sort_direction} 275 LIMIT 1 276 "; 277 278 $target = (int) $wpdb->get_var($sql); 279 280 return array( 281 'sql' => $sql, 282 'target' => $target, 283 'factor' => $factor, 284 'result' => $target != 0 ? (bool) update_post_meta($post_id, POST_SORTER_META_KEY, $target) : false 285 ); 286 } 287 288 public function move_up($post_id) { 289 return $this->move($post_id, 'up'); 290 } 291 292 public function move_down($post_id) { 293 return $this->move($post_id); 294 } 295 296 297 298 /* == = = = = = = = = = = AJAX HANDLERS = = = = = = = = = = == */ 299 300 public function attach_on_save($post_id) { 301 $post_id = (int) $post_id; 302 303 if($post_id <= 0) 304 return; 305 306 if(defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE) 307 return; 308 309 if(!wp_verify_nonce( isset($_POST['post_sorter']) ? $_POST['post_sorter'] : '', plugin_basename( __FILE__ ) )) 310 return; 311 312 if(!current_user_can( 'edit_post', $post_id )) 313 return; 314 315 $position = $_POST['post_sorter_inline']; 316 317 if(is_array($position) && !empty($position)) 318 $position = $position[0]; 319 320 $position = (int) $position; 321 322 update_post_meta($post_id, POST_SORTER_META_KEY, $position); 323 } 324 325 public function move_post() { 326 $post_id = isset($_POST['post_id']) ? (int) $_POST['post_id'] : 0; 327 $direction = isset($_POST['direction']) && mb_strtolower($_POST['direction']) == 'up' ? 'up' : 'down'; 328 329 if($post_id <= 0) 330 die(json_encode( array( 'result' => '0', 'message' => __('Invalid post selected.', 'post_sorter') ) )); 331 332 $data = $this->move($post_id, $direction); 333 334 $result = new stdClass(); 335 336 if(is_array($data)) 337 foreach($data as $key => $value) 338 $result->$key = $value; 339 340 die(json_encode($result)); 341 } 342 16 /** 17 * Whether custom sorting is enabled 18 * @var bool 19 */ 20 private $_custom = FALSE; 21 22 public function __construct() { 23 $this->init(); 24 } 25 26 public function init() { 27 load_plugin_textdomain( 'post_sorter', FALSE, plugin_dir_path(__FILE__) . '/lang/' ); 28 29 add_filter( 'manage_posts_columns', array( $this, 'add_sorter_column' ) ); 30 add_filter( 'manage_pages_columns', array( $this, 'add_sorter_column' ) ); 31 32 add_action( 'manage_posts_custom_column', array( $this, 'show_sorter_column' ) ); 33 add_action( 'manage_pages_custom_column', array( $this, 'show_sorter_column' ) ); 34 35 add_filter( 'manage_edit-post_sortable_columns', array( $this, 'add_sorter_sort' ) ); 36 add_filter( 'manage_edit-page_sortable_columns', array( $this, 'add_sorter_sort' ) ); 37 38 39 //add_filter( 'request', array( $this, 'order_by_at_request' ) ); 40 41 add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) ); 42 add_action( 'save_post', array( $this, 'attach_on_save' ) ); 43 44 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); 45 46 add_action( 'wp_ajax_save_sort_position', array( $this, 'save_sort_position' ) ); 47 add_action( 'wp_ajax_move_sort_post', array( $this, 'move_post' ) ); 48 49 add_filter( 'posts_join', array( $this, 'join' ) ); 50 add_filter( 'posts_orderby', array( $this, 'order_by' ) ); 51 52 // Internal filters 53 add_filter( 'post_sorter_join', array( $this, 'internal_join' ) ); 54 add_filter( 'post_sorter_order', array( $this, 'internal_order' ) ); 55 56 /* == = = = = = = = = = = ADMIN STUFF = = = = = = = = = = == */ 57 58 if ( !is_admin() ) 59 return; 60 61 add_action( 'admin_menu', array( $this, 'add_menu' ) ); 62 add_action( 'admin_init', array( $this, 'register_settings' ) ); 63 } 64 65 /** 66 * Activation hook of the plugin 67 */ 68 public function activate() { 69 update_option( 'post_sorter_enabled', TRUE ); 70 update_option( 'post_sorter_direction', 'ASC' ); 71 72 $args = array( 73 'numberposts' => -1, 74 'post_type' => array( 'post', 'page' ), 75 'post_status' => array( 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash' ) 76 ); 77 78 $posts = get_posts( $args ); 79 80 foreach ( $posts as $post ) { 81 $current = get_post_meta( $post->ID, POST_SORTER_META_KEY, TRUE ); 82 83 if ($current || 0 === $current) 84 continue; 85 86 update_post_meta( $post->ID, POST_SORTER_META_KEY, 0 ); 87 } 88 } 89 90 /** 91 * Deactivation hook of the plugin 92 */ 93 public function deactivate() { 94 95 } 96 97 /** 98 * Enqueues scripts (JavaScripts) and CSS styles 99 * @return [type] [description] 100 */ 101 public function enqueue_scripts() { 102 wp_register_style( 'post_sorter', plugin_dir_url(__FILE__) . 'css/style.css' ); 103 wp_enqueue_style( 'post_sorter' ); 104 105 wp_enqueue_script( 'post_sorter', plugin_dir_url(__FILE__) . 'js/common.js' ); 106 } 107 108 /** 109 * Adds (registers) new column in the admin posts lists 110 * @param array $columns The columns to be rendered in the admin post lists 111 * @return array The columns to be rendered with added new column inside 112 */ 113 public function add_sorter_column( $columns ) { 114 $columns['sort'] = __( 'Sorting', 'post_sorter' ); 115 return $columns; 116 } 117 118 /** 119 * Handles the call for rendering a column and calls corresponding render method 120 * @param string $name A column name 121 */ 122 public function show_sorter_column( $name ) { 123 //global $post; 124 125 switch ( $name ) { 126 case 'sort': 127 $this->render_sort_cell(); 128 break; 129 } 130 } 131 132 /** 133 * Renders (outputs) the column html 134 */ 135 public function render_sort_cell() { 136 global $post; 137 138 $val = (int) get_post_meta( $post->ID, POST_SORTER_META_KEY, TRUE ); 139 140 if( $this->_custom ) { 141 echo '<div class="post_sorter">—</div>'; 142 return; 143 } 144 145 $html = '<div class="post_sorter">'; 146 147 if ( get_option( 'post_sorter_arrows_enabled' ) ) { 148 $html .= '<a href="#" title="' . __( 'Move this element up', 'post_sorter' ) . '" class="up icon_button" 149 onclick="post_sorter_moveUp(' . $post->ID . '); return false;"></a>'; 150 151 $html .= '<a href="#" title="' . __( 'Move this element down', 'post_sorter' ) . '" class="down icon_button" 152 onclick="post_sorter_moveDown(' . $post->ID . '); return false;"></a>'; 153 } 154 155 $html .= '<input name="post_sorter_inline[]" id="post_sorter_inline_' . $post->ID . '" type="text" value="' . $val . '" class="inline_field" 156 onkeyup="return post_sorter_saveOnKeyUp(event, this, ' . $post->ID . ')" onblur="post_sorter_save(this, ' . $post->ID . ')" />'; 157 158 $html .= '</div>'; 159 160 echo $html; 161 } 162 163 /** 164 * Adds (registers) new column in the admin posts lists as sortable one 165 * @param array $columns The sortable columns to be rendered in the admin post lists 166 * @return array The sortable columns to be rendered with added new column inside 167 */ 168 public function add_sorter_sort( $columns ) { 169 $columns['sort'] = 'sort'; 170 return $columns; 171 } 172 173 /** 174 * Handles ordering at request filter 175 * @deprecated This function is deprecated, use order_by (previously order_by_front) now, it handles actually both admin and front ordering 176 * @param array $vars Initial request variables 177 * @return array Filtered (altered) request variables 178 */ 179 public function order_by_at_request( $vars ) { 180 if ( !isset( $vars['orderby'] ) || 'sort' != $vars['orderby'] ) 181 return $vars; 182 183 $direction = mb_strtoupper( get_option( 'post_sorter_direction' ) ) == 'DESC' ? ' DESC' : ''; 184 185 $vars = array_merge( $vars, array( 186 'meta_key' => POST_SORTER_META_KEY, 187 'order_by' => 'CAST(meta_value_num AS INT)' . $direction 188 )); 189 190 return $vars; 191 } 192 193 /** 194 * Handles join part of the query built for retrieving posts 195 * @param string $sql Original join SQL 196 * @return strung Modified join SQL 197 */ 198 public function join( $sql ) { 199 global $wpdb; 200 201 // Plugin disabled - nothing to do 202 if ( !get_option( 'post_sorter_enabled' ) ) 203 return $sql; 204 205 // If we have some hooks apply them - other plugins, etc. 206 if( 2 <= $this->_count_filter_hooks( 'post_sorter_join' ) ) { 207 $this->_custom = TRUE; 208 $sql = apply_filters( 'post_sorter_join', $sql ); 209 return $sql; 210 } 211 212 $sql .= "INNER JOIN {$wpdb->postmeta} AS post_sorter ON ({$wpdb->posts}.ID = post_sorter.post_id AND post_sorter.meta_key = '" . POST_SORTER_META_KEY . "')"; 213 214 return $sql; 215 } 216 217 /** 218 * Handles ordering part of the query built for retrieving posts 219 * @param string $sql Original order by SQL 220 * @return strung Modified order by SQL 221 */ 222 public function order_by( $sql ) { 223 //global $wpdb; 224 225 // Plugin disabled - nothing to do 226 if ( !get_option('post_sorter_enabled') ) 227 return $sql; 228 229 // If we have some hooks apply them - other plugins, etc. 230 if( 2 <= $this->_count_filter_hooks( 'post_sorter_order' ) ) { 231 $this->_custom = TRUE; 232 $sql = apply_filters( 'post_sorter_order', $sql ); 233 return $sql; 234 } 235 236 $direction = mb_strtoupper( get_option( 'post_sorter_direction' ) ) == 'DESC' ? ' DESC' : ''; 237 238 return 'CAST(post_sorter.meta_value AS UNSIGNED)' . $direction . ( $sql ? ', ' . $sql : '' ); 239 } 240 241 242 /** 243 * Saves new position along with post save 244 */ 245 public function attach_on_save( $post_id ) { 246 $post_id = (int) $post_id; 247 248 if ( 0 >= $post_id ) 249 return; 250 251 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 252 return; 253 254 if ( !wp_verify_nonce( isset( $_POST['post_sorter'] ) ? $_POST['post_sorter'] : '', plugin_basename(__FILE__) ) ) 255 return; 256 257 if ( !current_user_can( 'edit_post', $post_id ) ) 258 return; 259 260 $position = $_POST['post_sorter_inline']; 261 262 if ( is_array( $position ) && !empty( $position ) ) 263 $position = $position[0]; 264 265 $position = (int) $position; 266 267 update_post_meta( $post_id, POST_SORTER_META_KEY, $position ); 268 } 269 270 /** 271 * Adds new menu in WordPress administration 272 */ 273 public function add_menu() { 274 add_menu_page( 'Post Sorter :: General', 'Post Sorter', 'administrator', 'page-sorter', array( $this, 'render_menu' ) ); 275 } 276 277 /** 278 * Renders (outputs) admin menu - display the page behind the menu 279 */ 280 public function render_menu() { 281 include( plugin_dir_path(__FILE__) . 'page/general.php' ); 282 } 283 284 public function register_settings() { 285 } 286 287 /** 288 * Save a position for a given post. Data for post ID and position is retrieved from $_POST 289 */ 290 public function save_sort_position() { 291 $post_id = (int) $_POST['post_id']; 292 $position = (int) $_POST['position']; 293 294 $this->save( $post_id, $position ); 295 } 296 297 /** 298 * Attaches the new metabox to WordPress (logically) 299 */ 300 public function add_meta_box() { 301 add_meta_box( 'post_sorter', __( 'Post Sorter', 'post_sorter' ), array( $this, 'render_meta_box' ), NULL, 'side', 'core' ); 302 } 303 304 /** 305 * Renders (outputs) metabox in WordPress edit screen 306 * @param WP_Post $post the post which is being edited 307 */ 308 public function render_meta_box($post) { 309 wp_nonce_field( plugin_basename( __FILE__ ), 'post_sorter' ); 310 311 $val = (int) get_post_meta( $post->ID, POST_SORTER_META_KEY, TRUE ); 312 313 if( $this->_custom ) { 314 echo '<div class="post_sorter">' . __( 'Custom sorting is enabled. Factor is ignored.', 'post_sorter' ) . '</div>'; 315 return; 316 } 317 318 $html = '<div class="post_sorter">'; 319 320 $html .= __('Position Factor', 'post_sorter') . ': '; 321 322 $html .= '<input name="post_sorter_inline[]" id="post_sorter_inline_' . $post->ID . '" type="text" value="' . $val . '" class="inline_field" 323 onkeyup="return post_sorter_saveOnKeyUp(event, this, ' . $post->ID . ');" onblur="post_sorter_save(this, ' . $post->ID . ')" />'; 324 325 $html .= '</div>'; 326 327 echo $html; 328 } 329 330 /** 331 * Performs checkup and cleanup of SQL commands for not proper commands (injections) 332 * @param string $sql The SQL which is built 333 * @return string The filtered (cleared) SQL 334 */ 335 private function _sanitize_sql($sql) { 336 $sql = str_ireplace( array( 'UNION', 'SELECT', 'FROM', 'DELETE FROM', 'LOCK ', 'GRANT ', 'DROP ', 'TRUNCATE TABLE', 'USE ', 'SHOW ' ), '', $sql ); // Dangerous statements 337 338 return $sql; 339 } 340 341 /** 342 * Saves settings for the plugin 343 */ 344 public function save_settings() { 345 if ( !current_user_can( 'manage_options' ) ) 346 return; 347 348 if ( empty( $_POST ) ) 349 return; 350 351 update_option( 'post_sorter_enabled', isset( $_POST['post_sorter_enabled'] ) ); 352 update_option( 353 'post_sorter_direction', isset( $_POST['post_sorter_direction'] ) && mb_strtoupper( $_POST['post_sorter_direction'] ) == 'DESC' ? 'DESC' : '' 354 ); 355 356 update_option( 'post_sorter_arrows_enabled', isset( $_POST['post_sorter_arrows_enabled'] ) ); 357 358 update_option( 'post_sorter_custom_enabled', isset( $_POST['post_sorter_custom_enabled'] ) ); 359 $own_risk = get_option( 'post_sorter_custom_enabled' ); 360 361 update_option( 'post_sorter_join_clause', $own_risk ? $this->_sanitize_sql( $_POST['post_sorter_join_clause'] ) : '' ); 362 update_option( 'post_sorter_order_by_clause', $own_risk ? $this->_sanitize_sql( $_POST['post_sorter_order_by_clause'] ) : '' ); 363 } 364 365 /** 366 * Performs a discrete, single-step movement of the post in the given direction 367 * @param int $post_id The ID of the post we are going to move 368 * @param string $direction The direction we are going to move to [up, down] 369 * @return mixed FALSE on failure, array with details on success 370 */ 371 private function _move( $post_id, $direction = 'down' ) { 372 global $wpdb; 373 374 $post_id = (int) $post_id; 375 376 if ( 0 >= $post_id ) 377 return FALSE; 378 379 $sort_direction = mb_strtoupper( get_option( 'post_sorter_direction' ) ) == 'DESC' ? ' DESC' : ''; 380 $current = (int) get_post_meta( $post_id, POST_SORTER_META_KEY, TRUE ); 381 382 $factor = (bool) $sort_direction ^ $direction == 'down'; 383 384 $sign_compare = $factor ? '>' : '<'; 385 $sign_modify = $factor ? '+' : '-'; 386 387 $post = get_post( $post_id ); 388 389 $sql = " 390 SELECT 391 pm.meta_value {$sign_modify} 1 392 FROM {$wpdb->posts} AS p 393 INNER JOIN {$wpdb->postmeta} AS pm ON (p.ID = pm.post_id AND pm.meta_key = '" . POST_SORTER_META_KEY . "') 394 WHERE 395 p.post_type = '{$post->post_type}' 396 AND 397 p.post_status = '{$post->post_status}' 398 AND 399 pm.meta_value {$sign_compare} {$current} 400 GROUP BY 401 pm.meta_value 402 ORDER BY 403 (pm.meta_value {$sign_modify} 1) {$sort_direction}, 404 pm.meta_value{$sort_direction} 405 LIMIT 1 406 "; 407 408 //echo $sql; 409 410 $target = (int) $wpdb->get_var( $sql ); 411 412 //print_r($target); 413 //exit; 414 415 return array( 416 //'sql' => $sql, 417 'target' => $target, 418 'factor' => $factor, 419 'result' => 0 != $target ? (bool) update_post_meta( $post_id, POST_SORTER_META_KEY, $target ) : FALSE 420 ); 421 } 422 423 /** 424 * Moves a post up with one step 425 * @param int $post_id The ID of the post to be moved 426 * @return mixed The result of _move with direction up 427 */ 428 public function move_up( $post_id ) { 429 return $this->_move( $post_id, 'up' ); 430 } 431 432 /** 433 * Moves a post down with one step 434 * @param int $post_id The ID of the post to be moved 435 * @return mixed The result of _move with direction down 436 */ 437 public function move_down( $post_id ) { 438 return $this->_move( $post_id ); 439 } 440 441 /** 442 * Counts attached hooks to a filter tag 443 * @param string $tag The filter tag to be count for hooks 444 * @return int The number of hooks attached to the fitlter 445 */ 446 private function _count_filter_hooks( $tag ){ 447 global $wp_filter; 448 449 if( !$tag || !isset( $wp_filter[$tag] ) ) 450 return 0; 451 452 return count( $wp_filter[$tag] ); 453 } 454 455 456 457 /* == = = = = = = = = = INERNAL FILTERS = = = = = = = = = = == */ 458 459 /** 460 * Internal hook for Post Sorter`s join filter tag 461 * @param string $sql Original join SQL 462 * @return string Modified join SQL 463 */ 464 public function internal_join( $sql ) { 465 if( !( $join = get_option( 'post_sorter_join_clause' ) ) ) 466 return $sql; 467 468 return $join . $sql; 469 } 470 471 /** 472 * Internal hook for Post Sorter`s order filter tag 473 * @param string $sql Original order by SQL 474 * @return string Modified order by SQL 475 */ 476 public function internal_order( $sql ) { 477 if( !( $orderby = get_option( 'post_sorter_order_by_clause' ) ) ) 478 return $sql; 479 480 return $orderby . ( $sql ? ', ' . $sql : '' ); 481 } 482 483 484 485 /* == = = = = = = = = = = AJAX HANDLERS = = = = = = = = = = == */ 486 487 /** 488 * AJAX save handler on post modification 489 * @param int $post_id The ID of the post which is modified 490 * @param int $position The new position to be assigned 491 */ 492 public function save( $post_id, $position ) { 493 $post_id = (int) $post_id; 494 $position = (int) $position; 495 496 if ( 0 >= $post_id || 0 == $position ) 497 return; 498 499 $result = new stdClass(); 500 501 $result->result = update_post_meta( $post_id, POST_SORTER_META_KEY, $position ); 502 503 if ( $result->result ) { 504 $result->post_id = $post_id; 505 $result->position = $position; 506 } 507 508 die( json_encode( $result ) ); 509 } 510 511 /** 512 * AJAX handler for post movment (arrows or other) 513 */ 514 public function move_post() { 515 $post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0; 516 $direction = isset( $_POST['direction'] ) && mb_strtolower( $_POST['direction'] ) == 'up' ? 'up' : 'down'; 517 518 if ( 0 >= $post_id ) 519 die( json_encode( array( 'result' => '0', 'message' => __( 'Invalid post selected.', 'post_sorter' ) ) ) ); 520 521 $data = $this->_move( $post_id, $direction ); 522 523 524 $result = new stdClass(); 525 526 //die( print_r( $data ) ); 527 528 if ( is_array( $data ) ) 529 foreach ( $data as $key => $value ) 530 $result->$key = $value; 531 532 533 die( json_encode( $result ) ); 534 } 535 343 536 } 344 537 538 // Assigning new object to variable in order to be easy usable from other parts of the system 345 539 $post_sorter = new PostSorter(); 346 540 347 if(!isset($post_sorter) || !is_object($post_sorter) || get_class($post_sorter) != 'PostSorter') 348 return; 349 350 register_activation_hook( __FILE__, array( $post_sorter, 'activate' ) ); 351 register_deactivation_hook( __FILE__, array( $post_sorter, 'deactivate' ) ); 352 541 if ( !isset( $post_sorter ) || !is_object( $post_sorter ) || 'PostSorter' != get_class( $post_sorter ) ) 542 return; 543 544 register_activation_hook( __FILE__ , array( $post_sorter, 'activate' ) ); 545 register_deactivation_hook( __FILE__ , array( $post_sorter, 'deactivate' ) ); 353 546 ?> -
post-sorter/trunk/readme.txt
r620250 r730151 5 5 Requires at least: 3.2 6 6 Tested up to: 3.4 7 Stable tag: 1. 07 Stable tag: 1.2 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 38 38 of creation (by default). Then if **Post 3** is newer than **Post 2** it will be up in both cases of sorting direction. 39 39 40 === Custom Sorting === 41 With the use of the expert settings and knowledge in SQL you could implement custom sorting. With such sorting the arrows will disappear, since they are no longer applicable. 42 40 43 == Installation == 41 44 … … 59 62 60 63 1. View of the plugin options page in the admin. See the newly added menu on the bottom left, in the navigator. 61 1. View of post list in the administration. We have a new column for easy sorting. 62 1. The screen of post edition - you could see the **metabox added with caption *Post Sorter***. 64 2. View of post list in the administration. We have a new column for easy sorting. 65 3. The screen of post edition - you could see the **metabox added with caption *Post Sorter***. 66 4. A screenshot of updated Post Sorter settings. 63 67 64 68 == Changelog == 69 70 = 1.2 = 71 * Fixed a ordering bug where the postmeta.meta_value is sorted as longtext, but not as unsigned int. 72 * Improvements of sorting. 73 * Up and down arrows for quick sorting now can be turned on or off from the options. 74 * New proxy filters added: **post_sorter_join** and **post_sorter_order**. External plugins may cooperate with this plugin using them. 75 * Expert settings added where the user may implement in SQL custom sorting (ordering). 76 * Several fixes and cleanup. 77 * Method order_by renamed to order_by_at_requst. 78 * Method order_by_front renamed to order_by. 79 * Method order_by_at_request is depricated. 65 80 66 81 = 1.0 = -
post-sorter/trunk/uninstall.php
r620244 r730151 1 1 <?php 2 2 // Prevents accidental unistall 3 if( !defined('WP_UNINSTALL_PLUGIN') || !WP_UNINSTALL_PLUGIN) exit;3 if( !defined( 'WP_UNINSTALL_PLUGIN' ) || !WP_UNINSTALL_PLUGIN ) exit; 4 4 5 delete_option( 'post_sorter_enabled');6 delete_option( 'post_sorter_direction');7 delete_option( 'post_sorter_metakey');5 delete_option( 'post_sorter_enabled' ); 6 delete_option( 'post_sorter_direction' ); 7 delete_option( 'post_sorter_metakey' ); 8 8 9 delete_post_meta_by_key('post_sorter_order'); 9 delete_option( 'post_sorter_arrows_enabled' ); 10 11 delete_option( 'post_sorter_custom_enabled' ); 12 delete_option( 'post_sorter_join_clause' ); 13 delete_option( 'post_sorter_order_by_clause' ); 14 15 delete_post_meta_by_key( 'post_sorter_order' ); 10 16 ?>
Note: See TracChangeset
for help on using the changeset viewer.