Как работает этот кусок кода с сортировкой SplHeap?

Есть такой скрипт, который позволяет получать позицию поста из всей выборки бд (Wordpress):
Код
class SharesHeap extends SplHeap {  
      public function compare( $post1, $post2 ) {
        $key = Custom_Rating_Query::$key;
        if ( ! $post1 instanceof WP_Post || ! isset( $post1->$key ) ) return 0;
        if ( ! $post2 instanceof WP_Post || ! isset( $post2->$key ) ) return 0;
        return (int)$post2->$key - (int) $post1->$key;
      }
    }

    class Custom_Rating_Query extends WP_Query {

      public static $key = 'custom_rating'; // change the metakey here, if needed
      protected static $args = array( 'nopaging' => TRUE ); // get all posts

      public function __construct( $cat = NULL, $post_type = 'post' ) {
        if ( is_object($cat) && isset($cat->term_id) ) $cat = $cat->term_id;
        $cat_field = is_numeric($cat) ? 'cat' : 'category_name';
        self::$args['post_type'] = ! empty( $post_type ) ? $post_type : 'post';
        self::$args[$cat_field] = $cat;
        parent::__construct( self::$args );
      }

      public function get_posts() {
        add_filter('posts_clauses', array(__CLASS__, 'my_filters') );
        add_filter( 'posts_orderby', array(__CLASS__, 'my_posts_orderby'));
        add_filter( 'posts_groupby', array(__CLASS__, 'groupby'));
        $results = parent::get_posts();
        remove_filter('posts_clauses', array(__CLASS__, 'my_filters') );
        remove_filter( 'posts_orderby', array(__CLASS__, 'my_posts_orderby'));
        remove_filter( 'posts_groupby', array(__CLASS__, 'groupby'));
        return $results;
      }
      public static function my_posts_orderby($orderby) {
          global $wpdb;
          $orderby = "wp_postmeta.meta_value DESC";
          return $orderby;
      }
      public static function groupby($groupby) {
          global $wpdb;
          $groupby = "wp_postmeta.meta_value";
          return $groupby;
      }
      public static function my_filters( $pieces ) {
        $key = self::$key;
        $meta = $GLOBALS['wpdb']->postmeta;
        $posts = $GLOBALS['wpdb']->posts;
        $pieces['fields'] .= ", {$meta}.meta_value as {$key}";
        $pieces['join'] .= "INNER JOIN {$meta} ON ({$posts}.ID = {$meta}.post_id)";
        $where = " AND ( {$meta}.meta_key = '{$key}' AND ";
        $where .= " CAST( {$meta}.meta_value AS SIGNED ) > 0 )";
        $pieces['where'] .= $where;
        return $pieces;
      }
    }

    class Custom_Rating_Order {

      protected $heap;
      protected $posts;

      public function __construct( SplHeap $heap )  {
        $this->heap =  $heap;
      }

      public function getOrder( WP_Post $post = NULL ) {
        if ( ! $this->posts instanceof ArrayIterator ) return -1;
        if ( ! isset( $post->ID ) ) return FALSE; 
        while( $this->posts->valid() ) {
          $this->heap->insert( $this->posts->current() );
          $this->posts->next();
        }
        echo '<pre>';
        print_r($this->heap);
        echo '</pre>';
        $position = 0;
        while( $this->heap->valid() ) {
          $current = $this->heap->extract();
          echo $position;
          echo '<br/>';
          echo '<pre>';
          print_r($current->custom_rating);
          echo '</pre>';
          if ( $current->ID == $post->ID ) return $position + 1;
          $position++;
        }
        return FALSE;
      }

      public function getPosts( WP_Query $query ) {
        if ( $query->post_count > 0) $this->posts = new ArrayIterator( $query->posts );
      }
    }


    /**
     * Ordering post position.
     */
    function getCustom_Rating_Order( $post, $cat ) {
      if ( is_object($post) && isset( $post->ID ) ) $post = $post->ID;
      if ( ! is_numeric($post) || ! (int) $post > 0 ) return FALSE;
      if ( ! has_category($cat, $post) ) return FALSE;
      $order = new Custom_Rating_Order( new SharesHeap );
      $order->getPosts( new Custom_Rating_Query( $cat ) );
      $test = $order->getPosts( new Custom_Rating_Query( $cat ) );

      return $order->getOrder( get_post( $post ) );

    }
    function test() {
      $array = new Custom_Rating_Query( $cat );
      print_r($array->posts);

    }
?>



Я не могу понять как вообще работает метод getOrder да и сам SplHeap, так как я сортирую все свои посты по доп полю (по рейтингу). В метод getOrder передается весь отсортированный объект с постами, и вот дальше работа этого метода мне не ясна вообще. По идее, мне нужно чтобы мы проходили по всему объекту и как только дойдем до нужно нам поста (в методе if ( $current->ID == $post->ID )
мы вывели его номер и все). Однако для каждого поста в отдельности (на самой его странице мы запускаем функцию, куда передаем id поста и категорию для выборки), $this->heap у меня всегда разный (если его выводить, что я в методе и сделал, посты всегда по-разному отсортированы). Почему так происходит и по какому принципу эта сортировка производится?
  • Вопрос задан
  • 54 просмотра
Пригласить эксперта
Ответы на вопрос 1
IceRD
@IceRD
в абстрактной куче сортировка происходит на основе метода compare
Примеры тут php.net/manual/ru/class.splheap.php

в текущей ситуации
public function compare( $post1, $post2 ) {
        $key = Custom_Rating_Query::$key;
        if ( ! $post1 instanceof WP_Post || ! isset( $post1->$key ) ) return 0;
        if ( ! $post2 instanceof WP_Post || ! isset( $post2->$key ) ) return 0;
        return (int)$post2->$key - (int) $post1->$key;
  }

функция принимает 2 значения, проверяет их наличие.
далее, преобразует в integer и возвращает результат.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы