/** * Handle ajax term reordering * * This bit is inspired by the Simple Page Ordering plugin from 10up * * @since 0.1.0 */ public static function ajax_reordering_terms() { // Bail if required term data is missing if (empty($_POST['id']) || empty($_POST['tax']) || !isset($_POST['previd']) && !isset($_POST['nextid'])) { die(-1); } // Attempt to get the taxonomy $tax = get_taxonomy($_POST['tax']); // Bail if taxonomy does not exist if (empty($tax)) { die(-1); } // Bail if current user cannot assign terms if (!current_user_can($tax->cap->edit_terms)) { die(-1); } // Bail if term cannot be found $term = get_term($_POST['id'], $_POST['tax']); if (empty($term)) { die(-1); } // Sanitize positions $taxonomy = $_POST['tax']; $previd = empty($_POST['previd']) ? false : (int) $_POST['previd']; $nextid = empty($_POST['nextid']) ? false : (int) $_POST['nextid']; $start = empty($_POST['start']) ? 1 : (int) $_POST['start']; $excluded = empty($_POST['excluded']) ? array($term->term_id) : array_filter((array) $_POST['excluded'], 'intval'); // Define return values $new_pos = array(); $return_data = new stdClass(); // attempt to get the intended parent... $parent_id = $term->parent; $next_term_parent = $nextid ? wp_get_term_taxonomy_parent_id($nextid, $taxonomy) : false; // If the preceding term is the parent of the next term, move it inside if ($previd === $next_term_parent) { $parent_id = $next_term_parent; // If the next term's parent isn't the same as our parent, we need more info } elseif ($next_term_parent !== $parent_id) { $prev_term_parent = $previd ? wp_get_term_taxonomy_parent_id($nextid, $taxonomy) : false; // If the previous term is not our parent now, set it if ($prev_term_parent !== $parent_id) { $parent_id = $prev_term_parent !== false ? $prev_term_parent : $next_term_parent; } } // If the next term's parent isn't our parent, set to false if ($next_term_parent !== $parent_id) { $nextid = false; } // Get term siblings for relative ordering $siblings = get_terms($taxonomy, array('depth' => 1, 'number' => 100, 'parent' => $parent_id, 'orderby' => 'order', 'order' => 'ASC', 'hide_empty' => false, 'exclude' => $excluded)); // Loop through siblings and update terms foreach ($siblings as $sibling) { // Skip the actual term if it's in the array if ($sibling->term_id === (int) $term->term_id) { continue; } // If this is the term that comes after our repositioned term, set // our repositioned term position and increment order if ($nextid === (int) $sibling->term_id) { self::set_term_order($term->term_id, $taxonomy, $start, true); $ancestors = get_ancestors($term->term_id, $taxonomy, 'taxonomy'); $new_pos[$term->term_id] = array('order' => $start, 'parent' => $parent_id, 'depth' => count($ancestors)); $start++; } // If repositioned term has been set and new items are already in // the right order, we can stop looping if (isset($new_pos[$term->term_id]) && (int) $sibling->order >= $start) { $return_data->next = false; break; } // Set order of current sibling and increment the order if ($start !== (int) $sibling->order) { self::set_term_order($sibling->term_id, $taxonomy, $start, true); } $new_pos[$sibling->term_id] = $start; $start++; if (empty($nextid) && $previd === (int) $sibling->term_id) { self::set_term_order($term->term_id, $taxonomy, $start, true); $ancestors = get_ancestors($term->term_id, $taxonomy, 'taxonomy'); $new_pos[$term->term_id] = array('order' => $start, 'parent' => $parent_id, 'depth' => count($ancestors)); $start++; } } // max per request if (!isset($return_data->next) && count($siblings) > 1) { $return_data->next = array('id' => $term->term_id, 'previd' => $previd, 'nextid' => $nextid, 'start' => $start, 'excluded' => array_merge(array_keys($new_pos), $excluded), 'taxonomy' => $taxonomy); } else { $return_data->next = false; } if (empty($return_data->next)) { // If the moved term has children, refresh the page for UI reasons $children = get_terms($taxonomy, array('number' => 1, 'depth' => 1, 'orderby' => 'order', 'order' => 'ASC', 'parent' => $term->term_id, 'fields' => 'ids', 'hide_empty' => false)); if (!empty($children)) { die('children'); } } $return_data->new_pos = $new_pos; die(json_encode($return_data)); }
/** * Translate the value returned by 'option_{taxonomy}_children' and store it in cache * * @param array $original_value * @param bool|string $current_language * @param bool|string $taxonomy * * @return array */ function option_taxonomy_children($original_value, $current_language = false, $taxonomy = false) { if (!is_array($original_value) || count($original_value) == 0) { return $original_value; } $current_language = !$current_language ? $this->get_current_language() : $current_language; $default_language = $this->get_default_language(); if ($current_language == $default_language) { return $original_value; } $cache_key_array[] = $current_language; $cache_key_array[] = $default_language; $cache_key_array[] = $original_value; $cache_key = md5(serialize($cache_key_array)); $cache_group = 'translate_taxonomy_children'; $cache_found = false; $result = wp_cache_get($cache_key, $cache_group, false, $cache_found); if ($cache_found) { return $result; } $debug_backtrace = $this->get_backtrace(4, false, false); //Find the taxonomy name if (!$taxonomy && isset($debug_backtrace[3]) && isset($debug_backtrace[3]['args'])) { $option_name = $debug_backtrace[3]['args'][0]; $taxonomies = explode('_', $option_name); $taxonomy = $taxonomies[0]; } $translated_children = array(); if ($taxonomy && is_array($original_value)) { foreach ($original_value as $children_term_ids) { foreach ($children_term_ids as $child_term_id) { $translated_child_term_id = icl_object_id($child_term_id, $taxonomy, false, $current_language); if ($translated_child_term_id) { $translated_parent_term_id = wp_get_term_taxonomy_parent_id($translated_child_term_id, $taxonomy); if ($translated_parent_term_id) { if (!isset($translated_children[$translated_parent_term_id])) { $translated_children[$translated_parent_term_id] = array(); } $translated_children[$translated_parent_term_id][] = $translated_child_term_id; } } } } } wp_cache_set($cache_key, $translated_children, $cache_group); return $translated_children; }
/** * Adds the hierarchical depth as a variable to all terms. * 0 means, that the term has no parent. * * @param array $tridgroup * * @return array */ private function add_level_information_to_terms($tridgroup) { foreach ($tridgroup['elements'] as $lang => &$term) { $level = 0; $term_id = $term['term_id']; while ($term_id = wp_get_term_taxonomy_parent_id($term_id, $this->taxonomy)) { $level++; } $term['level'] = $level; } return $tridgroup; }