aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SemanticScuttle/Service/Bookmark.php57
-rw-r--r--tests/BookmarkTest.php80
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)
+ )
+ );
+ }
+
+
+
}