如何对页面进行整体重新排序

时间:2017-07-08 作者:LordTakason

我正在工作的网站有几千页,每一页都是地址列表。我需要它们按a)街道名称和b)地址编号排序。我可以逐个检查并更改顺序#但在第一个100个之后就过时了,我还有9000多个任务要完成。

有没有办法快速按特定的顺序对它们进行排序?

编辑:尝试在前端和后端对订单进行排序。

1 个回复
最合适的回答,由SO网友:hwl 整理而成

首先,设置排序算法的方法取决于这些街道名称和地址号码存储的位置/方式。a中的单线meta_key, 两个独立的meta_key 由于某种原因等输入内容

OP正在处理存储为的地址post_title 价值观因此,以下假设为字符串:

主街1234号

其余部分,匹配和更新页面menu_order 关键相当简单。

也许是这样一个过程:

来自init 挂钩:

[order_pages_by_values()]

获取页面对象数组:

[$pages = get_pages_wrapper();]

对于每个页面对象,将ID传递给获取数字/街道值的函数:

(1)[$addresses = extract_and_conflate_address( $pages );]

(2)[$number = get_address_number( $page->ID );]

(3)[$street = get_address_street( $page->ID );]

4) [
$split = explode( \' \', $address, 2 ); if ( $value === \'number\' ) { $return = $split[0]; } elseif ( $value === \'street\' ) { $return = $split[1]; }]

将数字和街道值添加到数组中key => value, i、 e。numeric => street:

[$address_k_v[$number] = $street;]

对该数组的值和键进行排序,然后创建多维数组street => array ( numeric, )

(1)[$flatten_array = sort_values_and_keys_and_flatten( $addresses )]

(2)[

foreach( $array as $n => $s ) {


    if ( array_key_exists( $s, $multi_array ) ) {
        $multi_array[$s][] = $n;
    }
    else {
         $multi_array[$s] = array( $n );
     }
  }
]

street 外部数组的键,然后针对每个street, 对内部数值数组排序

(1)[ksort($multi_array);]

(2)[foreach ($multi_array as $street => $numbers_array ) { asort($numbers_array);]

  • (现在已排序)number => street 输入,使其成为字符串number-street, 并将其添加到新阵列中

    每个(现在已排序)street => array ( numeric ) (内部数组),添加字符串number-street 到新阵列:

    [foreach( $numbers_array as $na ) { $flatten_array[] = $na .\'-\'. $street;]

    对于每个页面对象,再次获取数字和街道,这次使用它们创建字符串numberic-street:

    $number = get_address_number( $page->ID );
    $street = get_address_street( $page->ID ); 
    
    $match_string = $number . \'-\' . $street;`
    
    搜索排序的数组numberic-street 此的字符串numberic-street 字符串,返回要设置的索引号$menu_order:

    [$menu_order = array_search( $match_string, $flatten_array );]

    使用创建post的参数数组ID => page->IDmenu_order => index number:

    $update_post_args = array( \'ID\'         => $page->ID,
                               \'menu_order\' => $menu_order
                            );
    
    用这些参数更新帖子:

    [wp_update_post( $update_post_args )]

    如果没有这些地址字段的存储位置,就无法猜测解决方案,但我已经介绍了一种可能的方法,使用explode 在…上post_title 以防这是你当前噩梦的一部分

    下面只是一个可能的过程的示例,当然,在全面测试之前先对其进行测试。我可能会将其全部封装在一个插件类中。

    add_action( \'init\', \'order_pages_by_values\' );
    
    
    function get_pages_wrapper() {
        $args = array( \'post_type\'   => \'page\',
                       \'post_status\' => \'publish\'
                     );
        $pages = get_pages( $args );
    
        return $pages;
    }
    
    
    function extract_and_conflate_address( $pages ) {
        foreach ( $pages as $page ) {
            $number = get_address_number( $page->ID ); //depends on where value is stored
            $street = get_address_street( $page->ID ); //depends on where value is store
    
            $address_k_v[$number] = $street;
       }
       return $address_k_v;
    }
    //old version, several issues with this.
     // First, it is more of a re-sort, ignoring previously sorted items.
     /// Second, it cannot preserve instances where same post box address (1234) for different street would overwrite previous entry.
     /* function sort_values_and_keys( &$array, $valrev = false, $keyrev = false ) {
        //adopted from http://php.net/manual/en/function.asort.php#80798
        if ( $valrev ) { 
    
            arsort( $array );
    
        } else { 
    
            asort( $array );
    
        }
    
        $vals   = array_count_values( $array );
        $i      = 0;
    
        foreach ( $vals AS $val => $num ) {
    
            $first = array_splice( $array, 0, $i );
    
            $tmp   = array_splice( $array, 0, $num );
    
            if ( $keyrev ) { 
    
                krsort( $tmp ); 
    
            } else { 
    
                ksort( $tmp ); 
            }
    
            $array  = array_merge( $first, $tmp, $array );
    
            unset( $tmp );
    
            $i      = $num;
        }
    } */
    
    //Here we are creating a multidimensional array with the outer being Street
    // and inner being an array of corresponding numerical post addresses.
    
    function sort_values_and_keys_and_flatten( $array ) {
        //need array declared already for conditional inside foreach   
        $multi_array = array(); 
    
        foreach( $array as $n => $s ) {
    
           //makes sure Street doesn\'t exist yet. If it does, append, if not add.
            if ( array_key_exists( $s, $multi_array ) ) {
                $multi_array[$s][] = $n;
            }
            else {
                 $multi_array[$s] = array( $n );
             }
        }
    
        //sort the street names
        ksort($multi_array);
    
        foreach ($multi_array as $street => $numbers_array ) {
    
            //sort the numerical addresses
            asort($numbers_array);
    
            //build $flatten_array
            foreach( $numbers_array as $na ) {
    
                $flatten_array[] = $na .\'-\'. $street;
            }
        }
    
        return $flatten_array;
     }
    
    
    
    function order_pages_by_values() {
    
        $pages     = get_pages_wrapper();
    
        $addresses = extract_and_conflate_address( $pages );
    
       /**
         Replacing these lines with new sort function and setting $flatten to its return
        sort_values_and_keys( $addresses );
    
        foreach ( $addresses as $number => $street ) {
    
            $flatten_array[] = $number . \'-\' . $street;
        }
      */
    
        $flatten_array = sort_values_and_keys_and_flatten( $addresses );         
    
        foreach ( $pages as $page ) {
    
            $number = get_address_number( $page->ID ); //depends on where value is stored
            $street = get_address_street( $page->ID ); //depends on where value is stored
    
            $match_string = $number . \'-\' . $street;
    
            $menu_order = array_search( $match_string, $flatten_array );
    
            $update_post_args = array( \'ID\'         => $page->ID,
                                       \'menu_order\' => $menu_order
                                    );
    
            wp_update_post( $update_post_args );
        }
    
    }
    
    function get_address_number( $id ) {
        //assuming post_meta key of \'address_number\'
        //$number = get_post_meta( $id, \'address_number\', true ); 
    
        //assuming all addresses have format 1234 Main Street and saved as post title
        $number = extract_address( get_the_title( $id ), \'number\' );
        return $number;
    }
    function get_address_street( $id ) {
        //assumes post_meta key of \'address_street\'
        //$street = get_post_meta( $id, \'address_street\', true ); 
    
        //assuming all addresses have format 1234 Main Street and saved as post title
        $street = extract_address( get_the_title( $id ), \'street\' );
        return $street;
    }
    function extract_address( $address, $value ) {
    
        $split = explode( \' \', $address, 2 );
        if ( $value === \'number\' ) {
            $return = $split[0];
        }
        elseif ( $value === \'street\' ) {
            $return = $split[1];
        }
    
        return $return;
    }
    
    更新我更新了上面的代码块,但下面是排序函数的快速测试示例。我说不出它有多经济,但它在我这边起作用了。因为它正在返回$flatten_array 在上一个版本中,请注意,我已经从order_pages_by_value()

    Here is the testable code sample for the sort:

    //array as would be returned by extract_and_conflate_addresses()
    $the_array = array( 
                \'1234\'      => \'Main Street\',
                \'100\'       => \'Avenue Road\',
                \'105\'       => \'Avenue Road\',
                \'106\'       => \'Avenue Road\',
                \'106a\'      => \'Avenue Road\',
                \'107\'       => \'Avenue Road\',
                \'103\'       => \'Front Street\',
                \'42\'        => \'5 Lane\',
                \'42000\'     => \'B Street\',
        );
    
    
    function sort_values_and_keys_and_flatten( $array ) {
    
        //need array declared already for conditional inside foreach   
        $multi_array = array(); 
    
        foreach( $array as $n => $s ) {
    
            //makes sure Street doesn\'t exist yet. If it does, append, if not add.
            if ( array_key_exists( $s, $multi_array ) ) {
                $multi_array[$s][] = $n;
    
            }
            else {
                 $multi_array[$s] = array( $n );
             }
    
        }
    
        //sort the street names
        ksort($multi_array);
    
        foreach ($multi_array as $street => $numbers_array ) {
    
            //sort the numerical addresses
            asort($numbers_array);
    
            //build $flatten_array
            foreach( $numbers_array as $na ) {
    
                $flatten_array[] = $na .\'-\'. $street;
            }
    
        }
    
        return $flatten_array;
    
    }
    
    $test = sort_values_and_keys_and_flatten( $the_array );
    print_r($test);
    

    That should yield:

    Array
    (
        [0] => 42-5 Lane
        [1] => 100-Avenue Road
        [2] => 105-Avenue Road
        [3] => 106-Avenue Road
        [4] => 106a-Avenue Road
        [5] => 107-Avenue Road
        [6] => 42000-B Street
        [7] => 103-Front Street
        [8] => 1234-Main Street
    )
    

  • 结束