Instantly share code, notes, and snippets.
Created
July 11, 2014 12:41
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save soutar/3978bf7976f368da5f9b to your computer and use it in GitHub Desktop.
"Related category" functions from a widget built for S. Collins & Son
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class SomeClass { | |
/** | |
* Get X random related categories | |
* | |
* @param object $category The current category | |
* @param int $threshold The amount of common tags needed to deem a category "related" | |
* @param int $amount Amount of categories to return | |
* | |
* @return array The related categories | |
*/ | |
public function get_random_related_categories($category, $threshold, $amount) | |
{ | |
$related_categories = $this->get_related_categories($category, $threshold); | |
$related_count = count($related_categories); | |
if ($related_count == 0) { | |
return array(); | |
} elseif ($related_count < $threshold) { | |
$keys = array_rand($related_categories, $related_count); | |
} else { | |
$keys = array_rand($related_categories, $threshold); | |
} | |
if (is_array($keys)) { | |
return array_intersect_key($related_categories, array_flip($keys)); | |
} else { | |
return array($related_categories[$keys]); | |
} | |
} | |
/** | |
* Get related categories | |
* | |
* Retreive all categories which share at least 3 product tags | |
* with the current category | |
* | |
* @param object $category The current category | |
* @param int $threshold The amount of common tags needed to deem a category "related" | |
* | |
* @return array $relatedCategores The related categories | |
*/ | |
public function get_related_categories($category, $threshold) | |
{ | |
$relatedCategories = array(); | |
$excluded = get_ancestors($category->term_id, 'product_cat'); | |
array_push($excluded, $category->term_id); | |
$allCategories = get_terms('product_cat', array( | |
'exclude' => $excluded | |
)); | |
$tags = $this->get_category_tags($category->term_id); | |
foreach ($allCategories as $category) { | |
$thisTags = $this->get_category_tags($category->term_id); | |
if ($this->tags_in_common(array($tags, $thisTags)) >= $threshold) { | |
$relatedCategories[] = $category; | |
} | |
} | |
return $relatedCategories; | |
} | |
/** | |
* Tags in common | |
* | |
* Compare two arrays of tags and return the amount of elements | |
* which they both share (common) | |
* | |
* @param array $tag_sets An array containing the two arrays of tags | |
* | |
* @return int Amount of common elements between the two arrays | |
*/ | |
function tags_in_common($tag_sets) | |
{ | |
if (count($tag_sets) < 2) return; | |
$commonTags = array(); | |
foreach ($tag_sets[0] as $tag) { | |
if (in_array($tag, $tag_sets[1])) $commonTags[] = $tag; | |
} | |
return count($commonTags); | |
} | |
/** | |
* Get category tags | |
* | |
* Query the WP database for all distinct tags used in a specified category | |
* | |
* @param int $category_id | |
* | |
* @return array $tags | |
*/ | |
function get_category_tags($category_id) | |
{ | |
global $wpdb; | |
$tags = $wpdb->get_results($wpdb->prepare( | |
"SELECT DISTINCT | |
terms2.term_id as tag_id, | |
terms2.name as tag_name | |
FROM | |
{$wpdb->posts} as posts | |
LEFT JOIN {$wpdb->term_relationships} as term_relationships | |
ON term_relationships.object_id = posts.ID | |
LEFT JOIN {$wpdb->term_taxonomy} as term_taxonomy | |
ON term_relationships.term_taxonomy_id = term_taxonomy.term_taxonomy_id | |
LEFT JOIN {$wpdb->terms} as terms | |
ON terms.term_id = term_taxonomy.term_id, | |
{$wpdb->posts} as posts2 | |
LEFT JOIN {$wpdb->term_relationships} as term_relationships2 | |
ON term_relationships2.object_id = posts2.ID | |
LEFT JOIN {$wpdb->term_taxonomy} as term_taxonomy2 | |
ON term_relationships2.term_taxonomy_id = term_taxonomy2.term_taxonomy_id | |
LEFT JOIN {$wpdb->terms} as terms2 | |
ON terms2.term_id = term_taxonomy2.term_id | |
WHERE ( | |
term_taxonomy.taxonomy = 'product_cat' AND | |
terms.term_id = '%d' AND | |
term_taxonomy2.taxonomy = 'product_tag' AND | |
posts.post_status = 'publish' AND | |
posts2.post_status = 'publish' AND | |
posts.ID = posts2.ID | |
)", | |
$category_id | |
)); | |
return $tags; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment