876 lines
35 KiB
PHP
876 lines
35 KiB
PHP
<?php
|
|
/**
|
|
* @package ogre-sort
|
|
* @author cleverogre
|
|
* @copyright 2025 CleverOgre
|
|
* @license GLP-3.0-or-later
|
|
* @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();
|