Plugin Directory

Changeset 730151


Ignore:
Timestamp:
06/23/2013 12:36:31 AM (13 years ago)
Author:
rolice
Message:

v1.2

  • Fixed a ordering bug where the postmeta.meta_value is sorted as longtext, but not as unsigned int.
  • Improvements of sorting.
  • Up and down arrows for quick sorting now can be turned on or off from the options.
  • New proxy filters added: post_sorter_join and post_sorter_order. External plugins may cooperate with this plugin using them.
  • Expert settings added where the user may implement in SQL custom sorting (ordering).
  • Several fixes and cleanup.
  • Method order_by renamed to order_by_at_requst.
  • Method order_by_front renamed to order_by.
  • Method order_by_at_request is depricated.
Location:
post-sorter
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • post-sorter/trunk/css/style.css

    r620244 r730151  
    2828    margin-right: 16px;
    2929}
     30
     31.post_sorter_form textarea {}
     32.post_sorter_form textarea[readonly="readonly"] { background-color: #eee; }
  • post-sorter/trunk/js/common.js

    r620244 r730151  
    5656
    5757function post_sorter_onMove(res) {
    58     //window.location.href = window.location;
     58    window.location.href = window.location;
    5959}
  • post-sorter/trunk/page/general.php

    r620244 r730151  
    22    global $post_sorter;
    33
    4     if(!empty($_POST))
     4    if( !empty( $_POST ) )
    55        $post_sorter->save_settings();
    66?>
     
    1212   
    1313    <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>
    1843       
    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">&nbsp;</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>
    22115    </form>
    23116</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  
    44  Plugin URI: http://intellisys.org/
    55  Description: Plugin for easy sorting of posts and pages by numeric value, both ascending and descending.
    6   Version: 1.0
     6  Version: 1.2
    77  Author: Lyubomir Gardev
    88  Author URI: http://rolice.intellisys.info/
    99  Text Domain: post_sorter
    1010  License: GPLv2 or later
    11 */
    12 
    13 define('POST_SORTER_META_KEY',                      'post_sorter_order');
     11 */
     12
     13define( 'POST_SORTER_META_KEY', 'post_sorter_order' );
    1414
    1515class 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
    343536}
    344537
     538// Assigning new object to variable in order to be easy usable from other parts of the system
    345539$post_sorter = new PostSorter();
    346540
    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 
     541if ( !isset( $post_sorter ) || !is_object( $post_sorter ) || 'PostSorter' != get_class( $post_sorter ) )
     542    return;
     543
     544register_activation_hook( __FILE__ , array( $post_sorter, 'activate' ) );
     545register_deactivation_hook( __FILE__ , array( $post_sorter, 'deactivate' ) );
    353546?>
  • post-sorter/trunk/readme.txt

    r620250 r730151  
    55Requires at least: 3.2
    66Tested up to: 3.4
    7 Stable tag: 1.0
     7Stable tag: 1.2
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    3838of creation (by default). Then if **Post 3** is newer than **Post 2** it will be up in both cases of sorting direction.
    3939
     40=== Custom Sorting ===
     41With 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
    4043== Installation ==
    4144
     
    5962
    60631. 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***.
     642. View of post list in the administration. We have a new column for easy sorting.
     653. The screen of post edition - you could see the **metabox added with caption *Post Sorter***.
     664. A screenshot of updated Post Sorter settings.
    6367
    6468== 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.
    6580
    6681= 1.0 =
  • post-sorter/trunk/uninstall.php

    r620244 r730151  
    11<?php
    22// Prevents accidental unistall
    3 if(!defined('WP_UNINSTALL_PLUGIN') || !WP_UNINSTALL_PLUGIN) exit;
     3if( !defined( 'WP_UNINSTALL_PLUGIN' ) || !WP_UNINSTALL_PLUGIN ) exit;
    44
    5 delete_option('post_sorter_enabled');
    6 delete_option('post_sorter_direction');
    7 delete_option('post_sorter_metakey');
     5delete_option( 'post_sorter_enabled' );
     6delete_option( 'post_sorter_direction' );
     7delete_option( 'post_sorter_metakey' );
    88
    9 delete_post_meta_by_key('post_sorter_order');
     9delete_option( 'post_sorter_arrows_enabled' );
     10
     11delete_option( 'post_sorter_custom_enabled' );
     12delete_option( 'post_sorter_join_clause' );
     13delete_option( 'post_sorter_order_by_clause' );
     14
     15delete_post_meta_by_key( 'post_sorter_order' );
    1016?>
Note: See TracChangeset for help on using the changeset viewer.