Skip to content

Commit

Permalink
Merge pull request #737 from aaemnnosttv/pr/timber-terms-with-array
Browse files Browse the repository at this point in the history
Add support for TimberPost->terms( array ) & more
  • Loading branch information
jarednova committed Nov 10, 2015
2 parents 658413d + bdf0799 commit f72c16f
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 66 deletions.
91 changes: 52 additions & 39 deletions lib/timber-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class TimberPost extends TimberCore implements TimberCoreInterface {
*/
public $PostClass = 'TimberPost';

/**
* @var string $TermClass the name of the class to handle terms by default
*/
public $TermClass = 'TimberTerm';

/**
* @var string $object_type what does this class represent in WordPress terms?
*/
Expand All @@ -63,6 +68,7 @@ class TimberPost extends TimberCore implements TimberCoreInterface {
/**
* @internal
* @var array $_get_terms stores the results of a get_terms method call
* @deprecated
*/
protected $_get_terms;

Expand Down Expand Up @@ -773,56 +779,63 @@ function get_category( ) {

/**
* @internal
* @param string $tax
* @param string|array $tax
* @param bool $merge
* @param string $TermClass
* @return array
*/
function get_terms( $tax = '', $merge = true, $TermClass = 'TimberTerm' ) {
function get_terms( $tax = '', $merge = true, $TermClass = '' ) {

$TermClass = $TermClass ?: $this->TermClass;

if ( is_string($merge) && class_exists($merge) ) {
$TermClass = $merge;
}
if ( is_array($tax) ) {
$taxonomies = $tax;
}
if ( is_string($tax) ) {
if ( isset($this->_get_terms) && isset($this->_get_terms[$tax]) ) {
return $this->_get_terms[$tax];
if ( in_array($tax, array('all','any','')) ) {
$taxonomies = get_object_taxonomies($this->post_type);
} else {
$taxonomies = array($tax);
}
}
if ( !strlen($tax) || $tax == 'all' || $tax == 'any' ) {
$taxs = get_object_taxonomies($this->post_type);
} else if ( is_array($tax) ) {
$taxs = $tax;
} else {
$taxs = array($tax);
}
$ret = array();
foreach ( $taxs as $tax ) {
if ( $tax == 'tags' || $tax == 'tag' ) {
$tax = 'post_tag';
} else if ( $tax == 'categories' ) {
$tax = 'category';

$term_class_objects = array();

foreach ( $taxonomies as $taxonomy ) {
if ( in_array($taxonomy, array('tag','tags')) ) {
$taxonomy = 'post_tag';
}
$terms = wp_get_post_terms($this->ID, $tax);
if ( !is_array($terms) && is_object($terms) && get_class($terms) == 'WP_Error' ) {
//something is very wrong
TimberHelper::error_log('You have an error retrieving terms on a post in timber-post.php:628');
TimberHelper::error_log('tax = ' . $tax);
TimberHelper::error_log($terms);
} else {
foreach ( $terms as &$term ) {
$term = new $TermClass($term->term_id, $tax);
}
if ( $merge && is_array($terms) ) {
$ret = array_merge($ret, $terms);
} else if ( count($terms) ) {
$ret[$tax] = $terms;
}
if ( $taxonomy == 'categories' ) {
$taxonomy = 'category';
}

$terms = wp_get_post_terms($this->ID, $taxonomy);

if ( is_wp_error($terms) ) {
/* @var $terms WP_Error */
TimberHelper::error_log("Error retrieving terms for taxonomy '$taxonomy' on a post in timber-post.php");
TimberHelper::error_log('tax = ' . print_r($tax, true));
TimberHelper::error_log('WP_Error: ' . $terms->get_error_message());

return $term_class_objects;
}

// map over array of wordpress terms, and transform them into instances of the TermClass
$terms = array_map(function($term) use ($TermClass, $taxonomy) {
return call_user_func(array($TermClass, 'from'), $term->term_id, $taxonomy);
}, $terms);

if ( $merge && is_array($terms) ) {
$term_class_objects = array_merge($term_class_objects, $terms);
} else if ( count($terms) ) {
$term_class_objects[$taxonomy] = $terms;
}
}
if ( !isset($this->_get_terms) ) {
$this->_get_terms = array();
}
$this->_get_terms[$tax] = $ret;
return $ret;

return $term_class_objects;
}

/**
Expand Down Expand Up @@ -867,7 +880,7 @@ function get_image( $field ) {
* @return array
*/
function get_tags() {
return $this->get_terms('tags');
return $this->get_terms('post_tag');
}

/**
Expand Down Expand Up @@ -1326,7 +1339,7 @@ public function prev( $in_same_cat = false ) {
* Get the terms associated with the post
* This goes across all taxonomies by default
* @api
* @param string $tax What taxonomy to pull from, defaults to all of them. You can use custom ones, or built-in WordPress taxonomies (category, tag). Timber plays nice and figures out that tag/tags/post_tag are all the same (and categories/category), for custom taxonomies you're on your own.
* @param string|array $tax What taxonom(y|ies) to pull from. Defaults to all registered taxonomies for the post type. You can use custom ones, or built-in WordPress taxonomies (category, tag). Timber plays nice and figures out that tag/tags/post_tag are all the same (and categories/category), for custom taxonomies you're on your own.
* @param bool $merge Should the resulting array be one big one (true)? Or should it be an array of sub-arrays for each taxonomy (false)?
* @return array
*/
Expand Down
9 changes: 9 additions & 0 deletions lib/timber-term.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ public function __toString() {
return $this->name;
}

/**
* @param $tid
* @param $taxonomy
*
* @return static
*/
public static function from( $tid, $taxonomy ) {
return new static($tid, $taxonomy);
}


/* Setup
Expand Down
100 changes: 73 additions & 27 deletions tests/test-timber-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -452,42 +452,88 @@ function testPostCategory(){
$this->assertEquals('News', $post->category()->name);
}

function testPostCategories(){
$cats = array('News', 'Sports', 'Obits');
foreach($cats as &$cat){
$cat = wp_insert_term($cat, 'category');
}
function testPostCategories() {
$pid = $this->factory->post->create();
foreach($cats as $cat){
wp_set_object_terms($pid, $cat['term_id'], 'category', true);
}
$post = new TimberPost($pid);
$this->assertEquals(3, count($post->categories()));
}
$category_names = array('News', 'Sports', 'Obits');

function testPostTerms(){
register_taxonomy('team', 'post');
$teams = array('Patriots', 'Bills', 'Dolphins', 'Jets');
foreach($teams as &$team){
$team_terms[] = wp_insert_term($team, 'team');
// Uncategorized is applied by default
$default_categories = $post->categories();
$this->assertEquals('uncategorized', $default_categories[0]->slug);

foreach ( $category_names as $category_name ) {
$category_name = wp_insert_term($category_name, 'category');
wp_set_object_terms($pid, $category_name['term_id'], 'category', true);
}

$this->assertEquals(count($default_categories) + count($category_names), count($post->categories()));
}

function testPostTags() {
$pid = $this->factory->post->create();
foreach($team_terms as $team){
wp_set_object_terms($pid, $team['term_id'], 'team', true);
}
$post = new TimberPost($pid);
$teams = $post->terms('team');
$this->assertEquals(4, count($teams));
$tag = wp_insert_term('whatever', 'post_tag');
wp_set_object_terms($pid, $tag['term_id'], 'post_tag', true);
$tag_names = array('News', 'Sports', 'Obits');

foreach ( $tag_names as $tag_name ) {
$tag = wp_insert_term($tag_name, 'post_tag');
wp_set_object_terms($pid, $tag['term_id'], 'post_tag', true);
}

$this->assertEquals(count($tag_names), count($post->tags()));
}

function testPostTerms() {
$pid = $this->factory->post->create();
$post = new TimberPost($pid);
$this->assertEquals(6, count($post->terms()));
$tags = $post->tags();
$this->assertEquals('whatever', $tags[0]->slug);
$tags = $post->terms('tag');
$this->assertEquals('whatever', $tags[0]->slug);

// create a new tag and associate it with the post
$dummy_tag = wp_insert_term('whatever', 'post_tag');
wp_set_object_terms($pid, $dummy_tag['term_id'], 'post_tag', true);

// test expected tags
$timber_tags = $post->terms('post_tag');
$dummy_timber_tag = new TimberTerm($dummy_tag['term_id'], 'post_tag');
$this->assertEquals('whatever', $timber_tags[0]->slug);
$this->assertEquals($dummy_timber_tag, $timber_tags[0]);

// register a custom taxonomy, create some terms in it and associate to post
register_taxonomy('team', 'post');
$team_names = array('Patriots', 'Bills', 'Dolphins', 'Jets');

foreach ( $team_names as $team_name ) {
$team_term = wp_insert_term($team_name, 'team');
wp_set_object_terms($pid, $team_term['term_id'], 'team', true);
}

$this->assertEquals(count($team_names), count($post->terms('team')));

// check presence of specific terms
$this->assertTrue($post->has_term('Uncategorized'));
$this->assertTrue($post->has_term('whatever'));
$this->assertTrue($post->has_term('Dolphins'));
$this->assertTrue($post->has_term('Patriots', 'team'));

// 4 teams + 1 tag + default category (Uncategorized)
$this->assertEquals(6, count($post->terms()));

// test tags method - wrapper for $this->get_terms('tags')
$this->assertEquals($post->tags(), $post->terms('tag'));
$this->assertEquals($post->tags(), $post->terms('tags'));
$this->assertEquals($post->tags(), $post->terms('post_tag'));

// test categories method - wrapper for $this->get_terms('category')
$this->assertEquals($post->categories(), $post->terms('category'));
$this->assertEquals($post->categories(), $post->terms('categories'));

// test using an array of taxonomies
$post_tag_terms = $post->terms(array('post_tag'));
$this->assertEquals(1, count($post_tag_terms));
$post_team_terms = $post->terms(array('team'));
$this->assertEquals(count($team_names), count($post_team_terms));

// test multiple taxonomies
$post_tag_and_team_terms = $post->terms(array('post_tag','team'));
$this->assertEquals(count($post_tag_terms) + count($post_team_terms), count($post_tag_and_team_terms));
}

function testPostContentLength() {
Expand Down

0 comments on commit f72c16f

Please sign in to comment.