Files
ogre-sort/inc/class-sort.php
Cooper Dalrymple 4b2e3194be Initial commit
2025-11-18 16:56:26 -06:00

874 lines
35 KiB
PHP

<?php
/**
* @package ogre-sort
* @author cleverogre
* @version 1.0.0
* @since 1.0.0
*/
namespace Ogre\Sort;
use Ogre\Singleton;
use Ogre\Sort as Plugin;
if (!defined('ABSPATH')) exit;
// TODO: Split this class up
final class Sort {
use Singleton;
const TYPE_ORDER = ['term', 'taxonomy', 'post_type'];
protected array $relationships = [];
protected array $current_relationship = [];
protected function __construct() {
$this->relationships = [];
$this->current_relationship = [];
add_action('init', [$this, 'init'], 100);
}
public function validate_relationship(array $relationship):bool {
if (!isset($relationship['post_type']) && !isset($relationship['taxonomy'])) return false;
if (isset($relationship['post_type']) && !post_type_exists($relationship['post_type'])) return false;
if (isset($relationship['taxonomy']) && !taxonomy_exists($relationship['taxonomy'])) return false;
if (isset($relationship['post_type']) && isset($relationship['taxonomy']) && !in_array($relationship['taxonomy'], get_object_taxonomies($relationship['post_type']))) return false;
return true;
}
public function get_relationship_type(array $relationship):bool {
if (isset($relationship['post_type']) && isset($relationship['taxonomy'])) {
return 'term';
} else if (isset($relationship['post_type']) && !isset($relationship['taxonomy'])) {
return 'post_type';
} else if (!isset($relationship['post_type']) && isset($relationship['taxonomy'])) {
return 'taxonomy';
} else {
return false;
}
}
private function get_relationships():array {
$relationships = apply_filters('ogre_sort_relationships', []);
if (!is_array($relationships) || empty($relationships)) return [];
// Filter out invalid post types
$relationships = array_filter($relationships, [$this, 'validate_relationship']);
if (empty($relationships)) return [];
// Assign relationship types
foreach ($relationships as &$relationship) {
$relationship['type'] = $this->get_relationship_type($relationship);
}
// Sort Taxonomy Types to prefer term over post_type
usort($relationships, fn (array $a, array $b):bool => array_search($a['type'], self::TYPE_ORDER) > array_search($b['type'], self::TYPE_ORDER));
return $relationships;
}
public function init() {
$this->relationships = $this->get_relationships();
if (empty($this->relationships)) return;
// Update all order meta
if (is_admin() && function_exists('is_plugin_active') && is_plugin_active('wp-rocket/wp-rocket.php')) {
add_action('admin_post_purge_cache', [$this, 'refresh_purge_cache'], 1);
} else if (empty($_GET) && is_admin()) {
add_action('current_screen', [$this, 'refresh_screen'], 10, 1);
}
// Check if has active relationship in admin, sets current_relationship
if (is_admin()) {
add_action('current_screen', [$this, 'current_screen']);
}
// Post Updating
add_action('save_post', [$this, 'save_post'], 10, 3);
// Post Types
add_action('pre_get_posts', [$this, 'pre_get_posts'], 10, 1);
add_filter('get_previous_post_where', [$this, 'previous_post_where']);
add_filter('get_previous_post_sort', [$this, 'previous_post_sort']);
add_filter('get_next_post_where', [$this, 'next_post_where']);
add_filter('get_next_post_sort', [$this, 'next_post_sort']);
// Taxonomy
add_filter('terms_clauses', [$this, 'terms_clauses'], 10, 3);
add_filter('get_terms_orderby', [$this, 'get_terms_orderby'], 10, 3);
add_filter('wp_get_object_terms', [$this, 'wp_get_object_terms'], 10, 4);
add_filter('get_terms', [$this, 'get_terms'], 10, 4);
add_action('create_term', [$this, 'add_term_relationship'], 10, 3);
// Ajax
add_action('wp_ajax_ogre_sort', [$this, 'sort']);
}
public function current_screen() {
$screen = get_current_screen();
foreach ($this->relationships as $relationship) {
switch ($relationship['type']) {
case 'term':
if ($screen->base == 'edit' && $screen->post_type == $relationship['post_type'] && (isset($_GET[$relationship['taxonomy']]) || (isset($_GET['taxonomy']) && $_GET['taxonomy'] == $relationship['taxonomy']))) {
$this->current_relationship = $relationship;
break;
}
break;
case 'post_type':
if ($screen->base == 'edit' && $screen->post_type == $relationship['post_type']) {
$taxes = get_object_taxonomies($screen->post_type, 'names');
$tax_active = false;
foreach ($taxes as $tax) {
if (isset($_GET[$tax])) {
$tax_active = true;
break;
}
}
if (!$tax_active) $this->current_relationship = $relationship;
break;
}
break;
case 'taxonomy':
if ($screen->base == 'edit-tags' && $screen->taxonomy == $relationship['taxonomy']) {
$this->current_relationship = $relationship;
break;
}
break;
}
if ($this->current_relationship != false) break;
}
if ($this->current_relationship == false) return;
// Ajax
add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']);
}
public function enqueue_scripts() {
$vars = [
'ajaxurl' => admin_url('admin-ajax.php'),
'current_relationship' => $this->current_relationship,
'relationships' => $this->relationships,
];
if (!empty($term = get_queried_object())) $vars['term'] = $term;
wp_enqueue_script('jquery');
wp_enqueue_script('jquery-ui-sortable');
wp_enqueue_script('ogre-sort', Plugin::get_url('assets/sort.js'), ['jquery'], Plugin::get_version(), true);
wp_localize_script('ogre-sort', 'ogre_sort', $vars);
wp_enqueue_style('ogre-sort', Plugin::get_url('assets/sort/css'), false, Plugin::get_version());
}
// Add Meta when Post is Updated
public function save_post($post_id, $post, $update) {
global $wpdb;
$_post = get_post($post_id);
if (wp_is_post_revision($post_id) || $_post->post_stauts == 'auto-draft') return;
if (empty($this->relationships)) return;
$relationships = [];
foreach ($this->relationships as $relationship) {
switch ($relationship['type']) {
case 'post_type':
if (isset($relationship['post_type']) && $relationship['post_type'] == $_post->post_type) {
$relationships[] = $relationship;
}
break;
case 'term':
$taxonomies = get_object_taxonomies($_post->post_type);
if (isset($relationship['taxonomy']) && is_array($taxonomies) && in_array($relationship['taxonomy'], $taxonomies)) {
$relationships[] = $relationship;
}
break;
}
}
if (empty($relationships)) return;
foreach ($relationships as $relationship) {
switch ($relationship['type']) {
case 'post_type':
if ($_post->post_status == 'draft' && !$update) {
$wpdb->update($wpdb->posts, [
'menu_order' => -1,
], [
'ID' => $post_id,
]);
}
break;
case 'term':
$terms = wp_get_object_terms($post_id, $relationship['taxonomy'], [
'fields' => 'ids',
]);
if (is_array($terms) && !empty($terms)) {
foreach ($terms as $term_id) {
if (metadata_exists('post', $post_id, "ogre-sort_{$relationship['taxonomy']}_{$term_id}")) continue;
add_post_meta($post_id, "ogre-sort_{$relationship['taxonomy']}_{$term_id}", -1, true);
}
}
break;
}
}
}
// Query Filters
public function pre_get_posts($wp_query) {
if (empty($this->relationships)) return false;
if (isset($wp_query->query['orderby']) && !empty($wp_query->query['orderby']) && ((is_admin() && isset($_GET['orderby'])) || $wp_query->query['orderby'] != 'date')) return false;
//if (!is_admin() && isset($wp_query->query['suppress_filters'])) return false; // NOTE: suppress_filters set to true by default in get_posts
//if (!isset($wp_query->query['post_type'])) $wp_query->set('post_type', 'post');
$relationships = [];
foreach ($this->relationships as $relationship) {
switch ($relationship['type']) {
case 'post_type':
if (isset($relationship['post_type']) && isset($wp_query->query['post_type']) && $relationship['post_type'] == $wp_query->query['post_type']) {
$relationships[] = $relationship;
}
break;
case 'term':
if (isset($relationship['taxonomy']) && isset($wp_query->query[$relationship['taxonomy']])) {
$relationships[] = $relationship;
} else if (isset($relationship['taxonomy']) && isset($wp_query->query['taxonomy']) && $wp_query->query['taxonomy'] == $relationship['taxonomy']) {
$relationships[] = $relationship;
} else if (isset($relationship['taxonomy']) && isset($wp_query->query['tax_query']) && is_array($wp_query->query['tax_query']) && !empty($wp_query->query['tax_query'])) {
foreach ($wp_query->query['tax_query'] as $tax) {
if (!isset($tax['taxonomy'])) continue;
if ($relationship['taxonomy'] != $tax['taxonomy']) continue;
$relationships[] = $relationship;
break;
}
}
break;
}
}
if (empty($relationships)) return false;
$current_relationship = $relationships[0];
foreach ($relationships as $relationship) {
// Term relationships have higher priority
if ($relationship['type'] == 'term') {
$current_relationship = $relationship;
break;
}
}
if (empty($current_relationship)) $current_relationship = $relationships[0];
if (empty($current_relationship)) return false;
switch ($current_relationship['type']) {
case 'term':
$term_by = 'slug';
$term_id = '';
if (isset($wp_query->query[$current_relationship['taxonomy']])) {
$term_id = $wp_query->query[$current_relationship['taxonomy']];
} else if (isset($wp_query->query['taxonomy']) && $wp_query->query['taxonomy'] == $current_relationship['taxonomy'] && isset($wp_query->query['term'])) {
$term_id = $wp_query->query['term'];
} else if (isset($wp_query->query['tax_query']) && is_array($wp_query->query['tax_query']) && !empty($wp_query->query['tax_query'])) {
foreach ($wp_query->query['tax_query'] as $tax) {
if (!isset($tax['taxonomy'])) continue;
if ($current_relationship['taxonomy'] != $tax['taxonomy']) continue;
$term_by = $tax['field'];
$term_id = $tax['terms'];
break;
}
}
if (empty($term_id)) break;
$term = get_term_by($term_by, $term_id, $current_relationship['taxonomy']);
if (!is_a($term, 'WP_Term')) break;
$wp_query->set('meta_key', "ogre-sort_{$current_relationship['taxonomy']}_{$term->term_id}");
$wp_query->set('orderby', 'meta_value_num');
break;
case 'post_type':
$wp_query->set('orderby', 'menu_order');
break;
}
$wp_query->set('order', 'ASC');
}
public function previous_post_where($where) {
if (empty($this->relationships)) return $where;
global $post;
$active = false;
foreach ($this->relationships as $relationship) {
if ($relationship['type'] == 'post_type' && $relationship['post_type'] == $post->post_type) {
$active = true;
break;
}
}
if ($active == false) return $where;
return str_replace("p.post_date < '{$post->post_date}'", "p.menu_order > '{$post->menu_order}'", $where);
}
public function previous_post_sort($orderby) {
if (empty($this->relationships)) return $orderby;
global $post;
$active = false;
foreach ($this->relationships as $relationship) {
if ($relationship['type'] == 'post_type' && $relationship['post_type'] == $post->post_type) {
$active = true;
break;
}
}
if ($active == false) return $orderby;
return 'ORDER BY p.menu_order ASC LIMIT 1';
}
public function next_post_where($where) {
if (empty($this->relationships)) return $where;
global $post;
if (empty($this->relationships)) return $where;
$active = false;
foreach ($this->relationships as $relationship) {
if ($relationship['type'] == 'post_type' && $relationship['post_type'] == $post->post_type) {
$active = true;
break;
}
}
if ($active == false) return $where;
return str_replace("p.post_date > '{$post->post_date}'", "p.menu_order < '{$post->menu_order}'", $where);
}
public function next_post_sort($orderby) {
if (empty($this->relationships)) return $orderby;
global $post;
$active = false;
foreach ($this->relationships as $relationship) {
if ($relationship['type'] == 'post_type' && $relationship['post_type'] == $post->post_type) {
$active = true;
break;
}
}
if ($active == false) return $orderby;
return 'ORDER BY p.menu_order DESC LIMIT 1';
}
public function terms_clauses($pieces, $taxonomies, $args) {
global $wpdb;
if ((is_admin() && isset($_GET['orderby'])) || empty($this->relationships) || !isset($pieces['fields']) || strpos($pieces['fields'], 'tr.') || !isset($pieces['join']) || strpos($pieces['join'], $wpdb->term_relationships) != false) return $pieces;
$active = false;
foreach ($this->relationships as $relationship) {
if ($relationship['type'] == 'taxonomy' && $args['taxonomy'] != NULL && ($relationship['taxonomy'] == $args['taxonomy'] || in_array($relationship['taxonomy'], $args['taxonomy']))) {
$active = true;
break;
}
}
if ($active == false) return $pieces;
$pieces['fields'] .= ", tr.term_order AS term_order";
$pieces['join'] .= " INNER JOIN {$wpdb->term_relationships} AS tr ON ( tr.term_taxonomy_id = t.term_id AND tr.term_taxonomy_id = tt.term_taxonomy_id AND tr.object_id = t.term_id )";
return $pieces;
}
public function get_terms_orderby($orderby, $args, $taxonomies) {
if ((is_admin() && isset($_GET['orderby'])) || empty($this->relationships)) return $orderby;
$active = false;
foreach ($this->relationships as $relationship) {
if ($relationship['type'] == 'taxonomy' && $args['taxonomy'] != NULL && ($relationship['taxonomy'] == $args['taxonomy'] || in_array($relationship['taxonomy'], $args['taxonomy']))) {
$active = true;
break;
}
}
if ($active == false) return $orderby;
return 'tr.term_order';
}
public function wp_get_object_terms($terms, $object_ids, $taxonomies, $args) {
return $this->get_object_terms($terms, $args);
}
public function get_terms($terms, $taxonomies, $args, $term_query) {
return $this->get_object_terms($terms, $args);
}
public function get_object_terms($terms, $args) {
global $wpdb;
if (empty($terms) || (is_admin() && isset($_GET['orderby'])) || empty($this->relationships) || !isset($args['taxonomy'])) return $terms;
// Check if valid query
$active_relationship = false;
foreach ($this->relationships as $relationship) {
if ($relationship['type'] == 'taxonomy' && ($relationship['taxonomy'] == $args['taxonomy'] || in_array($relationship['taxonomy'], $args['taxonomy']))) {
$active_relationship = $relationship;
break;
}
}
if ($active_relationship == false) return $terms;
// Add term_relationships.term_order to WP_Term object
foreach ($terms as $key => $term) {
if (is_numeric($term)) $term = get_term($term);
$results = $wpdb->get_results("
SELECT term_relationships.term_order AS term_order
FROM {$wpdb->term_relationships} AS term_relationships
WHERE term_relationships.term_taxonomy_id = {$term->term_taxonomy_id} AND term_relationships.object_id = {$term->term_id}
");
if (!empty($results)) {
$term->term_order = intval($results[0]->term_order);
}
}
usort($terms, function ($a, $b):int {
if (is_object($a)) {
if ($a->term_order == $b->term_order) return 0;
return ($a->term_order < $b->term_order) ? -1 : 1;
} else {
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
});
return $terms;
}
public function add_term_relationship($term_id, $tt_id, $taxonomy) {
// Check if taxonomy is within relationships
$tax_relationship = false;
foreach ($this->relationships as $relationship) {
if ($relationship['type'] == 'taxonomy' && $relationship['taxonomy'] == $taxonomy) {
$tax_relationship = $relationship;
break;
}
}
if ($tax_relationship == false) return;
// Reset taxonomy terms to define term_relationship to added term
$this->refresh($tax_relationship);
}
// Ajax Functions
public function sort() {
global $wpdb;
$relationship = $_POST['relationship'];
if (!is_array($relationship)) {
wp_send_json_error(__('Invalid sort relationship.', 'ogrecore'));
exit;
}
$exists = false;
foreach ($this->relationships as $rel) {
if (($relationship['type'] == $rel['type']) && (!isset($relationship['post_type']) || $relationship['post_type'] == $rel['post_type']) && (!isset($relationship['taxonomy']) || $relationship['taxonomy'] == $rel['taxonomy'])) {
$exists = true;
break;
}
}
if ($exists == false) {
wp_send_json_error(__('Relationship does not exist.', 'ogrecore'));
exit;
}
parse_str($_POST['order'], $data);
if (!is_array($data)) {
wp_send_json_error(__('Order data invalid.', 'ogrecore'));
exit;
}
// Get objects per now page
$object_ids = [];
if (isset($data['post'])) {
$object_ids = array_filter(array_map('intval', $data['post']), function ($object_id) {
return is_int($object_id) && $object_id > 0;
});
} else if (isset($data['tag'])) {
$object_ids = array_filter(array_map('intval', $data['tag']), function ($object_id) {
return is_int($object_id) && $object_id > 0;
});
}
if (empty($object_ids)) {
wp_send_json_error(__('Unable to extract object ids from order data.', 'ogrecore'));
exit;
}
switch ($relationship['type']) {
case 'term':
$term = $_POST['term'];
if (!is_array($term)) {
wp_send_json_error(__('Invalid term provided.', 'ogrecore'));
exit;
}
foreach ($object_ids as $i => $post_id) {
update_post_meta($post_id, "ogre-sort_{$relationship['taxonomy']}_{$term['term_id']}", $i + 1);
}
break;
case 'post_type':
foreach ($object_ids as $i => $post_id) {
$wpdb->update($wpdb->posts, [
'menu_order' => $i + 1,
], [
'ID' => $post_id,
]);
}
break;
case 'taxonomy':
foreach ($object_ids as $i => $term_id) {
$result = $wpdb->get_row("
SELECT term_taxonomy.term_taxonomy_id AS term_taxonomy_id, term_relationships.term_order AS term_order
FROM {$wpdb->term_taxonomy} AS term_taxonomy
INNER JOIN {$wpdb->term_relationships} AS term_relationships ON ( term_taxonomy.term_taxonomy_id = term_relationships.term_taxonomy_id AND term_taxonomy.term_id = term_relationships.object_id )
WHERE term_taxonomy.term_id = {$term_id}
");
$wpdb->update($wpdb->term_relationships, [
'term_order' => $i + 1,
], [
'object_id' => $term_id,
'term_taxonomy_id' => $result->term_taxonomy_id,
]);
}
break;
}
wp_send_json_success();
exit;
}
// Core Functions
public function valid($relationship, $post_id = false, $term_id = false) {
switch ($relationship['type']) {
case 'term':
if ($post_id == false || !get_post_status($post_id)) { return false; }
if ($term_id == false || !term_exists($term_id, $relationship['taxonomy'])) { return false; }
break;
case 'post_type':
if ($post_id == false || !get_post_status($post_id)) { return false; }
break;
case 'taxonomy':
if ($term_id == false || !term_exists($term_id, $relationship['taxonomy'])) { return false; }
break;
default:
return false;
}
return true;
}
public function set($relationship, $order, $post_id = false, $term_id = false, $term_taxonomy_id = false) {
global $wpdb;
if (!$this->valid($relationship, $post_id, $term_id) || !is_int($order) || $order < 0) {
return false;
}
switch ($relationship['type']) {
case 'term':
update_post_meta($post_id, "ogre-sort_{$relationship['taxonomy']}_{$term_id}", $order);
break;
case 'post_type':
$wpdb->update($wpdb->posts, [
'menu_order' => $order,
], [
'ID' => $post_id,
]);
break;
case 'taxonomy':
$wpdb->update($wpdb->term_relationships, [
'term_order' => $order,
], [
'object_id' => $term_id,
'term_taxonomy_id' => $term_taxonomy_id,
]);
break;
}
return true;
}
public function get($relationship, $post_id = false, $term_id = false, $term_taxonomy_id = false) {
global $wpdb;
if (!$this->valid($relationship, $post_id, $term_id)) {
return false;
}
switch ($relationship['type']) {
case 'term':
return intval(get_post_meta($post_id, 'ogre-sort_' . $relationship['taxonomy'] . '_' . $term_id, true));
case 'post_type':
$_post = get_post($post_id);
return intval($_post->menu_order);
case 'taxonomy':
$results = $wpdb->get_results("SELECT term_order FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = {$term_taxonomy_id} AND object_id = {$term_id}");
if (!empty($results)) {
return intval($results[0]->term_order);
} else {
$orders = get_option('term_order_' . $relationship['taxonomy'], []);
if (!empty($orders)) {
foreach ($orders as $position => $value) {
if (intval($value) === intval($term_id)) return intval($position);
}
}
}
break;
}
return false;
}
public function reset($relationship) {
global $wpdb;
switch ($relationship['type']) {
case 'term':
$terms = get_terms([
'taxonomy' => $relationship['taxonomy'],
'hide_empty' => false,
'fields' => 'ids',
]);
if (!empty($terms)) {
foreach ($terms as $term_id) {
$posts = get_posts([
'post_type' => $relationship['post_type'],
'posts_per_page' => -1,
'tax_query' => [[
'taxonomy' => $relationship['taxonomy'],
'field' => 'id',
'terms' => $term_id,
]],
'fields' => 'ids',
]);
if (!empty($posts)) {
foreach ($posts as $post_id) {
delete_post_meta($post_id, "ogre-sort_{$relationship['taxonomy']}_{$term_id}");
}
}
}
}
break;
case 'post_type':
$results = $wpdb->get_results("SELECT ID FROM {$wpdb->posts} WHERE post_type = {$relationship['taxonomy']} AND post_status IN ('publish', 'pending', 'draft', 'private', 'future') ORDER BY post_date DESC");
if (!empty($results)) {
$i = 0;
foreach ($results as $row) {
$wpdb->update($wpdb->posts, [
'menu_order' => $i,
], [
'ID' => $row->ID,
]);
$i++;
}
}
break;
case 'taxonomy':
$terms = get_terms([
'taxonomy' => $relationship['taxonomy'],
'hide_empty' => false,
'fields' => 'all',
'orderby' => 'name',
'order' => 'ASC',
]);
if (!empty($terms)) {
foreach ($terms as $term) {
$wpdb->delete($wpdb->term_relationships, [
'object_id' => $term->term_id,
'term_taxonomy_id' => $term->term_taxonomy_id,
]);
}
}
break;
}
return true;
}
public function reset_all() {
foreach ($this->relationships as $relationship) {
$this->reset($relationship);
}
}
public function refresh($relationship) {
global $wpdb;
switch ($relationship['type']) {
case 'term':
$terms = get_terms([
'taxonomy' => $relationship['taxonomy'],
'hide_empty' => true,
'fields' => 'ids',
]);
if (empty($terms)) return false;
$terms = array_unique($terms);
foreach ($terms as $term_id) {
// Set all undefined meta data
$posts = get_posts([
'post_type' => $relationship['post_type'],
'posts_per_page' => -1,
'offset' => 0,
'post_status' => 'any',
'fields' => 'ids',
'tax_query' => [[
'taxonomy' => $relationship['taxonomy'],
'field' => 'term_id',
'terms' => $term_id,
'include_children' => true,
'operator' => 'IN',
]],
'meta_query' => [
'relation' => 'OR',
[
'key' => "ogre-sort_{$relationship['taxonomy']}_{$term_id}",
'compare' => 'NOT EXISTS',
'value' => '',
],
[
'key' => "ogre-sort_{$relationship['taxonomy']}_{$term_id}",
'value' => '',
],
],
]);
$posts = array_unique($posts);
foreach ($posts as $post_id) {
update_post_meta($post_id, "ogre-sort_{$relationship['taxonomy']}_{$term_id}", -1);
}
// Reorder
$posts = get_posts([
'post_type' => $relationship['post_type'],
'posts_per_page' => -1,
'offset' => 0,
'post_status' => 'any',
'fields' => 'ids',
'tax_query' => [[
'taxonomy' => $relationship['taxonomy'],
'field' => 'term_id',
'terms' => $term_id,
'include_children' => true,
'operator' => 'IN',
]],
'meta_key' => "ogre-sort_{$relationship['taxonomy']}_{$term_id}",
'orderby' => 'meta_value_num',
]);
$posts = array_values(array_unique($posts));
foreach ($posts as $i => $post_id) {
update_post_meta($post_id, "ogre-sort_{$relationship['taxonomy']}_{$term_id}", $i + 1);
}
}
break;
case 'post_type':
$result = $wpdb->get_row("
SELECT count(*) as cnt, max(menu_order) as max, min(menu_order) as min
FROM {$wpdb->posts}
WHERE post_type = '{$relationship['post_type']}' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
");
if ($result->cnt == 0 || $result->cnt == $result->max) return false;
$results = $wpdb->get_results("
SELECT ID
FROM {$wpdb->posts}
WHERE post_type = '{$relationship['post_type']}' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
ORDER BY menu_order ASC
");
foreach ($results as $key => $result) {
$wpdb->update($wpdb->posts, [
'menu_order' => $key + 1,
], [
'ID' => $result->ID,
]);
}
break;
case 'taxonomy':
// Set all undefined term_orders
$results = $wpdb->get_results("
SELECT terms.term_id AS term_id, term_taxonomy.term_taxonomy_id AS term_taxonomy_id
FROM {$wpdb->terms} AS terms
INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy ON ( terms.term_id = term_taxonomy.term_id )
WHERE term_taxonomy.taxonomy = '{$relationship['taxonomy']}'
");
if (empty($results)) return false;
foreach ($results as $key => $result) {
$term_order = $wpdb->get_results("
SELECT term_relationships.term_order, term_relationships.object_id
FROM {$wpdb->term_relationships} AS term_relationships
WHERE term_relationships.term_taxonomy_id = {$result->term_taxonomy_id} AND term_relationships.object_id = {$result->term_id}
");
if (empty($term_order)) {
$wpdb->insert($wpdb->term_relationships, [
'object_id' => $result->term_id,
'term_taxonomy_id' => $result->term_taxonomy_id,
'term_order' => -1,
]);
}
}
// Reorder term_orders
$results = $wpdb->get_results("
SELECT terms.term_id AS term_id, term_taxonomy.term_taxonomy_id AS term_taxonomy_id, term_relationships.term_order
FROM {$wpdb->terms} AS terms
INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy ON ( terms.term_id = term_taxonomy.term_id )
INNER JOIN {$wpdb->term_relationships} AS term_relationships ON ( term_taxonomy.term_taxonomy_id = term_relationships.term_taxonomy_id AND term_taxonomy.term_id = term_relationships.object_id )
WHERE term_taxonomy.taxonomy = '{$relationship['taxonomy']}'
ORDER BY term_order ASC
");
foreach ($results as $key => $result) {
$wpdb->update($wpdb->term_relationships, [
'term_order' => $key + 1,
], [
'object_id' => $result->term_id,
'term_taxonomy_id' => $result->term_taxonomy_id,
]);
}
break;
}
return true;
}
public function refresh_purge_cache() {
if (!isset($_GET['type'], $_GET['_wpnonce'])) return;
$_type = explode('-', $_GET['type']);
$_type = reset($_type);
if ($_type == 'all') {
$this->refresh_all();
}
}
public function refresh_screen($current_screen) {
// TODO: Move this to button on settings with post action
if ($current_screen->id == 'dashboard') {
$this->refresh_all();
}
}
public function refresh_all() {
foreach ($this->relationships as $relationship) {
$this->refresh($relationship);
}
}
}
Sort::instance();