【问题标题】:Sorting custom taxonomy column saved as serialized array对保存为序列化数组的自定义分类列进行排序
【发布时间】:2016-11-03 23:00:16
【问题描述】:

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

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

我使用 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 尝试将值转为整数。

现在,当我单击列对其进行排序时,什么也没有发生。

是否可以对这个乱七八糟的东西进行排序(序列化数组)?

【问题讨论】:

    标签: php mysql wordpress sorting serialization


    【解决方案1】:

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

    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 钩子。添加术语元的功能也如下所示:

    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 ;
    
        }
    }
    

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

    因为我在这里使用整数值,所以我不得不使用ABS()。我尝试使用CAST(tm.meta_value AS int),但出现错误,ABS() 有效。唯一的“坏事”是您不能使用负整数,因为绝对值会将其转换为正整数,但解决方法是您不要使用负值:D

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

    希望这对偶然发现这个问题的人有所帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-10
      • 2017-07-05
      • 2012-05-10
      • 1970-01-01
      • 2013-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多