将自定义分类列排序保存为序列化数组

时间:2016-07-01 13:40:48

标签: php mysql wordpress sorting serialization

我试图按照通常的方法在分类法中对我的自定义列进行排序,但后来我注意到该值作为序列化数组存储在我的选项表中,并且......复杂的事情。

我使用knowledgebase分类法创建了knowledgebase_category自定义帖子类型。

我使用knowledgebase_category_edit_form_fieldsknowledgebase_category_add_form_fields挂钩添加了类别订单字段,并使用

保存
add_action ( 'edited_knowledgebase_category', 'mytheme_save_extra_knowledgebase_category_fileds');
add_action ( 'created_knowledgebase_category', 'mytheme_save_extra_knowledgebase_category_fileds');

if ( ! function_exists( 'mytheme_save_extra_knowledgebase_category_fileds' ) ){
    function mytheme_save_extra_knowledgebase_category_fileds( $term_id ) {
        if ( isset( $_POST['Cat_meta'] ) ) {
            $t_id = $term_id;
            $cat_meta = get_option( "category_$t_id");
            $cat_keys = array_keys($_POST['Cat_meta']);
            foreach ($cat_keys as $key){
                if(isset($_POST['Cat_meta'][$key])){
                    $cat_meta[$key] = $_POST['Cat_meta'][$key];
                }
            }
            update_option( "category_$t_id", $cat_meta );
        }
    }
}

这将值存储为序列化数组。 options表中的值看起来像这样

a:1:{s:9:"cat_order";s:1:"3";}
a:1:{s:9:"cat_order";s:2:"34";}
a:1:{s:9:"cat_order";s:1:"8";}
a:1:{s:9:"cat_order";s:2:"21";}
a:1:{s:9:"cat_order";s:2:"67";}
a:1:{s:9:"cat_order";s:1:"6";}

因此排序很棘手。

我制作了我的专栏并使其可以排序

add_filter('manage_edit-knowledgebase_category_columns', 'mytheme_cat_order_column', 10, 2);

if (!function_exists('mytheme_cat_order_column')) {
    function mytheme_cat_order_column( $cat_columns ){
        $cat_columns['cat_order'] = esc_attr__('Category Order', 'mytheme');
        return $cat_columns;
    }
}


add_filter ('manage_knowledgebase_category_custom_column', 'mytheme_manage_knowledgebase_category_custom_fields', 10,3);

if (!function_exists('mytheme_manage_knowledgebase_category_custom_fields')) {
    function mytheme_manage_knowledgebase_category_custom_fields($deprecated, $column_name, $term_id){
        if ($column_name == 'cat_order') {
            $cat_meta = get_option( "category_$term_id");
            if (isset($cat_meta['cat_order']) && $cat_meta['cat_order'] != '') {
               echo intval($cat_meta['cat_order']);
            }
        }
    }
}


add_filter('manage_edit-knowledgebase_category_sortable_columns', 'mytheme_manage_knowledgebase_category_sortable_columns');

if(!function_exists('mytheme_manage_knowledgebase_category_sortable_columns')){
    function mytheme_manage_knowledgebase_category_sortable_columns($columns){
        $columns['cat_order'] = esc_attr__('Category Order', 'mytheme');
        return $columns;
    }
}

我尝试使用此

对其进行排序
add_filter( 'terms_clauses', 'mytheme_cat_order_orderby', 10, 3 );

if (!function_exists('mytheme_cat_order_orderby')) {
    function mytheme_cat_order_orderby( $pieces, $taxonomies, $args ) {

        $orderby = isset($_REQUEST['orderby']) ? trim(wp_unslash($_REQUEST['orderby'])) : 'Category Order';
        $order   = isset($_REQUEST['order'])   ? trim(wp_unslash($_REQUEST['order']))   : 'DESC';
        $trm = '"';

        if($orderby == 'Category Order' ) {
            $pieces['join']   .= " INNER JOIN wp_options AS opt ON opt.option_name = concat('category_',t.term_id)";
            $pieces['orderby'] = "ORDER BY CAST( ( SUBSTRING_INDEX( SUBSTRING_INDEX( opt.option_value,';',2 ),':',-1 ) ) AS UNSIGNED)";
            $pieces['order']   = $order;
        }

        return $pieces;

    }
}

现在我试着看看查询应该返回什么而不强制转换

SUBSTRING_INDEX( SUBSTRING_INDEX( opt.option_value,';',2 ),':',-1 )

