From cd64fbf416c818ddb46f0356cae64509efcf7ae8 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Mon, 15 Feb 2010 22:06:59 -0500 Subject: [PATCH] a bunch of tag and database changes --- classes/ComicPressComicPost.inc | 2 +- classes/ComicPressDBInterface.inc | 82 ++++++++++++++----- classes/ComicPressStoryline.inc | 4 + classes/ComicPressTagBuilder.inc | 35 +++++++- .../backends/ComicPressBackendFilesystem.inc | 1 + test/ComicPressDBInterfaceTest.php | 18 +++- test/ComicPressTagBuilderTest.php | 67 ++++++++++++--- 7 files changed, 174 insertions(+), 35 deletions(-) diff --git a/classes/ComicPressComicPost.inc b/classes/ComicPressComicPost.inc index 618ca9c..1324464 100644 --- a/classes/ComicPressComicPost.inc +++ b/classes/ComicPressComicPost.inc @@ -31,7 +31,7 @@ class ComicPressComicPost { /** * Normalize the ordering of attachments in this post. - * If images have beed added or removed, intelligently update the metadata. + * If images have been added or removed, intelligently update the metadata. * @param boolean $skip_checks If true, only return the post metadata, assuming that everything is correct. Do not use anywhere in the admin interface! * @return array The normalized data, which is also written to the post's metadata if $skip_checks is false. */ diff --git a/classes/ComicPressDBInterface.inc b/classes/ComicPressDBInterface.inc index 61d6d4d..ebb68cd 100644 --- a/classes/ComicPressDBInterface.inc +++ b/classes/ComicPressDBInterface.inc @@ -36,43 +36,55 @@ class ComicPressDBInterface { $wp_query->in_the_loop = $this->in_the_loop; } + function ensure_count($count) { + return max((int)$count, 1); + } + // @codeCoverageIgnoreStart /** * Find the terminal post in a specific category. */ - function get_terminal_post_in_categories($categories, $first = true) { + function get_terminal_post_in_categories($categories, $first = true, $count = false) { $this->_prepare_wp_query(); + $count = $this->ensure_count($count); + if (!is_array($categories)) { $categories = array($categories); } $sort_order = $first ? "asc" : "desc"; $terminal_comic_query = new WP_Query(); $terminal_comic_query->query(array( - 'showposts' => 1, + 'showposts' => $count, 'order' => $sort_order, - 'category__in' => $categories + 'category__in' => $categories, + 'post_status' => 'publish' )); - $post = false; + $result = false; + if ($terminal_comic_query->have_posts()) { - $post = reset($terminal_comic_query->posts); + if ($count == 1) { + $result = reset($terminal_comic_query->posts); + } else { + $result = $terminal_comic_query->posts; + } } $this->_reset_wp_query(); - return $post; + return $result; } /** * Get the first comic in a category. */ - function get_first_post($categories) { - return $this->get_terminal_post_in_categories($categories); + function get_first_post($categories, $reference_post = null, $count = false) { + return $this->get_terminal_post_in_categories($categories, true, $count); } /** * Get the last comic in a category. */ - function get_last_post($categories) { + function get_last_post($categories, $reference_post = null, $count = false) { return $this->get_terminal_post_in_categories($categories, false); } @@ -80,29 +92,61 @@ class ComicPressDBInterface { * Get the comic post adjacent to the current comic. * Wrapper around get_adjacent_post(). Don't unit test this method. */ - function get_adjacent_post($categories, $next = false, $override_post = null) { - global $post; + function get_adjacent_post($categories, $next = false, $override_post = null, $count = false) { + global $wpdb, $post; - $this->_prepare_wp_query(); - if (!is_null($override_post)) { $temp_post = $post; $post = $override_post; } + $count = $this->ensure_count($count); - $result = get_adjacent_post(false, implode(" and ", $this->_get_categories_to_exclude($categories)), !$next); + $post_to_use = (!is_null($override_post)) ? $override_post : $post; - $this->_reset_wp_query(); - if (!is_null($override_post)) { $post = $temp_post; } + $op = ($next ? '>' : '<'); + $order = ($next ? 'ASC' : 'DESC'); - return empty($result) ? false : $result; + $query = $wpdb->prepare("SELECT p.* FROM $wpdb->posts AS p + INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id + INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id + WHERE p.post_date ${op} %s + AND p.post_type = 'post' + AND p.post_status = 'publish' + AND tt.taxonomy = 'category' + AND tt.term_id IN (%s) + ORDER BY p.post_date ${order} LIMIT %d", + $post_to_use->post_date, + implode(',', $categories), + $count); + + $query_key = 'comicpress_adjacent_post_' . md5($query); + $result = wp_cache_get($query_key, 'counts'); + if ($result !== false) { + return $result; + } + + $result = $wpdb->get_results($query); + + if (!empty($result)) { + if ($count == 1) { $result = $result[0]; } + + wp_cache_set($query_key, $result, 'counts'); + + return $result; + } else { + return ($count == 1) ? false : array(); + } } /** * Get the previous comic from the current one. */ - function get_previous_post($categories = null, $override_post = null) { return $this->get_adjacent_post($categories, false, $override_post); } + function get_previous_post($categories = null, $override_post = null, $count = false) { + return $this->get_adjacent_post($categories, false, $override_post, $count); + } /** * Get the next comic from the current one. */ - function get_next_post($categories = null, $override_post = null) { return $this->get_adjacent_post($categories, true, $override_post); } + function get_next_post($categories = null, $override_post = null, $count = false) { + return $this->get_adjacent_post($categories, true, $override_post, $count); + } function get_parent_child_category_ids() { global $wpdb; diff --git a/classes/ComicPressStoryline.inc b/classes/ComicPressStoryline.inc index 2c66dac..d7cd531 100644 --- a/classes/ComicPressStoryline.inc +++ b/classes/ComicPressStoryline.inc @@ -558,6 +558,10 @@ class ComicPressStoryline { return $this; } + function _find_all() { + return array_keys($this->_structure); + } + function _find_level_or_above($level = null) { $found = array(); foreach ($this->_structure as $category_id => $info) { diff --git a/classes/ComicPressTagBuilder.inc b/classes/ComicPressTagBuilder.inc index 5ce272e..af4b1fa 100644 --- a/classes/ComicPressTagBuilder.inc +++ b/classes/ComicPressTagBuilder.inc @@ -184,7 +184,22 @@ class ComicPressTagBuilder { } return isset($arguments[0]) ? get_category($id) : $id; } else { - $this->post = call_user_func(array($this->dbi, "get_${method}_post"), $this->storyline->build_from_restrictions($this->restrictions), $this->parent_post); + if (empty($this->restrictions)) { + $this->restrictions = array( + array('from_post', $this->parent_post->ID) + ); + } + + $count = (isset($arguments[0])) ? (int)$arguments[0] : false; + if ($count < 2) { + $count = false; + } + $result = call_user_func(array($this->dbi, "get_${method}_post"), $this->storyline->build_from_restrictions($this->restrictions), $this->parent_post, $count); + if (is_array($result)) { + return $result; + } else { + $this->post = $result; + } } $ok = true; break; @@ -192,7 +207,12 @@ class ComicPressTagBuilder { if (!isset($arguments[0])) { throw new ComicPressException('Need to specify a category'); } - $this->restrictions[] = array('child_of', $arguments[0]); + if ($arguments[0] == 'all') { + $this->restrictions[] = array('all', true); + } else { + $this->restrictions[] = array('child_of', $arguments[0]); + } + $ok = true; break; case 'id': @@ -209,7 +229,16 @@ class ComicPressTagBuilder { case 'permalink': return get_permalink($this->post->ID); case 'post': - return $this->post; + if (isset($arguments[0])) { + if (!is_object($arguments[0]) && !is_array($arguments[0])) { + throw new ComicPressException('Provided post needs to be an array or object'); + } + $this->post = $arguments[0]; + $ok = true; + } else { + return $this->post; + } + break; case 'media': if (isset($this->post)) { $comic_post = $this->_new_comicpresscomicpost($this->post); diff --git a/classes/backends/ComicPressBackendFilesystem.inc b/classes/backends/ComicPressBackendFilesystem.inc index 67eb63f..638fce0 100644 --- a/classes/backends/ComicPressBackendFilesystem.inc +++ b/classes/backends/ComicPressBackendFilesystem.inc @@ -110,6 +110,7 @@ class ComicPressBackendFilesystemFactory { } $all_patterns = array_merge($all_patterns, $patterns); } + if (($filename_pattern = $this->has_common_filename_pattern($all_patterns)) !== false) { if (!empty($files)) { $grouped_by_root = $this->group_by_root($filename_pattern, $files); diff --git a/test/ComicPressDBInterfaceTest.php b/test/ComicPressDBInterfaceTest.php index 77d010d..54a90e1 100644 --- a/test/ComicPressDBInterfaceTest.php +++ b/test/ComicPressDBInterfaceTest.php @@ -80,6 +80,22 @@ class ComicPressDBInterfaceTest extends PHPUnit_Framework_TestCase { $this->assertTrue(false === $wp_query->is_single); $this->assertTrue(false === $wp_query->in_the_loop); } + + function providerTestEnsureCount() { + return array( + array(0, 1), + array(1, 1), + array(2, 2), + array('test', 1), + array(false, 1) + ); + } + + /** + * @dataProvider providerTestEnsureCount + */ + function testEnsureCount($input, $expected_output) { + $this->assertEquals($expected_output, ComicPressDBInterface::ensure_count($input)); + } } -?> diff --git a/test/ComicPressTagBuilderTest.php b/test/ComicPressTagBuilderTest.php index 8b1ce65..2ee7480 100644 --- a/test/ComicPressTagBuilderTest.php +++ b/test/ComicPressTagBuilderTest.php @@ -15,44 +15,46 @@ class ComicPressTagBuilderTest extends PHPUnit_Framework_TestCase { } function providerTestBuilder() { + $p = (object)array('ID' => 1); + return array( array( array( array('next') ), - array('get_next_post', array(1,2,3,4,5), 'current-post') + array('get_next_post', array(1), $p) ), array( array( array('previous'), ), - array('get_previous_post', array(1,2,3,4,5), 'current-post') + array('get_previous_post', array(1), $p) ), array( array( array('first'), ), - array('get_first_post', array(1,2,3,4,5), 'current-post') + array('get_first_post', array(1), $p) ), array( array( array('last'), ), - array('get_last_post', array(1,2,3,4,5), 'current-post') + array('get_last_post', array(1), $p) ), array( array( - array('in', 'category-1'), + array('in', 'category-2'), array('last') ), - array('get_last_post', array(1), 'current-post') + array('get_last_post', array(2,3,4), $p) ), array( array( array('in', 2), array('first') ), - array('get_first_post', array(2,3,4), 'current-post') + array('get_first_post', array(2,3,4), $p) ), array( array( @@ -60,7 +62,7 @@ class ComicPressTagBuilderTest extends PHPUnit_Framework_TestCase { array('first'), array('setup') ), - array('get_first_post', array(2,3,4), 'current-post'), + array('get_first_post', array(2,3,4), $p), true ), array( @@ -71,16 +73,32 @@ class ComicPressTagBuilderTest extends PHPUnit_Framework_TestCase { ), array('get_first_post', array(2,3,4), (object)array('other-post' => 'post')), ), + array( + array( + array('next', 3) + ), + array('get_next_post', array(1), $p, 3), + false, + true + ), + array( + array( + array('in', 'all'), + array('first') + ), + array('get_first_post', array(1,2,3,4,5), $p) + ), ); } /** * @dataProvider providerTestBuilder */ - // TODO same_category - function testStorylineBuilder($instructions, $expected_dbi_call, $expects_setup_postdata = false) { + function testStorylineBuilder($instructions, $expected_dbi_call, $expects_setup_postdata = false, $returns_array = false) { global $post, $wp_test_expectations; - $post = 'current-post'; + $post = (object)array('ID' => 1); + + wp_set_post_categories(1, array(1)); $method = array_shift($expected_dbi_call); @@ -92,6 +110,10 @@ class ComicPressTagBuilderTest extends PHPUnit_Framework_TestCase { call_user_func(array($expectation, 'will'), $this->returnValue('new-post')); } + if ($returns_array) { + call_user_func(array($expectation, 'will'), $this->returnValue(array('new-post'))); + } + $core = new ComicPressTagBuilderFactory($dbi); $storyline = new ComicPressStoryline(); @@ -675,4 +697,27 @@ class ComicPressTagBuilderTest extends PHPUnit_Framework_TestCase { $comicpress = ComicPress::get_instance(true); } + + function providerTestSetPostExpectations() { + return array( + array('test'), + array(123) + ); + } + + /** + * @expectedException ComicPressException + * @dataProvider providerTestSetPostExpectations + */ + function testSetPostExceptions($input) { + $core = new ComicPressTagBuilderFactory(); + $core->post($input); + } + + function testSetPost() { + $core = new ComicPressTagBuilderFactory(); + $core = $core->post((object)array('ID' => 1)); + + $this->assertEquals((object)array('ID' => 1), $core->post); + } }