diff options
-rw-r--r-- | src/SemanticScuttle/Service/Bookmark.php | 57 | ||||
-rw-r--r-- | tests/BookmarkTest.php | 80 |
2 files changed, 124 insertions, 13 deletions
diff --git a/src/SemanticScuttle/Service/Bookmark.php b/src/SemanticScuttle/Service/Bookmark.php index 05ea060..c7bfb3b 100644 --- a/src/SemanticScuttle/Service/Bookmark.php +++ b/src/SemanticScuttle/Service/Bookmark.php @@ -891,17 +891,29 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService /** * Counts the number of bookmarks that have the same address - * as the given address - * - * @param string $address Address/URL to look for - * - * @return integer Number of bookmarks minus one that have the address + * as the given address. + * + * @internal + * We do support fetching counts for multiple addresses at once + * because that allows us to reduce the number of queries + * we need in the web interface when displaying i.e. + * 10 bookmarks - only one SQL query is needed then. + * + * @param string|array $addresses Address/URL to look for, string + * of one address or array with + * multiple ones + * + * @return integer Number of bookmarks minus one that have the address. + * In case $addresses was an array, key-value array + * with key being the address, value said number of + * bookmarks */ - public function countOthers($address) + public function countOthers($addresses) { - if (!$address) { + if (!$addresses) { return false; } + $bArray = is_array($addresses); $us = SemanticScuttle_Service_Factory::get('User'); $sId = (int)$us->getCurrentUserId(); @@ -922,12 +934,22 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService $privacy = ' AND B.bStatus = 0'; } - $sql = 'SELECT COUNT(*) as "0" FROM ' + $addressesSql = ' AND (0'; + foreach ((array)$addresses as $address) { + $addressesSql .= ' OR B.bHash = "' + . $this->db->sql_escape(md5($address)) + . '"'; + } + $addressesSql .= ')'; + + + $sql = 'SELECT B.bAddress, COUNT(*) as count FROM ' . $us->getTableName() . ' AS U' . ', '. $GLOBALS['tableprefix'] . 'bookmarks AS B' . ' WHERE U.'. $us->getFieldName('primary') .' = B.uId' - . ' AND B.bHash = "'. md5($address) . '"' - . $privacy; + . $addressesSql + . $privacy + . ' GROUP BY B.bHash'; if (!($dbresult = $this->db->sql_query($sql))) { message_die( @@ -936,10 +958,19 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService ); } - $count = $this->db->sql_fetchfield(0, 0); - $count = ($count > 0) ? $count - 1 : (int)$count; + //be sure we also list urls in our array + // that are not found in the database + $counts = array_combine( + (array)$addresses, + array_fill(0, count((array)$addresses), 0) + ); + while ($row = $this->db->sql_fetchrow($dbresult)) { + $counts[$row['bAddress']] + = $row['count'] > 0 ? $row['count'] - 1 : 0; + } $this->db->sql_freeresult($dbresult); - return $count; + + return $bArray ? $counts : reset($counts); } diff --git a/tests/BookmarkTest.php b/tests/BookmarkTest.php index d791b9e..69e6e8a 100644 --- a/tests/BookmarkTest.php +++ b/tests/BookmarkTest.php @@ -943,6 +943,86 @@ class BookmarkTest extends TestBase + /** + * Test what countOther() returns when multiple addresses are + * passed to it and none of them exists. + * + * @return void + */ + public function testCountOthersArrayNone() + { + $this->assertEquals( + array('1' => 0, '2' => 0, '3' => 0), + $this->bs->countOthers(array('1', '2', '3')) + ); + } + + + + /** + * Test what countOther() returns when multiple addresses are + * passed to it and only one of them exists. + * + * @return void + */ + public function testCountOthersArrayOneNone() + { + $uid = $this->addUser(); + $uid2 = $this->addUser(); + $address1 = 'http://example.org/1'; + $address2 = 'http://example.org/2'; + $this->addBookmark($uid, $address1); + $this->addBookmark($uid, $address2); + $this->addBookmark($uid2, $address1); + $this->assertEquals( + array( + $address1 => 1, + $address2 => 0 + ), + $this->bs->countOthers( + array($address1, $address2) + ) + ); + } + + + + /** + * Test what countOther() returns when multiple addresses are passed + * to it and both of them exist with different numbers for each. + * + * @return void + */ + public function testCountOthersArrayTwoOne() + { + $uid = $this->addUser(); + $uid2 = $this->addUser(); + $uid3 = $this->addUser(); + + $address1 = 'http://example.org/1'; + $address2 = 'http://example.org/2'; + + $this->addBookmark($uid, $address1); + $this->addBookmark($uid, $address2); + + $this->addBookmark($uid2, $address1); + $this->addBookmark($uid2, $address2); + + $this->addBookmark($uid3, $address1); + + $this->assertEquals( + array( + $address1 => 2, + $address2 => 1 + ), + $this->bs->countOthers( + array($address1, $address2) + ) + ); + } + + + } |