Initial commit
This commit is contained in:
160
inc/class-settings.php
Normal file
160
inc/class-settings.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?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;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class Settings {
|
||||
use Singleton;
|
||||
|
||||
const CAPABILITY = 'manage_options';
|
||||
|
||||
protected function __construct() {
|
||||
add_filter('ogre_sort_relationships', [$this, 'register_relationships'], 10, 1);
|
||||
add_action('admin_menu', [$this, 'menu']);
|
||||
add_action('admin_init', [$this, 'init']);
|
||||
}
|
||||
|
||||
public function register_relationships(array $relationships):array {
|
||||
// Post Types
|
||||
foreach ($this->get('post_types') as $post_type) {
|
||||
$relationships[] = ['post_type' => $post_type];
|
||||
}
|
||||
|
||||
// Taxonomies
|
||||
foreach ($this->get('taxonomies') as $taxonomy) {
|
||||
$relationships[] = ['taxonomy' => $taxonomy];
|
||||
}
|
||||
|
||||
// Taxonomy Posts
|
||||
foreach ($this->get('taxonomy_post_types') as $key) {
|
||||
$parts = explode('~', $key);
|
||||
if (count($parts) == 2) {
|
||||
$relationships = [
|
||||
'post_type' => $parts[0],
|
||||
'taxonomy' => $parts[1],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $relationships;
|
||||
}
|
||||
|
||||
private function get(string $key = ''):array {
|
||||
$data = (array) get_option(Plugin::get_id(), []);
|
||||
if (!empty($key)) return array_key_exists($key, $data) ? (array) $data[$key] : [];
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function is_checked(string $name, string $value):bool {
|
||||
return is_array($option = $this->get($name)) && in_array($value, $option);
|
||||
}
|
||||
|
||||
public function menu() {
|
||||
if (!current_user_can(self::CAPABILITY)) return;
|
||||
|
||||
add_options_page(sprintf(Plugin::__('%s Settings'), Plugin::get_title()), Plugin::get_title(), self::CAPABILITY, Plugin::get_id(), [$this, 'page']);
|
||||
}
|
||||
|
||||
public function init() {
|
||||
register_setting('options', Plugin::get_id());
|
||||
|
||||
add_settings_section('post_types', Plugin::__('Post Types'), [$this, 'section'], Plugin::get_id());
|
||||
|
||||
foreach (get_post_types(output: 'objects') as $post_type) {
|
||||
add_settings_field(
|
||||
Plugin::get_id() . '_post_type_' . $post_type->name,
|
||||
$post_type->label,
|
||||
[$this, 'checkbox'],
|
||||
Plugin::get_id(),
|
||||
'post_types',
|
||||
[
|
||||
'name' => 'post_types',
|
||||
'value' => $post_type->name,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
add_settings_section('taxonomies', Plugin::__('Taxonomies'), [$this, 'section'], Plugin::get_id());
|
||||
|
||||
foreach (get_taxonomies(output: 'objects') as $taxonomy) {
|
||||
add_settings_field(
|
||||
Plugin::get_id() . '_taxonomy_' . $post_type->name,
|
||||
$post_type->label,
|
||||
[$this, 'checkbox'],
|
||||
Plugin::get_id(),
|
||||
'taxonomies',
|
||||
[
|
||||
'name' => 'taxonomies',
|
||||
'value' => $taxonomy->name,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
add_settings_section('taxonomy_post_types', Plugin::__('Taxonomy Posts'), [$this, 'section'], Plugin::get_id());
|
||||
|
||||
foreach (get_post_types(output: 'objects') as $post_type) {
|
||||
foreach (get_object_taxonomies($post_type->name, 'objects') as $taxonomy) {
|
||||
add_settings_field(
|
||||
Plugin::get_id() . '_post_type_' . $post_type->name . '_taxonomy_' . $taxonomy->name,
|
||||
sprintf('%s: %s', $post_type->label, $taxonomy->label),
|
||||
[$this, 'checkbox'],
|
||||
Plugin::get_id(),
|
||||
'taxonomy_post_types',
|
||||
[
|
||||
'name' => 'taxonomy_post_types',
|
||||
'value' => $post_type->name . '~' . $taxonomy->name,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function page() {
|
||||
if (!current_user_can(self::CAPABILITY)) return;
|
||||
|
||||
// Show update message
|
||||
if (isset($_GET['settings-updated'])) add_settings_error(Plugin::get_id(), 'updated', Plugin::__('Settings Saved'), 'updated');
|
||||
|
||||
// Show error/update messages
|
||||
settings_errors(Plugin::get_id());
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
|
||||
<form action="options.php" method="post"><?php
|
||||
settings_fields(Plugin::get_id());
|
||||
do_settings_sections(Plugin::get_id());
|
||||
submit_button();
|
||||
?></form>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function section():void { }
|
||||
|
||||
public function field(array $args):void {
|
||||
extract($args);
|
||||
printf(
|
||||
'<input type="checkbox" name="%s[]" value="%s" %s>',
|
||||
esc_attr($name),
|
||||
esc_attr($value),
|
||||
checked($this->is_checked($name, $value), display: false)
|
||||
);
|
||||
}
|
||||
|
||||
public static function get_url():string {
|
||||
return admin_url('options-general.php?page=' . Plugin::get_id());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Settings::instance();
|
||||
873
inc/class-sort.php
Normal file
873
inc/class-sort.php
Normal file
@@ -0,0 +1,873 @@
|
||||
<?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();
|
||||
Reference in New Issue
Block a user