get_queried_object();
}
/**
* Add cpt to taxonomy during the query
*
* @param WP_Query $query
*
* @return void
* @author Olatechpro
*/
public static function cpt_taxonomy_parse_query($query)
{
if (function_exists('get_current_screen')) {
$screen = get_current_screen();
}
if (is_admin()) {
return $query;
}
if (isset($screen->id) && $screen->id == 'edit-post') {
return $query;
}
if ($query->is_category == true || $query->is_tag == true || $query->is_tax == true) {
$get_queried_object = self::taxopress_get_queried_object();
if (is_object($get_queried_object)) {
if (!isset($get_queried_object->taxonomy)) {
return $query;
}
if (!taxopress_show_all_cpt_in_archive_result($get_queried_object->taxonomy)) {
return $query;
}
$get_taxonomy = get_taxonomy($get_queried_object->taxonomy);
if (is_object($get_taxonomy)) {
$post_types = $get_taxonomy->object_type;
if (isset($query->query_vars['post_type'])) {
if (is_array($query->query_vars['post_type'])) {
$post_types = array_filter(array_merge($query->query_vars['post_type'], $post_types));
} elseif (is_string($query->query_vars['post_type'])) {
$original_post_type = $query->query_vars['post_type'];
$get_post_type_object = get_post_type_object($original_post_type);
if (is_object($get_post_type_object)) {
if ((int)$get_post_type_object->public === 0) {
return $query;
}
}
$post_types[] = $query->query_vars['post_type'];
}
$new_post_object = $post_types;
} else {
$new_post_object = $post_types;
}
$query->query_vars['post_type'] = $new_post_object;
}
}
}
return $query;
}
/**
* Load translations
*/
public static function init_translation()
{
// phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound -- Keep support for bundled translations installed outside WordPress.org.
load_plugin_textdomain('simple-tags', false, basename(STAGS_DIR) . '/languages');
}
/**
* Register taxonomy post_tags for page post type
*
* @return void
* @author WebFactory Ltd
*/
public static function init()
{
register_taxonomy_for_object_type('post_tag', 'page');
}
/**
* Add page post type during the query
*
* @param WP_Query $query
*
* @return void
* @author WebFactory Ltd
*/
public static function parse_query($query)
{
if (function_exists('get_current_screen')) {
$screen = get_current_screen();
}
if (isset($screen->id) && $screen->id == 'edit-post') {
return $query;
}
if ($query->is_tag == true) {
if (isset($query->query_vars['post_type']) && is_array($query->query_vars['post_type'])) {
$query->query_vars['post_type'][] = 'page';
} else {
$query->query_vars['post_type'] = array( 'post', 'page' );
}
}
}
/**
* Randomize an array and keep association
*
* @param array $array
*
* @return boolean
*/
public static function random_array(&$array)
{
if (! is_array($array) || empty($array)) {
return false;
}
$keys = array_keys($array);
shuffle($keys);
$new = array();
foreach ((array) $keys as $key) {
$new[ $key ] = $array[ $key ];
}
$array = $new;
return true;
}
/**
* Build rel for tag link
*
* @return string
*/
public static function get_rel_attribut()
{
global $wp_rewrite;
$rel = (is_object($wp_rewrite) && $wp_rewrite->using_permalinks()) ? 'tag' : ''; // Tag ?
if (! empty($rel)) {
$rel = 'rel="' . $rel . '"'; // Add HTML Tag
}
return $rel;
}
/**
* Retrieve the post count for a term across all taxonomies.
*
* This function queries terms based on the given term name and returns the number of posts associated with the first matching term.
* It does not require specifying a taxonomy and will search across all public taxonomies.
*
* @param string $item
* @return int The number of posts associated with the first matching term. Returns 0 if no term is found or if it has no posts.
*/
public static function get_term_post_counts($item)
{
$terms = get_terms(array(
'name' => wp_strip_all_tags($item),
'hide_empty' => false,
'fields' => 'all',
'number' => 1,
));
// If terms exist, return the first matching term's count
if (! empty($terms) && ! is_wp_error($terms)) {
return $terms[0]->count;
}
return 0;
}
/**
* Format data for output
*
* @param string $html_class
* @param string $format
* @param string $title
* @param string|array $content
* @param boolean $copyright
* @param string $separator
*
* @return string|array
*/
public static function output_content($html_class = '', $format = 'list', $title = '', $content = '', $copyright = true, $separator = '', $div_class = '', $a_class = '', $before = '', $after = '', $taxonomy = '')
{
if (empty($content)) {
return ''; // return nothing
}
if ($format == 'array' && is_array($content)) {
return $content; // Return PHP array if format is array
}
$title = taxopress_sanitize_text_field($title);
if (is_array($content)) {
switch ($format) {
case 'list':
$output = '' . $before . '
' . "\n\t" . '- ' . implode("
\n\t- ", $content) . "
\n
{$after}\n";
break;
case 'ol':
$output = '' . $before . ' ' . "\n\t" . '- ' . implode("
\n\t- ", $content) . "
\n
{$after}\n";
break;
case 'comma':
$output = '' . '' . '' . '' . $before . implode($separator, $content) . " {$after}\n";
break;
case 'table':
$output = $before . '' . "\n\t";
$count = 0;
foreach ($content as $item) {
// If $item is an array, use its fields
if (is_array($item) && isset($item['html'], $item['count'])) {
$term_html = $item['html'];
$post_count = $item['count'];
} else {
// fallback for legacy
$term_html = $item;
$post_count = self::get_term_post_counts(wp_strip_all_tags($item));
}
// if ( $post_count === 0 ) {
// continue;
// }
$display_class = $count >= 6 ? 'hidden' : '';
$output .= '| ' . $term_html . ' | ' . $post_count . ' |
' . "\n\t";
$count++;
}
if ($count > 6) {
$output .= '| ';
$output .= 'see more ';
$output .= 'close table ';
$output .= ' |
' . "\n";
}
$output .= "
" . $after . "\n";
break;
case 'border':
$output = '' . $before . ' ' . "\n\t" . implode("{$separator}\n", $content) . " {$after}
\n";
break;
case 'box':
$output = '' . $before . ' ' . "\n\t" . implode("{$separator}\n", $content) . " {$after}
\n";
break;
case 'parent/child':
$output = $before . '' . "\n";
// Cache term hierarchy to avoid repeated queries
static $term_hierarchy = [];
$cache_key = md5($taxonomy . serialize($content));
if (!isset($term_hierarchy[$cache_key])) {
$terms_by_parent = [];
$all_terms = [];
$term_names = array_map(function ($term_html) {
return wp_strip_all_tags($term_html);
}, array_filter($content, 'trim'));
if (!empty($term_names)) {
$terms = get_terms([
'taxonomy' => $taxonomy,
'name' => $term_names,
'hide_empty' => false,
'update_term_meta_cache' => false
]);
if (!is_wp_error($terms)) {
foreach ($terms as $term) {
$all_terms[$term->term_id] = [
'term' => $term,
'html' => $content[array_search($term->name, $term_names)],
'is_parent' => false
];
$parent_id = $term->parent ?: '0';
$terms_by_parent[$parent_id][] = $term->term_id;
}
foreach ($terms_by_parent as $child_ids) {
foreach ($child_ids as $child_id) {
if (isset($terms_by_parent[$child_id])) {
$all_terms[$child_id]['is_parent'] = true;
}
}
}
}
}
$term_hierarchy[$cache_key] = [
'terms' => $all_terms,
'hierarchy' => $terms_by_parent
];
}
// Use cached hierarchy
$data = $term_hierarchy[$cache_key];
$all_terms = $data['terms'];
$terms_by_parent = $data['hierarchy'];
// Group terms by parent
$terms_by_parent = [];
$all_terms = [];
// First pass - collect all terms
foreach ($content as $term_html) {
if (empty(trim($term_html))) {
continue;
}
$term_name = wp_strip_all_tags($term_html);
$term = get_term_by('name', $term_name, $taxonomy);
if (!$term) {
continue;
}
// Store term for reference
$all_terms[$term->term_id] = [
'term' => $term,
'html' => $term_html,
'is_parent' => false
];
$parent_id = $term->parent ?: '0';
if (!isset($terms_by_parent[$parent_id])) {
$terms_by_parent[$parent_id] = [];
}
$terms_by_parent[$parent_id][] = $term->term_id;
}
foreach ($terms_by_parent as $parent_id => $children) {
foreach ($children as $child_id) {
if (isset($terms_by_parent[$child_id])) {
$all_terms[$child_id]['is_parent'] = true;
}
}
}
$output_term = function ($term_id, $level = 0) use (&$output_term, &$all_terms, &$terms_by_parent) {
if (!isset($all_terms[$term_id])) {
return '';
}
$term_data = $all_terms[$term_id];
$html = str_repeat("\t", $level);
$html .= '- ' . $term_data['html'];
if (isset($terms_by_parent[$term_id])) {
$html .= "\n" . str_repeat("\t", $level + 1);
$html .= '
' . "\n";
foreach ($terms_by_parent[$term_id] as $child_id) {
$html .= $output_term($child_id, $level + 2);
}
$html .= str_repeat("\t", $level + 1) . "
\n";
}
$html .= str_repeat("\t", $level) . " \n";
return $html;
};
$display_mode = isset($current['display_mode']) ? $current['display_mode'] : 'parents_and_sub';
if ($display_mode === 'parents_only') {
foreach ($all_terms as $term_id => $term_data) {
if ($term_data['is_parent']) {
$output .= '- ' . $term_data['html'] . "
\n";
}
}
} elseif ($display_mode === 'sub_terms_only') {
foreach ($all_terms as $term_id => $term_data) {
if ($term_data['term']->parent > 0) {
$output .= '- ' . $term_data['html'] . "
\n";
}
}
} else {
// Display full hierarchy
// Start with root terms or terms whose parents aren't in our set
foreach ($all_terms as $term_id => $term_data) {
$term = $term_data['term'];
if ($term->parent === 0 || !isset($all_terms[$term->parent])) {
$output .= $output_term($term_id);
}
}
}
$output .= "
" . $after . "\n";
return $output;
break;
default:
$output = '' . $before . ' ' . "\n\t" . implode("{$separator}\n", $content) . " {$after}
\n";
break;
}
} else {
$content = trim($content);
switch ($format) {
case 'string':
$output = $content;
break;
case 'list':
$output = '' . $before . ' ' . "\n\t" . '- ' . $content . "
\n\t" . "
{$after}\n";
break;
case 'comma':
$output = '' . '' . '' . '' . $before . $content . " {$after}\n";
break;
case 'table':
$output = $before . '' . "\n\t"
. '| ' . $content . ' |
' . "\n\t"
. "
" . $after . "\n";
break;
case 'border':
$output = '' . $before . ' ' . "\n\t" . $content . " {$after}
\n";
break;
case 'box':
$output = '' . $before . ' ' . "\n\t" . $content . " {$after}
\n";
break;
case 'parent/child':
$output = $before . '' . "\n";
$lines = explode("\n", $content);
$inside_sublist = false;
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) {
continue;
}
if (strpos($line, 'taxopress-parent-term') !== false) {
if ($inside_sublist) {
$output .= "
\n";
$inside_sublist = false;
}
$output .= '' . $line;
$output .= "\n\n";
$inside_sublist = true;
} else {
$output .= '- ' . $line . "
\n";
}
}
// Close any open tags
if ($inside_sublist) {
$output .= "
\n";
}
$output .= "" . $after . "\n";
break;
default:
$output = '' . $before . ' ' . "\n\t" . $content . " {$after}
\n";
break;
}
}
//wrap class
if (!empty(trim($div_class))) {
$wrap_div_class_open = '';
$wrap_div_class_close = '
';
} else {
$wrap_div_class_open = ' ';
$wrap_div_class_close = '
';
}
// Replace false by empty
$title = trim($title);
if (strtolower($title) == 'false') {
$title = '';
}
// Put title if exist
if (! empty($title)) {
$title .= "\n\t";
}
if ($copyright === true) {
return "\n" . '' . "\n\t" . $wrap_div_class_open . $title . $output . $wrap_div_class_close . "\n";
} else {
return "\n\t" . $wrap_div_class_open . $title . $output . $wrap_div_class_close . "\n";
}
}
/**
* Remplace marker by dynamic values (use for related tags, current tags and tag cloud)
*
* @param string $element_loop
* @param object $term
* @param string $rel
* @param integer $scale_result
* @param integer $scale_max
* @param integer $scale_min
* @param integer $largest
* @param integer $smallest
* @param string $unit
* @param string $maxcolor
* @param string $mincolor
*
* @return string
*/
public static function format_internal_tag($element_loop = '', $term = null, $rel = '', $scale_result = 0, $scale_max = null, $scale_min = 0, $largest = 0, $smallest = 0, $unit = '', $maxcolor = '', $mincolor = '')
{
// Need term object
$tag_link = get_term_link($term, $term->taxonomy);
$element_loop = str_replace('%tag_link%', esc_url($tag_link), $element_loop);
$element_loop = str_replace('%tag_feed%', esc_url(get_term_feed_link($term->term_id, $term->taxonomy, '')), $element_loop);
$element_loop = str_replace('%tag_name%', esc_html($term->name), $element_loop);
$element_loop = str_replace('%tag_name_attribute%', esc_html(wp_strip_all_tags($term->name)), $element_loop);
$element_loop = str_replace('%tag_id%', $term->term_id, $element_loop);
$element_loop = str_replace('%tag_count%', (int) $term->count, $element_loop);
$element_loop = str_replace('%tag_description%', esc_html($term->description), $element_loop);
// Need rel
$element_loop = str_replace('%tag_rel%', $rel, $element_loop);
// Need max/min/scale and other :)
if ($scale_result !== null) {
$scale_result = (int) $scale_result;
$scale_min = (int) $scale_min;
$scale_max = (int) $scale_max;
$largest = (int) $largest;
$smallest = (int) $smallest;
$element_loop = str_replace('%tag_size%', 'font-size:' . self::round(($scale_result - $scale_min) * ($largest - $smallest) / ($scale_max - $scale_min) + $smallest, 2) . $unit . ';', $element_loop);
$element_loop = str_replace('%tag_color%', 'color:' . self::get_color_by_scale(self::round(($scale_result - $scale_min) * (100) / ($scale_max - $scale_min), 2), $mincolor, $maxcolor) . ';', $element_loop);
$element_loop = str_replace('%tag_scale%', $scale_result, $element_loop);
}
// External link
$element_loop = str_replace('%tag_technorati%', self::format_external_tag('technorati', $term->name), $element_loop);
$element_loop = str_replace('%tag_flickr%', self::format_external_tag('flickr', $term->name), $element_loop);
$element_loop = str_replace('%tag_delicious%', self::format_external_tag('delicious', $term->name), $element_loop);
return $element_loop;
}
/**
* This is pretty filthy. Doing math in hex is much too weird. It's more likely to work, this way!
* Provided from UTW. Thanks.
*
* @param integer $scale_color
* @param string $min_color
* @param string $max_color
*
* @return string
*/
public static function get_color_by_scale($scale_color, $min_color, $max_color)
{
$scale_color = $scale_color / 100;
$minr = hexdec(substr($min_color, 1, 2));
$ming = hexdec(substr($min_color, 3, 2));
$minb = hexdec(substr($min_color, 5, 2));
$maxr = hexdec(substr($max_color, 1, 2));
$maxg = hexdec(substr($max_color, 3, 2));
$maxb = hexdec(substr($max_color, 5, 2));
$r = dechex(intval((($maxr - $minr) * $scale_color) + $minr));
$g = dechex(intval((($maxg - $ming) * $scale_color) + $ming));
$b = dechex(intval((($maxb - $minb) * $scale_color) + $minb));
if (strlen($r) == 1) {
$r = '0' . $r;
}
if (strlen($g) == 1) {
$g = '0' . $g;
}
if (strlen($b) == 1) {
$b = '0' . $b;
}
return '#' . $r . $g . $b;
}
/**
* Extend the round PHP public static function for force a dot for all locales instead the comma.
*
* @param string $value
* @param string $approximation
*
* @return float
* @author WebFactory Ltd
*/
public static function round($value, $approximation)
{
$value = round($value, $approximation);
$value = str_replace(',', '.', $value); // Fixes locale comma
$value = str_replace(' ', '', $value); // No space
return $value;
}
/**
* Format nice URL depending service
*
* @param string $type
* @param string $term_name
*
* @return string
*/
public static function format_external_tag($type = '', $term_name = '')
{
if (empty($term_name)) {
return '';
}
$term_name = esc_html($term_name);
switch ($type) {
case 'technorati':
return '' . $term_name . '';
break;
case 'flickr':
return '' . $term_name . '';
break;
case 'delicious':
return '' . $term_name . '';
break;
default:
return '';
break;
}
}
}