aboutsummaryrefslogtreecommitdiff
path: root/src/SemanticScuttle/Service
diff options
context:
space:
mode:
Diffstat (limited to 'src/SemanticScuttle/Service')
-rw-r--r--src/SemanticScuttle/Service/Bookmark.php228
-rw-r--r--src/SemanticScuttle/Service/Bookmark2Tag.php75
-rw-r--r--src/SemanticScuttle/Service/Factory.php6
-rw-r--r--src/SemanticScuttle/Service/User.php38
4 files changed, 285 insertions, 62 deletions
diff --git a/src/SemanticScuttle/Service/Bookmark.php b/src/SemanticScuttle/Service/Bookmark.php
index 0ac1855..364b1a0 100644
--- a/src/SemanticScuttle/Service/Bookmark.php
+++ b/src/SemanticScuttle/Service/Bookmark.php
@@ -178,8 +178,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
*/
public function getBookmarkByAddress($address)
{
- $hash = md5($address);
- return $this->getBookmarkByHash($hash);
+ return $this->getBookmarkByHash($this->getHash($address));
}
@@ -188,10 +187,12 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
* Retrieves a bookmark with the given hash.
* DOES NOT RESPECT PRIVACY SETTINGS!
*
- * @param string $hash URL hash (MD5)
+ * @param string $hash URL hash
*
* @return mixed Array with bookmark data or false in case
* of an error (i.e. not found).
+ *
+ * @see getHash()
*/
public function getBookmarkByHash($hash)
{
@@ -201,6 +202,25 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
/**
+ * Returns the hash value of a given address.
+ *
+ * @param string $address URL to hash
+ * @param boolean $bNormalize If the address shall be normalized before
+ * being hashed
+ *
+ * @return string Hash value
+ */
+ public function getHash($address, $bNormalize = true)
+ {
+ if ($bNormalize) {
+ $address = $this->normalize($address);
+ }
+ return md5($address);
+ }
+
+
+
+ /**
* Retrieves a bookmark that has a given short
* name.
*
@@ -284,15 +304,18 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
}
$userservice = SemanticScuttle_Service_Factory::get('User');
- $user = $userservice->getCurrentUser();
+ $user = $userservice->getCurrentObjectUser();
+ if ($user === null) {
+ return false;
+ }
//user has to be either admin, or owner
if ($GLOBALS['adminsCanModifyBookmarksFromOtherUsers']
- && $userservice->isAdmin($user)
+ && $userservice->isAdmin($user->username)
) {
return true;
} else {
- return ($bookmark['uId'] == $user['uId']);
+ return ($bookmark['uId'] == $user->id);
}
}
@@ -309,20 +332,20 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
* @return boolean True when the bookmark with the given URL
* exists for the user, false if not.
*/
- function bookmarkExists($address = false, $uid = null)
+ public function bookmarkExists($address = false, $uid = null)
{
if (!$address) {
return false;
}
- $address = $this->normalize($address);
-
- $crit = array('bHash' => md5($address));
+ $crit = array('bHash' => $this->getHash($address));
if (isset ($uid)) {
$crit['uId'] = $uid;
}
- $sql = 'SELECT COUNT(*) as "0" FROM '. $GLOBALS['tableprefix'] .'bookmarks WHERE '. $this->db->sql_build_array('SELECT', $crit);
+ $sql = 'SELECT COUNT(*) as "0" FROM '
+ . $GLOBALS['tableprefix'] . 'bookmarks'
+ . ' WHERE '. $this->db->sql_build_array('SELECT', $crit);
if (!($dbresult = $this->db->sql_query($sql))) {
message_die(
@@ -342,6 +365,60 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
/**
+ * Checks if the given addresses exist
+ *
+ * @param array $addresses Array of addresses
+ * @param integer $uid User ID the addresses shall belong to
+ *
+ * @return array Array with addresses as keys, true/false for existence
+ * as value
+ */
+ public function bookmarksExist($addresses, $uid = null)
+ {
+ if (count($addresses) == 0) {
+ return array();
+ }
+
+ $hashes = array();
+ $sql = '(0';
+ foreach ($addresses as $key => $address) {
+ $hash = $this->getHash($address);
+ $hashes[$hash] = $address;
+ $sql .= ' OR bHash = "'
+ . $this->db->sql_escape($hash)
+ . '"';
+ }
+ $sql .= ')';
+ if ($uid !== null) {
+ $sql .= ' AND uId = ' . intval($uid);
+ }
+
+ $sql = 'SELECT bHash, COUNT(*) as "count" FROM '
+ . $this->getTableName()
+ . ' WHERE ' . $sql
+ . ' GROUP BY bHash';
+
+ if (!($dbresult = $this->db->sql_query($sql))) {
+ message_die(
+ GENERAL_ERROR, 'Could not get bookmark counts', '',
+ __LINE__, __FILE__, $sql, $this->db
+ );
+ }
+
+ $existence = array_combine(
+ $addresses,
+ array_fill(0, count($addresses), false)
+ );
+ while ($row = $this->db->sql_fetchrow($dbresult)) {
+ $existence[$hashes[$row['bHash']]] = $row['count'] > 0;
+ }
+
+ return $existence;
+ }
+
+
+
+ /**
* Adds a bookmark to the database.
*
* @param string $address Full URL of the bookmark
@@ -402,17 +479,17 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
// Set up the SQL insert statement and execute it.
$values = array(
- 'uId' => intval($sId),
- 'bIp' => $ip,
- 'bDatetime' => $datetime,
- 'bModified' => $datetime,
- 'bTitle' => $title,
- 'bAddress' => $address,
+ 'uId' => intval($sId),
+ 'bIp' => $ip,
+ 'bDatetime' => $datetime,
+ 'bModified' => $datetime,
+ 'bTitle' => $title,
+ 'bAddress' => $address,
'bDescription' => $description,
'bPrivateNote' => $privateNote,
- 'bStatus' => intval($status),
- 'bHash' => md5($address),
- 'bShort' => $short
+ 'bStatus' => intval($status),
+ 'bHash' => $this->getHash($address),
+ 'bShort' => $short
);
$sql = 'INSERT INTO '. $this->getTableName()
@@ -522,14 +599,14 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
// Set up the SQL update statement and execute it.
$updates = array(
- 'bModified' => $moddatetime,
- 'bTitle' => $title,
- 'bAddress' => $address,
+ 'bModified' => $moddatetime,
+ 'bTitle' => $title,
+ 'bAddress' => $address,
'bDescription' => $description,
'bPrivateNote' => $privateNote,
- 'bStatus' => $status,
- 'bHash' => md5($address),
- 'bShort' => $short
+ 'bStatus' => $status,
+ 'bHash' => $this->getHash($address, false),
+ 'bShort' => $short
);
if (!is_null($date)) {
@@ -804,10 +881,17 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$total = $row['total'];
$this->db->sql_freeresult($totalresult);
- $bookmarks = array();
- while ($row = & $this->db->sql_fetchrow($dbresult)) {
- $row['tags'] = $b2tservice->getTagsForBookmark(intval($row['bId']));
- $bookmarks[] = $row;
+ $bookmarks = array();
+ $bookmarkids = array();
+ while ($row = $this->db->sql_fetchrow($dbresult)) {
+ $bookmarks[] = $row;
+ $bookmarkids[] = $row['bId'];
+ }
+ if (count($bookmarkids)) {
+ $tags = $b2tservice->getTagsForBookmarks($bookmarkids);
+ foreach ($bookmarks as &$bookmark) {
+ $bookmark['tags'] = $tags[$bookmark['bId']];
+ }
}
$this->db->sql_freeresult($dbresult);
@@ -889,36 +973,88 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
- function countOthers($address)
+ /**
+ * Counts the number of bookmarks that have the same 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($addresses)
{
- if (!$address) {
+ if (!$addresses) {
return false;
}
+ $bArray = is_array($addresses);
- $userservice = SemanticScuttle_Service_Factory :: get('User');
- $sId = $userservice->getCurrentUserId();
+ $us = SemanticScuttle_Service_Factory::get('User');
+ $sId = (int)$us->getCurrentUserId();
- if ($userservice->isLoggedOn()) {
- // All public bookmarks, user's own bookmarks and any shared with user
- $privacy = ' AND ((B.bStatus = 0) OR (B.uId = '. $sId .')';
- $watchnames = $userservice->getWatchNames($sId, true);
- foreach($watchnames as $watchuser) {
- $privacy .= ' OR (U.username = "'. $watchuser .'" AND B.bStatus = 1)';
+ if ($us->isLoggedOn()) {
+ //All public bookmarks, user's own bookmarks
+ // and any shared with our user
+ $privacy = ' AND ((B.bStatus = 0) OR (B.uId = ' . $sId . ')';
+ $watchnames = $us->getWatchNames($sId, true);
+ foreach ($watchnames as $watchuser) {
+ $privacy .= ' OR (U.username = "'
+ . $this->db->sql_escape($watchuser)
+ . '" AND B.bStatus = 1)';
}
$privacy .= ')';
} else {
- // Just public bookmarks
+ //Just public bookmarks
$privacy = ' AND B.bStatus = 0';
}
- $sql = 'SELECT COUNT(*) FROM '. $userservice->getTableName() .' AS U, '. $GLOBALS['tableprefix'] .'bookmarks AS B WHERE U.'. $userservice->getFieldName('primary') .' = B.uId AND B.bHash = "'. md5($address) .'"'. $privacy;
- if (!($dbresult = & $this->db->sql_query($sql))) {
- message_die(GENERAL_ERROR, 'Could not get vars', '', __LINE__, __FILE__, $sql, $this->db);
+ $addressesSql = ' AND (0';
+ foreach ((array)$addresses as $address) {
+ $addressesSql .= ' OR B.bHash = "'
+ . $this->db->sql_escape($this->getHash($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'
+ . $addressesSql
+ . $privacy
+ . ' GROUP BY B.bHash';
+
+ if (!($dbresult = $this->db->sql_query($sql))) {
+ message_die(
+ GENERAL_ERROR, 'Could not get other count',
+ '', __LINE__, __FILE__, $sql, $this->db
+ );
}
- $output = $this->db->sql_fetchfield(0, 0) - 1;
+ //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 $output;
+
+ return $bArray ? $counts : reset($counts);
}
diff --git a/src/SemanticScuttle/Service/Bookmark2Tag.php b/src/SemanticScuttle/Service/Bookmark2Tag.php
index 8e5cb22..4d2c969 100644
--- a/src/SemanticScuttle/Service/Bookmark2Tag.php
+++ b/src/SemanticScuttle/Service/Bookmark2Tag.php
@@ -266,27 +266,90 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
return true;
}
- function &getTagsForBookmark($bookmarkid) {
+
+ /**
+ * Retrieves all tags for a given bookmark except system tags.
+ *
+ * @param integer $bookmarkid ID of the bookmark
+ *
+ * @return array Array of tags
+ */
+ public function getTagsForBookmark($bookmarkid)
+ {
if (!is_numeric($bookmarkid)) {
- message_die(GENERAL_ERROR, 'Could not get tags (invalid bookmarkid)', '', __LINE__, __FILE__, $query);
+ message_die(
+ GENERAL_ERROR, 'Could not get tags (invalid bookmarkid)',
+ '', __LINE__, __FILE__, $query
+ );
return false;
}
- $query = 'SELECT tag FROM '. $this->getTableName() .' WHERE bId = '. intval($bookmarkid) .' AND LEFT(tag, 7) <> "system:" ORDER BY id ASC';
+ $query = 'SELECT tag FROM ' . $this->getTableName()
+ . ' WHERE bId = ' . intval($bookmarkid)
+ . ' AND LEFT(tag, 7) <> "system:"'
+ . ' ORDER BY id ASC';
- if (!($dbresult =& $this->db->sql_query($query))) {
- message_die(GENERAL_ERROR, 'Could not get tags', '', __LINE__, __FILE__, $query, $this->db);
+ if (!($dbresult = $this->db->sql_query($query))) {
+ message_die(
+ GENERAL_ERROR, 'Could not get tags',
+ '', __LINE__, __FILE__, $query, $this->db
+ );
return false;
}
$tags = array();
- while ($row =& $this->db->sql_fetchrow($dbresult)) {
+ while ($row = $this->db->sql_fetchrow($dbresult)) {
$tags[] = $row['tag'];
}
$this->db->sql_freeresult($dbresult);
return $tags;
}
+
+ /**
+ * Retrieves all tags for an array of bookmark IDs
+ *
+ * @param array $bookmarkids Array of bookmark IDs
+ *
+ * @return array Array of tag arrays. Key is bookmark ID.
+ */
+ public function getTagsForBookmarks($bookmarkids)
+ {
+ if (!is_array($bookmarkids)) {
+ message_die(
+ GENERAL_ERROR, 'Could not get tags (invalid bookmarkids)',
+ '', __LINE__, __FILE__, $query
+ );
+ return false;
+ } else if (count($bookmarkids) == 0) {
+ return array();
+ }
+
+ $query = 'SELECT tag, bId FROM ' . $this->getTableName()
+ . ' WHERE bId IN (' . implode(',', $bookmarkids) . ')'
+ . ' AND LEFT(tag, 7) <> "system:"'
+ . ' ORDER BY id, bId ASC';
+
+ if (!($dbresult = $this->db->sql_query($query))) {
+ message_die(
+ GENERAL_ERROR, 'Could not get tags',
+ '', __LINE__, __FILE__, $query, $this->db
+ );
+ return false;
+ }
+
+ $tags = array_combine(
+ $bookmarkids,
+ array_fill(0, count($bookmarkids), array())
+ );
+ while ($row = $this->db->sql_fetchrow($dbresult)) {
+ $tags[$row['bId']][] = $row['tag'];
+ }
+ $this->db->sql_freeresult($dbresult);
+ return $tags;
+ }
+
+
function &getTags($userid = NULL) {
$userservice =SemanticScuttle_Service_Factory::get('User');
$logged_on_user = $userservice->getCurrentUserId();
diff --git a/src/SemanticScuttle/Service/Factory.php b/src/SemanticScuttle/Service/Factory.php
index 9b79e6c..d7ff1d4 100644
--- a/src/SemanticScuttle/Service/Factory.php
+++ b/src/SemanticScuttle/Service/Factory.php
@@ -113,7 +113,7 @@ class SemanticScuttle_Service_Factory
protected static function loadDb()
{
global $dbhost, $dbuser, $dbpass, $dbname,
- $dbport, $dbpersist, $dbtype;
+ $dbport, $dbpersist, $dbtype, $dbneedssetnames;
if (self::$db !== null) {
return;
@@ -130,7 +130,9 @@ class SemanticScuttle_Service_Factory
self::$db
);
}
- $db->sql_query('SET NAMES UTF8');
+
+ $dbneedssetnames && $db->sql_query('SET NAMES UTF8');
+
self::$db = $db;
}
diff --git a/src/SemanticScuttle/Service/User.php b/src/SemanticScuttle/Service/User.php
index cedde92..281c18c 100644
--- a/src/SemanticScuttle/Service/User.php
+++ b/src/SemanticScuttle/Service/User.php
@@ -76,15 +76,28 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
$this->updateSessionStability();
}
- function _getuser($fieldname, $value) {
- $query = 'SELECT * FROM '. $this->getTableName() .' WHERE '. $fieldname .' = "'. $this->db->sql_escape($value) .'"';
+ /**
+ * Fetches the desired user row from database, specified by column and value
+ *
+ * @param string $fieldname Name of database column to identify user
+ * @param string $value Value of $fieldname
+ *
+ * @return array Database row or boolean false
+ */
+ protected function _getuser($fieldname, $value)
+ {
+ $query = 'SELECT * FROM '. $this->getTableName()
+ . ' WHERE ' . $fieldname . ' = "' . $this->db->sql_escape($value) . '"';
- if (! ($dbresult =& $this->db->sql_query($query)) ) {
- message_die(GENERAL_ERROR, 'Could not get user', '', __LINE__, __FILE__, $query, $this->db);
+ if (!($dbresult = $this->db->sql_query($query)) ) {
+ message_die(
+ GENERAL_ERROR, 'Could not get user',
+ '', __LINE__, __FILE__, $query, $this->db
+ );
return false;
}
- $row =& $this->db->sql_fetchrow($dbresult);
+ $row = $this->db->sql_fetchrow($dbresult);
$this->db->sql_freeresult($dbresult);
if ($row) {
return $row;
@@ -305,9 +318,14 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
/**
* Checks if the given user is an administrator.
* Uses global admin_users property containing admin
- * user names
+ * user names.
+ *
+ * Passing the user id makes this function load the user
+ * from database. For efficiency reasons, try to pass
+ * the user name or database row.
*
- * @param integer|array $user User ID or user row from DB
+ * @param integer|array|string $user User ID or user row from DB
+ * or user name
*
* @return boolean True if the user is admin
*/
@@ -315,10 +333,13 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
{
if (is_numeric($user)) {
$user = $this->getUser($user);
+ $user = $user['username'];
+ } else if (is_array($user)) {
+ $user = $user['username'];
}
if (isset($GLOBALS['admin_users'])
- && in_array($user['username'], $GLOBALS['admin_users'])
+ && in_array($user, $GLOBALS['admin_users'])
) {
return true;
} else {
@@ -386,6 +407,7 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
}
//reload user object
$this->getCurrentUser(true);
+ $this->getCurrentObjectUser(true);
}