部分,但是我收到了一个错误,这可能是因为我的号码周围有""(我通过使用this question作为参考并在php中测试它得出的结论)。所以我使用CAST来尝试将值转换为整数。

现在,当我点击列进行排序时,没有任何反应。

是否可以对此混乱(序列化数组)进行排序?

1 个答案:

答案 0 :(得分:1)

我意识到自从WordPress 4.4发布以来,有一个术语元。所以我将代码更改为更新,并在术语元中设置附加字段,如下所示:

add_action ( 'created_knowledgebase_category', 'mytheme_save_extra_knowledgebase_category_fileds');

if ( ! function_exists( 'mytheme_save_extra_knowledgebase_category_fileds' ) ){
    function mytheme_save_extra_knowledgebase_category_fileds( $term_id ) {
        if ( isset( $_POST['cat_order'] ) ) {
            $cat_order = intval($_POST['cat_order']);
            add_term_meta( $term_id, 'cat_order', $cat_order, true );
        }
    }
}

同样,我修改了edited_knowledgebase_category钩子。此外,添加术语meta的功能如下所示:

add_action ( 'knowledgebase_category_edit_form_fields', 'mytheme_extra_knowledgebase_category_fields');

if ( ! function_exists( 'mytheme_extra_knowledgebase_category_fields' ) ){
    function mytheme_extra_knowledgebase_category_fields( $term ) {
        $cat_order = get_term_meta( $term->term_id, 'cat_order', true );
        ?>
        <tr class="form-field">
            <th scope="row" valign="top"><label for="cat_order"><?php esc_attr_e('Category order', 'mytheme'); ?></label></th>
            <td><input type="text" name="cat_order" for="cat_order" id="cat_order" value="<?php echo intval($cat_order); ?>"></td>
        </tr>
    <?php
    }
}

因为我从termmeta表中提取信息。当您创建新字段时,只需将输入留空(因为当您创建它时它应该为空 - 这在选择的情况下是不同的 - 查看here以获取更多信息这一点)。

现在,因为我有一个明确的数据要排序,我更新了我的可排序列,因此它排序的名称只是cat_order(为了简单起见)

add_filter('manage_edit-knowledgebase_category_sortable_columns', 'mytheme_manage_knowledgebase_category_sortable_columns');

if(!function_exists('mytheme_manage_knowledgebase_category_sortable_columns')){
    function mytheme_manage_knowledgebase_category_sortable_columns($sortable){
        $sortable['cat_order'] = 'cat_order';
        return $sortable;
    }
}

然后排序非常简单:

/**
 * Custom column sortable query
 *
 * @param array $pieces     Terms query SQL clauses.
 * @param array $taxonomies An array of taxonomies.
 * @param array $args       An array of terms query arguments.
 * @return string           Modified query
 * @since   1.0.0
 */

add_filter( 'terms_clauses', 'mytheme_filter_custom_terms', 10, 3 );

if (!function_exists('mytheme_filter_custom_terms')) {
    function mytheme_filter_custom_terms( $pieces, $taxonomies, $args ) {

        global $wpdb;

        $orderby = isset($_REQUEST['orderby']) ? trim(wp_unslash($_REQUEST['orderby'])) : 'cat_order';
        $order   = isset($_REQUEST['order'])   ? trim(wp_unslash($_REQUEST['order']))   : 'DESC';

        if($orderby == 'cat_order' ) {
            $pieces['fields']   .= ", tm.*";
            $pieces['join']   .= " INNER JOIN {$wpdb->termmeta} AS tm ON tt.term_id = tm.term_id";
            $pieces['orderby'] = "ORDER BY ABS(tm.meta_value)";
        }

        return $pieces ;

    }
}

首先,检查您是否按照自己创建的新列进行排序,然后需要在SELECT数组的$pieces['fields']部分中添加新字段,然后使用正确的termmeta加入term_id表,然后按meta_value排序。

由于我在这里使用整数值,我必须使用ABS()。我尝试使用CAST(tm.meta_value AS int)但我收到了错误,ABS()有效。唯一的坏事&#39;关于这个是你不能使用负整数,因为绝对值会把它变成正整数,但解决方法是你不要使用负值:D

这是您可以对包含整数值的列进行排序的方法,对于您更改orderby部分的其他值,但要点是相同的,并且最好存储分类法元值在termmeta表中,而在选项表中作为序列化数组。首先,它没有序列化,第二,当你从分类中删除你的术语时它会被删除;)

希望这有助于有人绊倒这个问题:)