Files
doitinpoland.com/wp-content/plugins/sitepress-multilingual-cms/classes/url-handling/class-wpml-score-hierarchy.php
2023-09-12 21:41:04 +02:00

140 lines
3.3 KiB
PHP

<?php
class WPML_Score_Hierarchy {
private $data = array();
private $slugs = array();
/**
* WPML_Score_Hierarchy constructor.
*
* @param object[] $data_set
* @param string[] $slugs
*/
public function __construct( $data_set, $slugs ) {
$this->data = $data_set;
$this->slugs = $slugs;
}
/**
* Array of best matched post_ids. Better matches have a lower index!
*
* @return int[]
*/
public function get_possible_ids_ordered() {
$pages_with_name = $this->data;
$slugs = $this->slugs;
$parent_slugs = array_slice( $slugs, 0, - 1 );
foreach ( $this->data as $key => $page ) {
if ( $page->parent_name ) {
$slug_pos = array_keys( $slugs, $page->post_name, true );
$par_slug_pos = array_keys( $slugs, $page->parent_name, true );
if ( (bool) $par_slug_pos !== false
&& (bool) $slug_pos !== false
) {
$remove = true;
foreach ( $slug_pos as $child_slug_pos ) {
if ( in_array( $child_slug_pos - 1, $par_slug_pos ) ) {
$remove = false;
break;
}
}
if ( $remove === true ) {
unset( $pages_with_name[ $key ] );
}
}
}
}
$related_ids = array();
$matching_ids = array();
foreach ( $pages_with_name as $key => $page ) {
$correct_slug = end( $slugs );
if ( $page->post_name === $correct_slug ) {
if ( $this->is_exactly_matching_all_slugs_in_order( $page ) ) {
$matching_ids[] = (int) $page->ID;
} else {
$related_ids[ $page->ID ] = $this->calculate_score( $parent_slugs, $pages_with_name, $page );
}
}
}
arsort( $related_ids );
$related_ids = array_keys( $related_ids );
return array(
'matching_ids' => $matching_ids,
'related_ids' => $related_ids,
);
}
/**
* Get page object by its id.
*
* @param int $id
*
* @return false|object
*/
private function get_page_by_id( $id ) {
foreach ( $this->data as $page ) {
if ( (int) $page->ID === (int) $id ) {
return $page;
}
}
return false;
}
/**
* @param string[] $parent_slugs
* @param object[] $pages_with_name
* @param object $page
*
* @return int
*/
private function calculate_score( $parent_slugs, $pages_with_name, $page ) {
$parent_positions = array_keys( $parent_slugs, $page->parent_name, true );
$new_score = (bool) $parent_positions === true ? max( $parent_positions ) + 1 : ( $page->post_parent ? - 1 : 0 );
if ( $page->post_parent ) {
foreach ( $pages_with_name as $parent ) {
if ( $parent->ID == $page->post_parent ) {
$new_score += $this->calculate_score( array_slice( $parent_slugs, 0, count( $parent_slugs ) - 1 ), $pages_with_name, $parent );
break;
}
}
}
return $new_score;
}
/**
* @param stdClass $page
*
* @return bool
*/
private function is_exactly_matching_all_slugs_in_order( $page ) {
return $this->slugs === $this->get_slugs_for_page( $page );
}
/**
* @param stdClass $current_page
*
* @return array
*/
private function get_slugs_for_page( $current_page ) {
$slugs = array();
while ( $current_page && $current_page->post_name ) {
$slugs[] = $current_page->post_name;
$parent_name = $current_page->parent_name;
$current_page = $this->get_page_by_id( $current_page->post_parent );
if ( ! $current_page && $parent_name ) {
$slugs[] = $parent_name;
}
}
return array_reverse( $slugs );
}
}