Merge branch 'master' into pearpkg

This commit is contained in:
Christian Weiske 2010-08-12 20:49:35 +02:00
commit 0a8dadf87e
57 changed files with 3304 additions and 473 deletions

View file

@ -8,8 +8,8 @@
--> -->
<property file="build.properties" /> <property file="build.properties" />
<property name="version-m" value="0.96" /> <property name="version-m" value="0.97" />
<property name="version" value="0.96.1" /> <property name="version" value="0.97.0" />
<property name="zipfile" value="${phing.project.name}-${version}.zip" /> <property name="zipfile" value="${phing.project.name}-${version}.zip" />
<property name="distfile" value="dist/${zipfile}" /> <property name="distfile" value="dist/${zipfile}" />
<property name="sfproject" value="SemanticScuttle" /> <property name="sfproject" value="SemanticScuttle" />

View file

@ -180,6 +180,15 @@ $dbname = 'scuttle';
*/ */
$tableprefix = 'sc_'; $tableprefix = 'sc_';
/*
* If the database needs to be switched to UTF8
* manually or not. If true, a "SET NAMES UTF8" query
* will be sent at the beginning. If you need performance,
* save this query and set it in your mysql server options.
*
* @var boolean
*/
$dbneedssetnames = true;
/*************************************************** /***************************************************
@ -714,4 +723,16 @@ $authDebug = false;
* @var string * @var string
*/ */
$authEmailSuffix = null; $authEmailSuffix = null;
/**
* URL unittests are being run against
* Has to have a trailing slash
*
* @var string
*/
$unittestUrl = null;
?> ?>

View file

@ -1,4 +1,4 @@
# Scuttle en-GB Translation # SemanticScuttle en-GB Translation
# Copyright (C) 2005 - 2009 SemanticScuttle project # Copyright (C) 2005 - 2009 SemanticScuttle project
# This file is distributed under the same license as the SemanticScuttle package. # This file is distributed under the same license as the SemanticScuttle package.
# Ogee <ogee@ogee.de> # Ogee <ogee@ogee.de>

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -17,7 +17,7 @@ $this->includeTemplate($GLOBALS['top_include']);
<?php if(!is_null($currentUser) && $currentUser->isAdmin()): ?> <?php if(!is_null($currentUser) && $currentUser->isAdmin()): ?>
<li>SemanticScuttle v0.96.1</li> <li>SemanticScuttle v0.97.0</li>
<?php endif ?> <?php endif ?>
</ul> </ul>

View file

@ -216,9 +216,27 @@ if($currenttag!= '') {
<ol <?php echo ($start > 0 ? ' start="'. ++$start .'"' : ''); ?> <ol <?php echo ($start > 0 ? ' start="'. ++$start .'"' : ''); ?>
id="bookmarks"> id="bookmarks">
<?php <?php
foreach(array_keys($bookmarks) as $key) { $addresses = array();
$row =& $bookmarks[$key]; foreach ($bookmarks as $key => &$row) {
$addresses[$row['bId']] = $row['bAddress'];
}
$otherCounts = $bookmarkservice->countOthers($addresses);
if ($userservice->isLoggedOn()) {
$existence = $bookmarkservice->bookmarksExist(
$addresses, $currentUser->getId()
);
}
if ($userservice->isLoggedOn()) {
$watchedNames = $userservice->getWatchNames(
$currentUser->getId(), true
);
} else {
$watchedNames = null;
}
foreach ($bookmarks as $key => &$row) {
switch ($row['bStatus']) { switch ($row['bStatus']) {
case 0: case 0:
$access = ''; $access = '';
@ -234,9 +252,7 @@ if($currenttag!= '') {
$cats = ''; $cats = '';
$tagsForCopy = ''; $tagsForCopy = '';
$tags = $row['tags']; $tags = $row['tags'];
foreach(array_keys($tags) as $key) { foreach ($tags as $tkey => &$tag) {
$tag =& $tags[$key];
$cats .= '<a href="'. sprintf($cat_url, filter($row['username'], 'url'), filter($tag, 'url')) .'" rel="tag">'. filter($tag) .'</a>, '; $cats .= '<a href="'. sprintf($cat_url, filter($row['username'], 'url'), filter($tag, 'url')) .'" rel="tag">'. filter($tag) .'</a>, ';
$tagsForCopy.= $tag.','; $tagsForCopy.= $tag.',';
} }
@ -264,7 +280,7 @@ if($currenttag!= '') {
// Udders! // Udders!
if (!isset($hash)) { if (!isset($hash)) {
$others = $bookmarkservice->countOthers($row['bAddress']); $others = $otherCounts[$row['bAddress']];
$ostart = '<a href="'. createURL('history', $row['bHash']) .'">'; $ostart = '<a href="'. createURL('history', $row['bHash']) .'">';
$oend = '</a>'; $oend = '</a>';
switch ($others) { switch ($others) {
@ -281,7 +297,7 @@ if($currenttag!= '') {
// Copy link // Copy link
if ($userservice->isLoggedOn() if ($userservice->isLoggedOn()
&& ($currentUser->getId() != $row['uId']) && ($currentUser->getId() != $row['uId'])
&& !$bookmarkservice->bookmarkExists($row['bAddress'], $currentUser->getId()) && !$existence[$row['bAddress']]
) { ) {
$copy .= ' - <a href="' $copy .= ' - <a href="'
. createURL('bookmarks', $currentUser->getUsername() .'?action=add&amp;copyOf='. $row['bId']) . createURL('bookmarks', $currentUser->getUsername() .'?action=add&amp;copyOf='. $row['bId'])
@ -304,7 +320,7 @@ if($currenttag!= '') {
} }
// Admin specific design // Admin specific design
if($userservice->isAdmin($row['uId'])) { if ($userservice->isAdmin($row['username']) && $GLOBALS['enableAdminColors']) {
$adminBgClass = 'class="adminBackground"'; $adminBgClass = 'class="adminBackground"';
$adminStar = ' <img src="'. ROOT .'images/logo_24.gif" width="12px" title="'. T_('This bookmark is certified by an admin user.') .'" />'; $adminStar = ' <img src="'. ROOT .'images/logo_24.gif" width="12px" title="'. T_('This bookmark is certified by an admin user.') .'" />';
} else { } else {
@ -313,7 +329,11 @@ if($currenttag!= '') {
} }
// Private Note (just visible by the owner and his/her contacts) // Private Note (just visible by the owner and his/her contacts)
if($userservice->isLoggedOn() && ($currentUser->getId() == $row['uId'] || in_array($row['username'], $userservice->getWatchNames($currentUser->getId(), true)))) { if ($watchedNames !== null
&& ($currentUser->getId() == $row['uId']
|| in_array($row['username'], $watchedNames)
)
) {
$privateNoteField = $row['bPrivateNote']; $privateNoteField = $row['bPrivateNote'];
} else { } else {
$privateNoteField = ''; $privateNoteField = '';

View file

@ -1,10 +1,28 @@
ChangeLog for SemantiScuttle ChangeLog for SemantiScuttle
============================ ============================
0.9X.X - 2010-XX-XX
-------------------
- Fix bug getTagsForBookmarks() that fetched all tags
0.97.0 - 2010-06-09
-------------------
- Many SQL optimizations - SemanticScuttle shows bookmarks 4 times faster now
- New config option to skip "SET NAMES UTF8" call: $dbneedssetnames
- Do not highlight admin bookmarks when $enableAdminColors is disabled
- Add russian translation
- Make HTML export follow the specifications a bit better
- Fix bug #2953732: faulty error message for duplicate bookmarks
- Fix bug #2960663: do not send content-type headers twice for ajax/api scripts
- Fix bug #2976593: fr_FR locale is vietnamese
0.96.1 - 2010-02-09 0.96.1 - 2010-02-09
------------------- -------------------
- Fix bug #2948410: API is broken in 0.96.0 - Fix bug #2948410: API is broken in 0.96.0
0.96.0 - 2010-02-08 0.96.0 - 2010-02-08
------------------- -------------------
- Fix bug #2843523: ArtViper thumbnail license change - Fix bug #2843523: ArtViper thumbnail license change

View file

@ -1,6 +1,12 @@
Upgrading SemanticScuttle from a previous version Upgrading SemanticScuttle from a previous version
================================================= =================================================
From version 0.96 to 0.97
-------------------------
No database changes necessary.
From version 0.95 to 0.96 From version 0.95 to 0.96
------------------------- -------------------------
Update your database: Update your database:

View file

@ -3,19 +3,20 @@ How to release a new version of SemanticScuttle
0. Run unit tests and verify that all of them pass 0. Run unit tests and verify that all of them pass
1. Update doc/ChangeLog 1. Update doc/ChangeLog
2. Update version in data/templates/about.tpl.php 2. Update doc/UPGRADE.txt
3. Update version in data/templates/about.tpl.php
and build.xml and build.xml
3. Create a release zip file via the build script: 4. Create a release zip file via the build script:
Just type "phing". Just type "phing".
4. Make a test installation from your zip file with a fresh 5. Make a test installation from your zip file with a fresh
database. Register a user, add bookmarks etc. database. Register a user, add bookmarks etc.
5. When all is fine, it's time to release. 6. When all is fine, it's time to release.
The build script takes care for most of the The build script takes care for most of the
tasks. tasks.
Run "phing release", and it will upload the release to Run "phing release", and it will upload the release to
sourceforge and create a svn tag. sourceforge and create a svn tag.
6. Write announcement mail to the SemanticScuttle mailing list 7. Write announcement mail to the SemanticScuttle mailing list
semanticscuttle-devel@lists.sourceforge.net semanticscuttle-devel@lists.sourceforge.net
7. Announce the new release in the sourceforge project news 8. Announce the new release in the sourceforge project news
https://sourceforge.net/apps/trac/sourceforge/wiki/News https://sourceforge.net/apps/trac/sourceforge/wiki/News

View file

@ -158,7 +158,7 @@ class SemanticScuttle_Model_User
// Look for value only if not already set // Look for value only if not already set
if(!isset($this->isAdmin)) { if(!isset($this->isAdmin)) {
$us = SemanticScuttle_Service_Factory::get('User'); $us = SemanticScuttle_Service_Factory::get('User');
$this->isAdmin = $us->isAdmin($this->id); $this->isAdmin = $us->isAdmin($this->username);
} }
return $this->isAdmin; return $this->isAdmin;
} }

View file

@ -178,8 +178,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
*/ */
public function getBookmarkByAddress($address) public function getBookmarkByAddress($address)
{ {
$hash = md5($address); return $this->getBookmarkByHash($this->getHash($address));
return $this->getBookmarkByHash($hash);
} }
@ -188,10 +187,12 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
* Retrieves a bookmark with the given hash. * Retrieves a bookmark with the given hash.
* DOES NOT RESPECT PRIVACY SETTINGS! * 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 * @return mixed Array with bookmark data or false in case
* of an error (i.e. not found). * of an error (i.e. not found).
*
* @see getHash()
*/ */
public function getBookmarkByHash($hash) public function getBookmarkByHash($hash)
{ {
@ -200,6 +201,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 * Retrieves a bookmark that has a given short
* name. * name.
@ -284,15 +304,18 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
} }
$userservice = SemanticScuttle_Service_Factory::get('User'); $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 //user has to be either admin, or owner
if ($GLOBALS['adminsCanModifyBookmarksFromOtherUsers'] if ($GLOBALS['adminsCanModifyBookmarksFromOtherUsers']
&& $userservice->isAdmin($user) && $userservice->isAdmin($user->username)
) { ) {
return true; return true;
} else { } 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 * @return boolean True when the bookmark with the given URL
* exists for the user, false if not. * exists for the user, false if not.
*/ */
function bookmarkExists($address = false, $uid = null) public function bookmarkExists($address = false, $uid = null)
{ {
if (!$address) { if (!$address) {
return false; return false;
} }
$address = $this->normalize($address); $crit = array('bHash' => $this->getHash($address));
$crit = array('bHash' => md5($address));
if (isset ($uid)) { if (isset ($uid)) {
$crit['uId'] = $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))) { if (!($dbresult = $this->db->sql_query($sql))) {
message_die( message_die(
@ -341,6 +364,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. * Adds a bookmark to the database.
* *
@ -402,17 +479,17 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
// Set up the SQL insert statement and execute it. // Set up the SQL insert statement and execute it.
$values = array( $values = array(
'uId' => intval($sId), 'uId' => intval($sId),
'bIp' => $ip, 'bIp' => $ip,
'bDatetime' => $datetime, 'bDatetime' => $datetime,
'bModified' => $datetime, 'bModified' => $datetime,
'bTitle' => $title, 'bTitle' => $title,
'bAddress' => $address, 'bAddress' => $address,
'bDescription' => $description, 'bDescription' => $description,
'bPrivateNote' => $privateNote, 'bPrivateNote' => $privateNote,
'bStatus' => intval($status), 'bStatus' => intval($status),
'bHash' => md5($address), 'bHash' => $this->getHash($address),
'bShort' => $short 'bShort' => $short
); );
$sql = 'INSERT INTO '. $this->getTableName() $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. // Set up the SQL update statement and execute it.
$updates = array( $updates = array(
'bModified' => $moddatetime, 'bModified' => $moddatetime,
'bTitle' => $title, 'bTitle' => $title,
'bAddress' => $address, 'bAddress' => $address,
'bDescription' => $description, 'bDescription' => $description,
'bPrivateNote' => $privateNote, 'bPrivateNote' => $privateNote,
'bStatus' => $status, 'bStatus' => $status,
'bHash' => md5($address), 'bHash' => $this->getHash($address, false),
'bShort' => $short 'bShort' => $short
); );
if (!is_null($date)) { if (!is_null($date)) {
@ -804,10 +881,17 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$total = $row['total']; $total = $row['total'];
$this->db->sql_freeresult($totalresult); $this->db->sql_freeresult($totalresult);
$bookmarks = array(); $bookmarks = array();
while ($row = & $this->db->sql_fetchrow($dbresult)) { $bookmarkids = array();
$row['tags'] = $b2tservice->getTagsForBookmark(intval($row['bId'])); while ($row = $this->db->sql_fetchrow($dbresult)) {
$bookmarks[] = $row; $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); $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; return false;
} }
$bArray = is_array($addresses);
$userservice = SemanticScuttle_Service_Factory :: get('User'); $us = SemanticScuttle_Service_Factory::get('User');
$sId = $userservice->getCurrentUserId(); $sId = (int)$us->getCurrentUserId();
if ($userservice->isLoggedOn()) { if ($us->isLoggedOn()) {
// All public bookmarks, user's own bookmarks and any shared with user //All public bookmarks, user's own bookmarks
$privacy = ' AND ((B.bStatus = 0) OR (B.uId = '. $sId .')'; // and any shared with our user
$watchnames = $userservice->getWatchNames($sId, true); $privacy = ' AND ((B.bStatus = 0) OR (B.uId = ' . $sId . ')';
foreach($watchnames as $watchuser) { $watchnames = $us->getWatchNames($sId, true);
$privacy .= ' OR (U.username = "'. $watchuser .'" AND B.bStatus = 1)'; foreach ($watchnames as $watchuser) {
$privacy .= ' OR (U.username = "'
. $this->db->sql_escape($watchuser)
. '" AND B.bStatus = 1)';
} }
$privacy .= ')'; $privacy .= ')';
} else { } else {
// Just public bookmarks //Just public bookmarks
$privacy = ' AND B.bStatus = 0'; $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; $addressesSql = ' AND (0';
if (!($dbresult = & $this->db->sql_query($sql))) { foreach ((array)$addresses as $address) {
message_die(GENERAL_ERROR, 'Could not get vars', '', __LINE__, __FILE__, $sql, $this->db); $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); $this->db->sql_freeresult($dbresult);
return $output;
return $bArray ? $counts : reset($counts);
} }

View file

@ -266,27 +266,90 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
return true; 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)) { 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; 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))) { if (!($dbresult = $this->db->sql_query($query))) {
message_die(GENERAL_ERROR, 'Could not get tags', '', __LINE__, __FILE__, $query, $this->db); message_die(
GENERAL_ERROR, 'Could not get tags',
'', __LINE__, __FILE__, $query, $this->db
);
return false; return false;
} }
$tags = array(); $tags = array();
while ($row =& $this->db->sql_fetchrow($dbresult)) { while ($row = $this->db->sql_fetchrow($dbresult)) {
$tags[] = $row['tag']; $tags[] = $row['tag'];
} }
$this->db->sql_freeresult($dbresult); $this->db->sql_freeresult($dbresult);
return $tags; 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) { function &getTags($userid = NULL) {
$userservice =SemanticScuttle_Service_Factory::get('User'); $userservice =SemanticScuttle_Service_Factory::get('User');
$logged_on_user = $userservice->getCurrentUserId(); $logged_on_user = $userservice->getCurrentUserId();

View file

@ -113,7 +113,7 @@ class SemanticScuttle_Service_Factory
protected static function loadDb() protected static function loadDb()
{ {
global $dbhost, $dbuser, $dbpass, $dbname, global $dbhost, $dbuser, $dbpass, $dbname,
$dbport, $dbpersist, $dbtype; $dbport, $dbpersist, $dbtype, $dbneedssetnames;
if (self::$db !== null) { if (self::$db !== null) {
return; return;
@ -130,7 +130,9 @@ class SemanticScuttle_Service_Factory
self::$db self::$db
); );
} }
$db->sql_query('SET NAMES UTF8');
$dbneedssetnames && $db->sql_query('SET NAMES UTF8');
self::$db = $db; self::$db = $db;
} }

View file

@ -76,15 +76,28 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
$this->updateSessionStability(); $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)) ) { if (!($dbresult = $this->db->sql_query($query)) ) {
message_die(GENERAL_ERROR, 'Could not get user', '', __LINE__, __FILE__, $query, $this->db); message_die(
GENERAL_ERROR, 'Could not get user',
'', __LINE__, __FILE__, $query, $this->db
);
return false; return false;
} }
$row =& $this->db->sql_fetchrow($dbresult); $row = $this->db->sql_fetchrow($dbresult);
$this->db->sql_freeresult($dbresult); $this->db->sql_freeresult($dbresult);
if ($row) { if ($row) {
return $row; return $row;
@ -305,9 +318,14 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
/** /**
* Checks if the given user is an administrator. * Checks if the given user is an administrator.
* Uses global admin_users property containing admin * Uses global admin_users property containing admin
* user names * user names.
* *
* @param integer|array $user User ID or user row from DB * 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|string $user User ID or user row from DB
* or user name
* *
* @return boolean True if the user is admin * @return boolean True if the user is admin
*/ */
@ -315,10 +333,13 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
{ {
if (is_numeric($user)) { if (is_numeric($user)) {
$user = $this->getUser($user); $user = $this->getUser($user);
$user = $user['username'];
} else if (is_array($user)) {
$user = $user['username'];
} }
if (isset($GLOBALS['admin_users']) if (isset($GLOBALS['admin_users'])
&& in_array($user['username'], $GLOBALS['admin_users']) && in_array($user, $GLOBALS['admin_users'])
) { ) {
return true; return true;
} else { } else {
@ -386,6 +407,7 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
} }
//reload user object //reload user object
$this->getCurrentUser(true); $this->getCurrentUser(true);
$this->getCurrentObjectUser(true);
} }

View file

@ -440,7 +440,7 @@ class sql_db
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n"; echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n";
echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n"; echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n";
echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n"; echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n";
echo '</style><title>' . $msg_title . '</title></head><body>'; echo '</style><title>DB query explanation</title></head><body>';
echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>'; echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>';
echo $sql_report; echo $sql_report;
echo '</td></tr></table><br /></body></html>'; echo '</td></tr></table><br /></body></html>';

View file

@ -1,6 +1,19 @@
<?php <?php
/* Define functions used into the application */ /**
* Defines some commonly used functions.
*
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
* @author Christian Weiske <cweiske@cweiske.de>
* @author Eric Dane <ericdane@users.sourceforge.net>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
// Converts tags: // Converts tags:
// - direction = out: convert spaces to underscores; // - direction = out: convert spaces to underscores;
@ -35,10 +48,23 @@ function filter($data, $type = NULL) {
return $data; return $data;
} }
function getPerPageCount($userObject = null) { /**
* Returns the number of bookmarks that shall be displayed on one page.
*
* @param SemanticScuttle_Model_User $userObject Object of the current user
*
* @return integer Number of bookmarks per page
*
* @uses $defaultPerPage
* @uses $defaultPerPageForAdmins
*/
function getPerPageCount($userObject = null)
{
global $defaultPerPage, $defaultPerPageForAdmins; global $defaultPerPage, $defaultPerPageForAdmins;
if(isset($defaultPerPageForAdmins) && $userObject != null && $userObject->isAdmin()) { if (isset($defaultPerPageForAdmins)
&& $userObject != null && $userObject->isAdmin()
) {
return $defaultPerPageForAdmins; return $defaultPerPageForAdmins;
} else { } else {
return $defaultPerPage; return $defaultPerPage;

View file

@ -107,6 +107,12 @@ $tplVars['userservice'] = $userservice;
// 6 // Force UTF-8 behaviour for server (cannot be moved into top.inc.php which is not included into every file) // 6 // Force UTF-8 behaviour for server (cannot be moved into top.inc.php which is not included into every file)
if (!defined('UNIT_TEST_MODE')) { if (!defined('UNIT_TEST_MODE')) {
header('Content-Type: text/html; charset=utf-8'); //API files define that, so we need a way to support both of them
if (!isset($httpContentType)) {
$httpContentType = 'text/html';
}
if ($httpContentType !== false) {
header('Content-Type: ' . $httpContentType . '; charset=utf-8');
}
} }
?> ?>

View file

@ -56,6 +56,7 @@ class AllTests extends PHPUnit_Framework_TestSuite
$suite = new AllTests(); $suite = new AllTests();
$tdir = dirname(__FILE__); $tdir = dirname(__FILE__);
$suite->addTestFile($tdir . '/BookmarkTest.php'); $suite->addTestFile($tdir . '/BookmarkTest.php');
$suite->addTestFile($tdir . '/Bookmark2TagTest.php');
$suite->addTestFile($tdir . '/Tag2TagTest.php'); $suite->addTestFile($tdir . '/Tag2TagTest.php');
$suite->addTestFile($tdir . '/TagsCacheTest.php'); $suite->addTestFile($tdir . '/TagsCacheTest.php');
$suite->addTestFile($tdir . '/CommonDescriptionTest.php'); $suite->addTestFile($tdir . '/CommonDescriptionTest.php');

287
tests/Api/ExportCsvTest.php Normal file
View file

@ -0,0 +1,287 @@
<?php
/**
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
* @author Christian Weiske <cweiske@cweiske.de>
* @author Eric Dane <ericdane@users.sourceforge.net>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
require_once dirname(__FILE__) . '/../prepare.php';
require_once 'HTTP/Request2.php';
if (!defined('PHPUnit_MAIN_METHOD')) {
define('PHPUnit_MAIN_METHOD', 'Api_ExportCsvTest::main');
}
/**
* Unit tests for the SemanticScuttle csv export API
*
* @category Bookmarking
* @package SemanticScuttle
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
* @author Christian Weiske <cweiske@cweiske.de>
* @author Eric Dane <ericdane@users.sourceforge.net>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
class Api_ExportCsvTest extends TestBaseApi
{
protected $us;
protected $bs;
protected $urlPart = 'api/export_csv.php';
/**
* Used to run this test class standalone
*
* @return void
*/
public static function main()
{
require_once 'PHPUnit/TextUI/TestRunner.php';
PHPUnit_TextUI_TestRunner::run(
new PHPUnit_Framework_TestSuite(__CLASS__)
);
}
/**
* Test if authentication is required when sending no auth data
*/
public function testAuthWithoutAuthData()
{
$req = $this->getRequest(null, false);
$res = $req->send();
$this->assertEquals(401, $res->getStatus());
}
/**
* Test if authentication is required when sending wrong user data
*/
public function testAuthWrongCredentials()
{
$req = $this->getRequest(null, false);
$req->setAuth('user', 'password', HTTP_Request2::AUTH_BASIC);
$res = $req->send();
$this->assertEquals(401, $res->getStatus());
}
/**
* Test MIME content type and filename header fields
*/
public function testMimeTypeFilename()
{
$res = reset($this->getAuthRequest())->send();
$this->assertEquals(200, $res->getStatus());
//verify MIME content type
$this->assertEquals(
'application/csv-tab-delimited-table; charset=utf-8',
$res->getHeader('content-type')
);
//we need a file name
$this->assertNotNull($res->getHeader('content-disposition'));
}
/**
* Test CSV export without bookmarks
*/
public function testNoBookmarks()
{
list($req, $uid) = $this->getAuthRequest();
$body = $req->send()->getBody();
$csv = $this->getCsvArray($body);
$this->assertEquals(1, count($csv));
$this->assertCsvHeader($csv);
}
/**
* Test CSV export with some bookmarks
*/
public function testBookmarks()
{
list($req, $uid) = $this->getAuthRequest();
//public
$this->addBookmark(
$uid, 'http://example.org/testBookmarks', 0,
array('unittest', 'testBookmarks'), 'mytitle'
);
//shared
$this->addBookmark(
$uid, 'http://example.org/testBookmarks-shared', 1,
array('unittest', 'testBookmarks'), 'mytitle-shared'
);
//private
$this->addBookmark(
$uid, 'http://example.org/testBookmarks-private', 2,
array('unittest', 'testBookmarks'), 'mytitle-private'
);
//private other that should not in the export
$this->addBookmark(
null, 'http://example.org/testBookmarks-private2', 2
);
//public bookmark from other people that should not be
// exported, too
$this->addBookmark(
null, 'http://example.org/testBookmarks-other', 0
);
$body = $req->send()->getBody();
$csv = $this->getCsvArray($body);
$this->assertEquals(4, count($csv));
$this->assertCsvHeader($csv);
$this->assertEquals('http://example.org/testBookmarks', $csv[1][0]);
$this->assertEquals('mytitle', $csv[1][1]);
$this->assertEquals('unittest,testbookmarks', $csv[1][2]);
$this->assertEquals('http://example.org/testBookmarks-shared', $csv[2][0]);
$this->assertEquals('mytitle-shared', $csv[2][1]);
$this->assertEquals('unittest,testbookmarks', $csv[2][2]);
$this->assertEquals('http://example.org/testBookmarks-private', $csv[3][0]);
$this->assertEquals('mytitle-private', $csv[3][1]);
$this->assertEquals('unittest,testbookmarks', $csv[3][2]);
}
/**
* Test CSV export with tag filter
*/
public function testTagFilter()
{
list($req, $uid) = $this->getAuthRequest('?tag=tag1');
$this->addBookmark(
$uid, 'http://example.org/tag-1', 0,
array('unittest', 'tag1')
);
$this->addBookmark(
$uid, 'http://example.org/tag-2', 0,
array('unittest', 'tag2')
);
$this->addBookmark(
$uid, 'http://example.org/tag-3', 0,
array('unittest', 'tag1', 'tag2')
);
$body = $req->send()->getBody();
$csv = $this->getCsvArray($body);
$this->assertEquals(3, count($csv));
$this->assertCsvHeader($csv);
$this->assertEquals('http://example.org/tag-1', $csv[1][0]);
$this->assertEquals('http://example.org/tag-3', $csv[2][0]);
}
/**
* Test CSV export with tag filter for multiple tags
*/
public function testTagFilterMultiple()
{
list($req, $uid) = $this->getAuthRequest('?tag=tag1+tag2');
$this->addBookmark(
$uid, 'http://example.org/tag-1', 0,
array('unittest', 'tag1')
);
$this->addBookmark(
$uid, 'http://example.org/tag-2', 0,
array('unittest', 'tag2')
);
$this->addBookmark(
$uid, 'http://example.org/tag-3', 0,
array('unittest', 'tag1', 'tag2')
);
$body = $req->send()->getBody();
$csv = $this->getCsvArray($body);
$this->assertEquals(2, count($csv));
$this->assertCsvHeader($csv);
$this->assertEquals('http://example.org/tag-3', $csv[1][0]);
}
/**
* Asserts that the CSV array contains the correct header
*
* @param array $csv CSV array from getCsvArray()
*
* @return void
*/
protected function assertCsvHeader($csv)
{
$this->assertEquals(
array('url', 'title', 'tags', 'description'),
$csv[0]
);
}
/**
* Converts a string of CSV data to an array
*
* @param string $body String containing the full CSV file
*
* @return array Array of CSV data
*/
protected function getCsvArray($body)
{
$v53 = (version_compare(PHP_VERSION, '5.3.0') === 1);
//dead simple implementation that does not work with
// advanced CSV files
$ar = array();
foreach (explode("\n", $body) as $line) {
if ($v53) {
$ar[] = str_getcsv($line, ';');
} else {
$arl = explode(';', $line);
foreach ($arl as &$str) {
if (substr($str, 0, 1) == '"'
&& substr($str, -1) == '"'
) {
$str = substr($str, 1, -1);
}
}
$ar[] = $arl;
}
}
if (count(end($ar)) == 1 && reset(end($ar)) == '') {
unset($ar[key($ar)]);
}
return $ar;
}
}
if (PHPUnit_MAIN_METHOD == 'Api_ExportCsvTest::main') {
Api_ExportCsvTest::main();
}
?>

213
tests/Bookmark2TagTest.php Normal file
View file

@ -0,0 +1,213 @@
<?php
/**
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
* @author Christian Weiske <cweiske@cweiske.de>
* @author Eric Dane <ericdane@users.sourceforge.net>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
require_once 'prepare.php';
if (!defined('PHPUnit_MAIN_METHOD')) {
define('PHPUnit_MAIN_METHOD', 'Bookmark2TagTest::main');
}
/**
* Unit tests for the SemanticScuttle bookmark-tag combination service.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
* @author Christian Weiske <cweiske@cweiske.de>
* @author Eric Dane <ericdane@users.sourceforge.net>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
class Bookmark2TagTest extends TestBase
{
protected $us;
protected $bs;
protected $ts;
protected $tts;
/**
* Used to run this test class standalone
*
* @return void
*/
public static function main()
{
require_once 'PHPUnit/TextUI/TestRunner.php';
PHPUnit_TextUI_TestRunner::run(
new PHPUnit_Framework_TestSuite(__CLASS__)
);
}
protected function setUp()
{
$this->us = SemanticScuttle_Service_Factory::get('User');
$this->bs = SemanticScuttle_Service_Factory::get('Bookmark');
$this->bs->deleteAll();
$this->b2ts= SemanticScuttle_Service_Factory::get('Bookmark2Tag');
$this->b2ts->deleteAll();
$this->tts = SemanticScuttle_Service_Factory::get('Tag2Tag');
$this->tts->deleteAll();
$this->tsts = SemanticScuttle_Service_Factory::get('TagStat');
$this->tsts->deleteAll();
$this->vs = SemanticScuttle_Service_Factory::get('Vote');
$this->vs->deleteAll();
}
/**
* Test getTagsForBookmark() when the bookmark has no tags
*
* @return void
*/
public function testGetTagsForBookmarkNone()
{
$this->addBookmark(null, null, 0, array('forz', 'barz'));
$bid = $this->addBookmark(null, null, 0, array());
$this->assertEquals(
array(),
$this->b2ts->getTagsForBookmark($bid)
);
}
/**
* Test getTagsForBookmark() when the bookmark has one tag
*
* @return void
*/
public function testGetTagsForBookmarkOne()
{
$this->addBookmark(null, null, 0, array('forz', 'barz'));
$bid = $this->addBookmark(null, null, 0, array());
$this->b2ts->attachTags($bid, array('foo'));
$this->assertEquals(
array('foo'),
$this->b2ts->getTagsForBookmark($bid)
);
}
/**
* Test getTagsForBookmark() when the bookmark has three tags
*
* @return void
*/
public function testGetTagsForBookmarkThree()
{
$this->addBookmark(null, null, 0, array('forz', 'barz'));
$bid = $this->addBookmark(null, null, 0, array());
$this->b2ts->attachTags($bid, array('foo', 'bar', 'fuu'));
$tags = $this->b2ts->getTagsForBookmark($bid);
$this->assertType('array', $tags);
$this->assertContains('foo', $tags);
$this->assertContains('bar', $tags);
$this->assertContains('fuu', $tags);
}
/**
* Test getTagsForBookmarks() when no bookmarks have tags.
*
* @return void
*/
public function testGetTagsForBookmarksNone()
{
$bid1 = $this->addBookmark(null, null, 0, array());
$bid2 = $this->addBookmark(null, null, 0, array());
$alltags = $this->b2ts->getTagsForBookmarks(
array($bid1, $bid2)
);
$this->assertType('array', $alltags);
$this->assertEquals(2, count($alltags));
$this->assertType('array', $alltags[$bid1]);
$this->assertType('array', $alltags[$bid2]);
$this->assertEquals(0, count($alltags[$bid1]));
$this->assertEquals(0, count($alltags[$bid2]));
}
/**
* Test getTagsForBookmarks() when most bookmarks have tags.
*
* @return void
*/
public function testGetTagsForBookmarksMost()
{
$bid1 = $this->addBookmark(null, null, 0, array());
$this->b2ts->attachTags($bid1, array('foo', 'bar', 'fuu'));
$bid2 = $this->addBookmark(null, null, 0, array());
$this->b2ts->attachTags($bid2, array('foo', 'bar2', 'fuu2'));
$bid3 = $this->addBookmark(null, null, 0, array());
$this->b2ts->attachTags($bid3, array('foo', 'bar2', 'fuu3'));
$bid4 = $this->addBookmark(null, null, 0, array());
//no tags
//bookmark that does not get queried
//http://sourceforge.net/projects/semanticscuttle/forums/forum/759510/topic/3752670
$bid5 = $this->addBookmark(null, null, 0, array());
$this->b2ts->attachTags($bid5, array('foo', 'bar2', 'fuu5'));
$alltags = $this->b2ts->getTagsForBookmarks(
array($bid1, $bid2, $bid3, $bid4)
);
$this->assertType('array', $alltags);
foreach ($alltags as $bid => $btags) {
$this->assertType('array', $btags);
if ($bid == $bid1) {
$this->assertEquals(3, count($btags));
$this->assertContains('foo', $btags);
$this->assertContains('bar', $btags);
$this->assertContains('fuu', $btags);
} else if ($bid == $bid2) {
$this->assertEquals(3, count($btags));
$this->assertContains('foo', $btags);
$this->assertContains('bar2', $btags);
$this->assertContains('fuu2', $btags);
} else if ($bid == $bid3) {
$this->assertEquals(3, count($btags));
$this->assertContains('foo', $btags);
$this->assertContains('bar2', $btags);
$this->assertContains('fuu3', $btags);
} else if ($bid == $bid4) {
$this->assertEquals(0, count($btags));
} else {
$this->assertTrue(false, 'Unknown bookmark id');
}
}
}
}
if (PHPUnit_MAIN_METHOD == 'Bookmark2TagTest::main') {
Bookmark2TagTest::main();
}
?>

View file

@ -252,6 +252,132 @@ class BookmarkTest extends TestBase
/**
* Tests if bookmarksExist() returns true when a bookmark
* exists
*
* @return void
*/
public function testBookmarksExistTrueSingle()
{
$bid = $this->addBookmark();
$bookmark = $this->bs->getBookmark($bid);
$ret = $this->bs->bookmarksExist(array($bookmark['bAddress']));
$this->assertType('array', $ret);
$this->assertEquals(1, count($ret));
$this->assertTrue($ret[$bookmark['bAddress']]);
}
/**
* Tests if bookmarksExist() returns true when all bookmarks
* exist
*
* @return void
*/
public function testBookmarksExistTrueMultiple()
{
$bid = $this->addBookmark();
$bookmark = $this->bs->getBookmark($bid);
$bid2 = $this->addBookmark();
$bookmark2 = $this->bs->getBookmark($bid2);
$ret = $this->bs->bookmarksExist(
array(
$bookmark['bAddress'],
$bookmark2['bAddress']
)
);
$this->assertType('array', $ret);
$this->assertEquals(2, count($ret));
$this->assertTrue($ret[$bookmark['bAddress']]);
$this->assertTrue($ret[$bookmark2['bAddress']]);
}
/**
* Tests if bookmarksExist() returns false when a bookmark
* does not exist
*
* @return void
*/
public function testBookmarksExistFalseSingle()
{
$ret = $this->bs->bookmarksExist(array('does-not-exist'));
$this->assertType('array', $ret);
$this->assertEquals(1, count($ret));
$this->assertFalse($ret['does-not-exist']);
}
/**
* Tests if bookmarksExist() returns false when all bookmarks
* do not exist
*
* @return void
*/
public function testBookmarksExistFalseMultiple()
{
$bms = array(
'does-not-exist',
'does-not-exist-2',
'does-not-exist-3',
);
$ret = $this->bs->bookmarksExist($bms);
$this->assertType('array', $ret);
$this->assertEquals(3, count($ret));
$this->assertFalse($ret['does-not-exist']);
$this->assertFalse($ret['does-not-exist-2']);
$this->assertFalse($ret['does-not-exist-3']);
}
/**
* Tests if bookmarksExist() returns true when some bookmarks
* exist.
*
* @return void
*/
public function testBookmarksExistSome()
{
$bid = $this->addBookmark();
$bookmark = $this->bs->getBookmark($bid);
$bid2 = $this->addBookmark();
$bookmark2 = $this->bs->getBookmark($bid2);
//do not search for this one
$bid3 = $this->addBookmark();
$bookmark3 = $this->bs->getBookmark($bid3);
$ret = $this->bs->bookmarksExist(
array(
$bookmark['bAddress'],
'does-not-exist',
$bookmark2['bAddress'],
'does-not-exist-2',
'does-not-exist-3'
)
);
$this->assertType('array', $ret);
$this->assertEquals(5, count($ret));
$this->assertTrue($ret[$bookmark['bAddress']]);
$this->assertTrue($ret[$bookmark2['bAddress']]);
$this->assertFalse($ret['does-not-exist']);
$this->assertFalse($ret['does-not-exist-2']);
$this->assertFalse($ret['does-not-exist-3']);
}
/** /**
* Test if countBookmarks() works with no bookmarks * Test if countBookmarks() works with no bookmarks
* *
@ -331,6 +457,40 @@ class BookmarkTest extends TestBase
/**
* Check tag loading functionality of getBookmarks()
*
* @return void
*/
public function testGetBookmarksIncludeTags()
{
$uid = $this->addUser();
$bid = $this->addBookmark($uid);
$this->b2ts->attachTags($bid, array('foo', 'bar'));
$bid2 = $this->addBookmark($uid);
$this->b2ts->attachTags($bid2, array('fuu', 'baz'));
$bms = $this->bs->getBookmarks();
$this->assertEquals(2, count($bms['bookmarks']));
$this->assertEquals(2, $bms['total']);
foreach ($bms['bookmarks'] as $bm) {
$this->assertArrayHasKey('tags', $bm);
$this->assertType('array', $bm['tags']);
if ($bm['bId'] == $bid) {
$this->assertContains('foo', $bm['tags']);
$this->assertContains('bar', $bm['tags']);
} else if ($bm['bId'] == $bid2) {
$this->assertContains('fuu', $bm['tags']);
$this->assertContains('baz', $bm['tags']);
} else {
$this->assertTrue(false, 'Unknown bookmark id');
}
}
}
/** /**
* Test if deleting a bookmark works. * Test if deleting a bookmark works.
* *
@ -703,6 +863,50 @@ class BookmarkTest extends TestBase
/**
* Tests if getBookmarkByAddress() works correctly.
*
* @return void
*/
public function testGetBookmarkByAddress()
{
$url = 'http://example.org';
$uid = $this->addUser();
$bid = $this->addBookmark($uid, $url);
$bm = $this->bs->getBookmarkByAddress($url);
$this->assertType('array', $bm);
$this->assertEquals($url, $bm['bAddress']);
}
/**
* Tests if getBookmarkByAddress() works correctly with aliases.
* When passing an incomplete address i.e. without protocol,
* the full URL needs to be searched for.
*
* The failure of this test lead to #2953732.
*
* @return void
*
* @link https://sourceforge.net/tracker/?func=detail&atid=1017430&aid=2953732&group_id=211356
*/
public function testGetBookmarkByAddressAlias()
{
$url = 'http://example.org';
$incomplete = 'example.org';
$uid = $this->addUser();
$bid = $this->addBookmark($uid, $url);
$bm = $this->bs->getBookmarkByAddress($incomplete);
$this->assertType('array', $bm);
$this->assertEquals($url, $bm['bAddress']);
}
public function testNormalize() public function testNormalize()
{ {
$this->assertEquals( $this->assertEquals(
@ -778,6 +982,251 @@ class BookmarkTest extends TestBase
$this->assertEquals('newShortNambb', $bm['bShort']); $this->assertEquals('newShortNambb', $bm['bShort']);
} }
/**
* Test what countOther() returns when the address does not exist
*
* @return void
*/
public function testCountOthersAddressDoesNotExist()
{
$this->assertEquals(0, $this->bs->countOthers('http://example.org'));
}
/**
* Test what countOther() returns when nobody else has the same bookmark
*
* @return void
*/
public function testCountOthersNone()
{
$uid = $this->addUser();
$address = 'http://example.org';
$this->addBookmark($uid, $address);
$this->assertEquals(0, $this->bs->countOthers($address));
}
/**
* Test what countOther() returns when the address exists only once
* and multiple bookmarks are in the database.
*
* @return void
*/
public function testCountOthersMultipleNone()
{
$uid = $this->addUser();
$address = 'http://example.org';
$this->addBookmark($uid, $address);
$this->addBookmark($uid);
$this->addBookmark($uid);
$this->assertEquals(0, $this->bs->countOthers($address));
}
/**
* Test what countOther() returns when the address exists only once
* and the same user and other users have other bookmarks
*
* @return void
*/
public function testCountOthersMultipleUsersNone()
{
$uid = $this->addUser();
$uid2 = $this->addUser();
$address = 'http://example.org';
$this->addBookmark($uid, $address);
$this->addBookmark($uid);
$this->addBookmark($uid2);
$this->assertEquals(0, $this->bs->countOthers($address));
}
/**
* Test what countOther() returns when the address exists two
* times in the database.
*
* @return void
*/
public function testCountOthersOne()
{
$uid = $this->addUser();
$uid2 = $this->addUser();
$address = 'http://example.org';
$this->addBookmark($uid, $address);
$this->addBookmark($uid2, $address);
$this->assertEquals(1, $this->bs->countOthers($address));
}
/**
* Test what countOther() returns when the address exists four
* times in the database.
*
* @return void
*/
public function testCountOthersThree()
{
$uid = $this->addUser();
$address = 'http://example.org';
$this->addBookmark($uid, $address);
$this->addBookmark(null, $address);
$this->addBookmark(null, $address);
$this->addBookmark(null, $address);
$this->assertEquals(3, $this->bs->countOthers($address));
}
/**
* Test what countOther() returns when the user is logged in
* and friends (people on the watchlist) have bookmarked
* and shared the same address.
*
* @return void
*/
public function testCountOthersWatchlist()
{
$uid = $this->addUser();
$address = 'http://example.org';
//log user in
$this->us->setCurrentUserId($uid);
//setup users
$otherPublic1 = $this->addUser();
$otherPublic2 = $this->addUser();
$otherShared1 = $this->addUser();
$otherPrivate1 = $this->addUser();
$friendPublic1 = $this->addUser();
$friendShared1 = $this->addUser();
$friendShared2 = $this->addUser();
$friendPrivate1 = $this->addUser();
$friendSharing1 = $this->addUser();
//setup watchlists
$us = SemanticScuttle_Service_Factory::get('User');
$this->us->setCurrentUserId($friendPublic1);
$us->setWatchStatus($uid);
$this->us->setCurrentUserId($friendShared1);
$us->setWatchStatus($uid);
$this->us->setCurrentUserId($friendShared2);
$us->setWatchStatus($uid);
$this->us->setCurrentUserId($friendPrivate1);
$us->setWatchStatus($uid);
//back to login of main user
$this->us->setCurrentUserId($uid);
$us->setWatchStatus($friendSharing1);
//add bookmarks
$this->addBookmark($uid, $address, 0);
$this->addBookmark($otherPublic1, $address, 0);
$this->addBookmark($otherPublic2, $address, 0);
$this->addBookmark($otherShared1, $address, 1);
$this->addBookmark($otherPrivate1, $address, 2);
$this->addBookmark($friendPublic1, $address, 0);
$this->addBookmark($friendShared1, $address, 1);
$this->addBookmark($friendShared2, $address, 1);
$this->addBookmark($friendPrivate1, $address, 2);
//this user is on our watchlist, but we not on his
$this->addBookmark($friendSharing1, $address, 1);
//2 public
//1 public (friend)
//2 shared
//-> 5
$this->assertEquals(5, $this->bs->countOthers($address));
}
/**
* 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)
)
);
}
} }

View file

@ -12,7 +12,7 @@ Warning
The unit tests are DESTRUCTIBLE! Never ever run them on your The unit tests are DESTRUCTIBLE! Never ever run them on your
normal SemanticScuttle database! Always use a different database normal SemanticScuttle database! Always use a different database
for testing - whole tables are emptied and re-filled during the for testing - whole tables are emptied and re-filled during the
tests, and you will definitely loose all data in there. tests, and you will definitely lose all data in there.
Running the tests Running the tests

View file

@ -29,25 +29,45 @@ class TestBase extends PHPUnit_Framework_TestCase
/** /**
* Create a new bookmark. * Create a new bookmark.
* *
* @param integer $user User ID the bookmark shall belong * @param integer $user User ID the bookmark shall belong
* @param string $address Bookmark address to use
* @param integer $status Bookmark visibility
* @param array $tags Array of tags to attach. If "null" is given,
* it will automatically be "unittest"
* @param string $title Bookmark title
* *
* @return integer ID of bookmark * @return integer ID of bookmark
*
* @see SemanticScuttle_Service_Bookmark::addBookmark()
*/ */
protected function addBookmark($user = null) protected function addBookmark(
{ $user = null, $address = null, $status = 0,
$tags = null, $title = null
) {
if ($user === null) { if ($user === null) {
$user = $this->addUser(); $user = $this->addUser();
} }
if ($tags === null) {
$tags = array('unittest');
}
$bs = SemanticScuttle_Service_Factory::get('Bookmark'); $bs = SemanticScuttle_Service_Factory::get('Bookmark');
$rand = rand(); $rand = rand();
if ($address === null) {
$address = 'http://example.org/' . $rand;
}
if ($title === null) {
$title = 'unittest bookmark #' . $rand;
}
$bid = $bs->addBookmark( $bid = $bs->addBookmark(
'http://example.org/' . $rand, $address,
'unittest bookmark #' . $rand, $title,
'description', 'description',
null, null,
0, $status,
array('unittest'), $tags,
null, null, false, false, null, null, false, false,
$user $user
); );
@ -59,15 +79,26 @@ class TestBase extends PHPUnit_Framework_TestCase
/** /**
* Creates a new user in the database. * Creates a new user in the database.
* *
* @param string $username Username
* @param string $password Password
*
* @return integer ID of user * @return integer ID of user
*/ */
protected function addUser() protected function addUser($username = null, $password = null)
{ {
$us = SemanticScuttle_Service_Factory::get('User'); $us = SemanticScuttle_Service_Factory::get('User');
$rand = rand(); $rand = rand();
if ($username === null) {
$username = 'unittestuser-' . $rand;
}
if ($password === null) {
$password = $rand;
}
$uid = $us->addUser( $uid = $us->addUser(
'unittestuser-' . $rand, $username,
$rand, $password,
'unittest-' . $rand . '@example.org' 'unittest-' . $rand . '@example.org'
); );
return $uid; return $uid;

100
tests/TestBaseApi.php Normal file
View file

@ -0,0 +1,100 @@
<?php
/**
* SemanticScuttle - your social bookmark manager.
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
require_once 'PHPUnit/Framework.php';
PHPUnit_Util_Filter::addFileToFilter(__FILE__);
/**
* Base unittest class for web API tests.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Christian Weiske <cweiske@cweiske.de>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
class TestBaseApi extends TestBase
{
protected $url;
protected $urlPart = null;
protected function setUp()
{
if ($GLOBALS['unittestUrl'] === null) {
$this->assertTrue(false, 'Unittest URL not set in config');
}
if ($this->urlPart === null) {
$this->assertTrue(false, 'Set the urlPart variable');
}
$this->url = $GLOBALS['unittestUrl'] . $this->urlPart;
$this->us = SemanticScuttle_Service_Factory::get('User');
$this->us->deleteAll();
$this->bs = SemanticScuttle_Service_Factory::get('Bookmark');
$this->bs->deleteAll();
$this->b2t = SemanticScuttle_Service_Factory::get('Bookmark2Tag');
$this->b2t->deleteAll();
}
/**
* Gets a HTTP request object
*
* @param string $urlSuffix Suffix for the URL
*
* @return HTTP_Request2 HTTP request object
*/
protected function getRequest($urlSuffix = null)
{
$req = new HTTP_Request2(
$this->url . $urlSuffix,
HTTP_Request2::METHOD_GET
);
return $req;
}
/**
* Gets a HTTP request object
*
* @param string $urlSuffix Suffix for the URL
* @param mixed $auth If user authentication is needed (true/false)
* or array with username and password
*
* @return array(HTTP_Request2, integer) HTTP request object and user id
*/
protected function getAuthRequest($urlSuffix = null, $auth = true)
{
$req = $this->getRequest($urlSuffix);
if (is_array($auth)) {
list($username, $password) = $auth;
} else {
$username = 'testuser';
$password = 'testpassword';
}
$uid = $this->addUser($username, $password);
$req->setAuth(
$username, $password,
HTTP_Request2::AUTH_BASIC
);
return array($req, $uid);
}
}
?>

View file

@ -21,6 +21,7 @@ define('UNIT_TEST_MODE', true);
require_once dirname(__FILE__) . '/../src/SemanticScuttle/header.php'; require_once dirname(__FILE__) . '/../src/SemanticScuttle/header.php';
require_once dirname(__FILE__) . '/TestBase.php'; require_once dirname(__FILE__) . '/TestBase.php';
require_once dirname(__FILE__) . '/TestBaseApi.php';
if ($GLOBALS['debugMode'] == true if ($GLOBALS['debugMode'] == true
&& $GLOBALS['dbtype'] == 'mysql4' && $GLOBALS['dbtype'] == 'mysql4'

View file

@ -20,7 +20,7 @@
***************************************************************************/ ***************************************************************************/
/* Return a json file with list of linked tags */ /* Return a json file with list of linked tags */
$httpContentType = 'application/json';
require_once '../www-header.php'; require_once '../www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */

View file

@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/ ***************************************************************************/
/* Return a json file with list of tags according to current user and sort by popularity*/ /* Return a json file with list of tags according to current user and sort by popularity*/
$httpContentType = 'application/json';
require_once '../www-header.php'; require_once '../www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */

View file

@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/ ***************************************************************************/
/* Return a json file with list of tags according to current user and sort by popularity*/ /* Return a json file with list of tags according to current user and sort by popularity*/
$httpContentType = 'application/json';
require_once '../www-header.php'; require_once '../www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */

View file

@ -20,7 +20,7 @@
***************************************************************************/ ***************************************************************************/
/* Return a json file with list of linked tags */ /* Return a json file with list of linked tags */
$httpContentType = 'application/json';
require_once '../www-header.php'; require_once '../www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */

View file

@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/ ***************************************************************************/
/* Return a json file with list of tags according to current user and sort by popularity*/ /* Return a json file with list of tags according to current user and sort by popularity*/
$httpContentType = 'application/json';
require_once '../www-header.php'; require_once '../www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */

View file

@ -19,9 +19,9 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/ ***************************************************************************/
header('Content-Type: text/xml; charset=UTF-8');
header('Last-Modified: '. gmdate("D, d M Y H:i:s") .' GMT'); header('Last-Modified: '. gmdate("D, d M Y H:i:s") .' GMT');
header('Cache-Control: no-cache, must-revalidate'); header('Cache-Control: no-cache, must-revalidate');
$httpContentType = 'text/xml';
require_once 'www-header.php'; require_once 'www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */

View file

@ -19,10 +19,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/ ***************************************************************************/
header('Content-Type: text/xml; charset=UTF-8');
header("Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT"); header("Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT");
header("Cache-Control: no-cache, must-revalidate"); header("Cache-Control: no-cache, must-revalidate");
$httpContentType = 'text/xml';
require_once 'www-header.php'; require_once 'www-header.php';
/* Managing all possible inputs */ /* Managing all possible inputs */

View file

@ -19,10 +19,10 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/ ***************************************************************************/
header('Content-Type: text/xml; charset=UTF-8');
header("Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT"); header("Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT");
header("Cache-Control: no-cache, must-revalidate"); header("Cache-Control: no-cache, must-revalidate");
$httpContentType = 'text/xml';
require_once 'www-header.php'; require_once 'www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */

View file

@ -2,6 +2,7 @@
/** /**
* We re-use vote.php but set the ajax flag * We re-use vote.php but set the ajax flag
*/ */
$httpContentType = 'text/xml';
$GLOBALS['ajaxRequest'] = true; $GLOBALS['ajaxRequest'] = true;
require 'vote.php'; require 'vote.php';
@ -17,7 +18,6 @@ default:
$template = 'bookmarks-vote.inc.tpl.php'; $template = 'bookmarks-vote.inc.tpl.php';
} }
header('Content-Type: text/xml; charset=utf-8');
echo '<voteresult><bookmark>' . $bookmark . '</bookmark>' echo '<voteresult><bookmark>' . $bookmark . '</bookmark>'
. '<html xmlns="http://www.w3.org/1999/xhtml">'; . '<html xmlns="http://www.w3.org/1999/xhtml">';
$ts->loadTemplate( $ts->loadTemplate(

View file

@ -1,24 +1,40 @@
<?php <?php
// Export in CSV format in order to allow the import into a spreadsheet tool like Excel /**
* Export own bookmarks in CSV format in order to allow the import
* into a spreadsheet tool like Excel
*
* PHP version 5.
*
* @category Bookmarking
* @package SemanticScuttle
* @author Benjamin Huynh-Kim-Bang <mensonge@users.sourceforge.net>
* @author Christian Weiske <cweiske@cweiske.de>
* @author Eric Dane <ericdane@users.sourceforge.net>
* @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle
*/
// Force HTTP authentication first! // Force HTTP authentication first!
require_once('httpauth.inc.php'); $httpContentType = 'application/csv-tab-delimited-table';
require_once '../www-header.php'; require_once 'httpauth.inc.php';
header("Content-disposition: filename=exportBookmarks.csv");
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark'); $bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
// Check to see if a tag was specified. // Check to see if a tag was specified.
if (isset($_REQUEST['tag']) && (trim($_REQUEST['tag']) != '')) if (isset($_REQUEST['tag']) && (trim($_REQUEST['tag']) != '')) {
$tag = trim($_REQUEST['tag']); //$_GET vars have + replaced to " " automatically
else $tag = str_replace(' ', '+', trim($_REQUEST['tag']));
$tag = NULL; } else {
$tag = null;
}
// Get the posts relevant to the passed-in variables. // Get the posts relevant to the passed-in variables.
$bookmarks =& $bookmarkservice->getBookmarks(0, NULL, $userservice->getCurrentUserId(), $tag, NULL, getSortOrder()); $bookmarks = $bookmarkservice->getBookmarks(
0, null, $userservice->getCurrentUserId(),
header("Content-Type: application/csv-tab-delimited-table;charset=UTF-8"); $tag, null, getSortOrder()
header("Content-disposition: filename=exportBookmarks.csv"); );
//columns titles //columns titles
echo 'url;title;tags;description'; echo 'url;title;tags;description';

View file

@ -5,6 +5,7 @@
// Force HTTP authentication first! // Force HTTP authentication first!
//require_once('httpauth.inc.php'); //require_once('httpauth.inc.php');
$httpContentType = false;
require_once '../www-header.php'; require_once '../www-header.php';
if($GLOBALS['enableGoogleCustomSearch'] == false) { if($GLOBALS['enableGoogleCustomSearch'] == false) {
@ -39,7 +40,7 @@ $bookmarks =& $bookmarkservice->getBookmarks(0, NULL, NULL, $tag, NULL, getSortO
// Set up the plain file and output all the posts. // Set up the plain file and output all the posts.
header('Content-Type: text/plain'); header('Content-Type: text/plain; charset=utf-8');
if(!$xml) { if(!$xml) {
header('Content-Type: text/plain'); header('Content-Type: text/plain');
foreach($bookmarks['bookmarks'] as $row) { foreach($bookmarks['bookmarks'] as $row) {
@ -48,7 +49,7 @@ if(!$xml) {
} }
} }
} else { } else {
header('Content-Type: application/xml'); header('Content-Type: text/xml');
echo '<GoogleCustomizations>'."\n"; echo '<GoogleCustomizations>'."\n";
echo ' <Annotations>'."\n"; echo ' <Annotations>'."\n";
foreach($bookmarks['bookmarks'] as $row) { foreach($bookmarks['bookmarks'] as $row) {

View file

@ -3,6 +3,9 @@
* Implements the del.icio.us API request for all a user's posts, * Implements the del.icio.us API request for all a user's posts,
* optionally filtered by tag. * optionally filtered by tag.
* *
* Netscape bookmark file format is documented at
* http://msdn.microsoft.com/en-us/library/aa753582(VS.85).aspx
*
* SemanticScuttle - your social bookmark manager. * SemanticScuttle - your social bookmark manager.
* *
* PHP version 5. * PHP version 5.
@ -27,7 +30,8 @@ $bookmarkservice = SemanticScuttle_Service_Factory::get('Bookmark');
// Check to see if a tag was specified. // Check to see if a tag was specified.
if (isset($_REQUEST['tag']) && (trim($_REQUEST['tag']) != '')) { if (isset($_REQUEST['tag']) && (trim($_REQUEST['tag']) != '')) {
$tag = trim($_REQUEST['tag']); //$_GET vars have + replaced to " " automatically
$tag = str_replace(' ', '+', trim($_REQUEST['tag']));
} else { } else {
$tag = null; $tag = null;
} }
@ -45,7 +49,7 @@ echo '<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8" />';
echo '<!-- This is an automatically generated file. -->'."\r\n"; echo '<!-- This is an automatically generated file. -->'."\r\n";
echo '<TITLE>Bookmarks</TITLE>'."\r\n"; echo '<TITLE>Bookmarks</TITLE>'."\r\n";
echo '<H1 LAST_MODIFIED="'. date('U') .'">Bookmarks for '. htmlspecialchars($currentUser->getUsername()) .''. (is_null($tag) ? '' : ' tag="'. htmlspecialchars($tag) .'"') ." from " . $sitename ."</H1>\r\n"; echo '<H1 LAST_MODIFIED="'. date('U') .'">Bookmarks for '. htmlspecialchars($currentUser->getUsername()) .''. (is_null($tag) ? '' : ' tag="'. htmlspecialchars($tag) .'"') ." from " . $sitename ."</H1>\r\n";
echo '<DL><p>'."\r\n"; echo '<DL>'."\r\n";
@ -67,9 +71,9 @@ foreach ($bookmarks['bookmarks'] as $row) {
$taglist = 'system:unfiled'; $taglist = 'system:unfiled';
} }
echo "\t<dt><a href=\"". filter($row['bAddress'], 'xml') .'" '. $description .' hash="'. md5($row['bAddress']) .'" tags="'. filter($taglist, 'xml') .'" ADD_DATE="'. date('U', strtotime($row['bDatetime'])) ."\" >" . filter($row['bTitle'], 'xml') ."</a>\r\n"; echo "\t<DT><A HREF=\"". filter($row['bAddress'], 'xml') .'" '. $description .' hash="'. md5($row['bAddress']) .'" tags="'. filter($taglist, 'xml') .'" ADD_DATE="'. date('U', strtotime($row['bDatetime'])) ."\" >" . filter($row['bTitle'], 'xml') ."</a>\r\n";
} }
echo '</DL><p>'; echo '</DL>';
?> ?>

View file

@ -1,8 +1,8 @@
<?php <?php
/* Export data with semantic format (SIOC: http://sioc-project.org/, FOAF, SKOS, Annotea Ontology) */ /* Export data with semantic format (SIOC: http://sioc-project.org/, FOAF, SKOS, Annotea Ontology) */
$httpContentType = 'text/xml';
require_once '../www-header.php'; require_once '../www-header.php';
header('Content-Type: text/xml; charset=utf-8'); //we change headers html defined in headers.inc.php
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$userservice =SemanticScuttle_Service_Factory::get('User'); $userservice =SemanticScuttle_Service_Factory::get('User');

View file

@ -1,6 +1,6 @@
<?php <?php
$httpContentType = 'text/xml';
require_once '../www-header.php'; require_once '../www-header.php';
header("Content-type: text/xml");
?> ?>
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"> <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">

View file

@ -11,8 +11,8 @@
// - No support for 'replace' variable // - No support for 'replace' variable
// Force HTTP authentication // Force HTTP authentication
require_once('httpauth.inc.php'); $httpContentType = 'text/xml';
require_once '../www-header.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark'); $bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
@ -82,7 +82,6 @@ if (is_null($url) || is_null($description)) {
} }
// Set up the XML file and output the result. // Set up the XML file and output the result.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo '<result code="'. ($added ? 'done' : 'something went wrong') .'" />'; echo '<result code="'. ($added ? 'done' : 'something went wrong') .'" />';
?> ?>

View file

@ -5,8 +5,8 @@
// - doesn't include the filtered tag as an attribute on the root element (we do) // - doesn't include the filtered tag as an attribute on the root element (we do)
// Force HTTP authentication first! // Force HTTP authentication first!
require_once('httpauth.inc.php'); $httpContentType = 'text/xml';
require_once '../www-header.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark'); $bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
@ -22,7 +22,6 @@ else
$bookmarks =& $bookmarkservice->getBookmarks(0, NULL, $userservice->getCurrentUserId(), $tag); $bookmarks =& $bookmarkservice->getBookmarks(0, NULL, $userservice->getCurrentUserId(), $tag);
// Set up the XML file and output all the posts. // Set up the XML file and output all the posts.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo '<posts update="'. gmdate('Y-m-d\TH:i:s\Z') .'" user="'. htmlspecialchars($currentUser->getUsername()) .'"'. (is_null($tag) ? '' : ' tag="'. htmlspecialchars($tag) .'"') .">\r\n"; echo '<posts update="'. gmdate('Y-m-d\TH:i:s\Z') .'" user="'. htmlspecialchars($currentUser->getUsername()) .'"'. (is_null($tag) ? '' : ' tag="'. htmlspecialchars($tag) .'"') .">\r\n";

View file

@ -17,6 +17,7 @@
*/ */
// Force HTTP authentication first! // Force HTTP authentication first!
$httpContentType = 'text/xml';
require_once 'httpauth.inc.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
@ -36,7 +37,6 @@ $bookmarks = $bookmarkservice->getBookmarks(
); );
// Set up the XML file and output all the tags. // Set up the XML file and output all the tags.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo '<dates tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentUser->getUsername(), 'xml') ."\">\r\n"; echo '<dates tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentUser->getUsername(), 'xml') ."\">\r\n";

View file

@ -7,8 +7,8 @@
// - doesn't set the Content-Type to text/xml (we do). // - doesn't set the Content-Type to text/xml (we do).
// Force HTTP authentication first! // Force HTTP authentication first!
require_once('httpauth.inc.php'); $httpContentType = 'text/xml';
require_once '../www-header.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark'); $bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
@ -28,7 +28,6 @@ if (is_null($_REQUEST['url'])) {
} }
// Set up the XML file and output the result. // Set up the XML file and output the result.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo '<result code="'. ($deleted ? 'done' : 'something went wrong') .'" />'; echo '<result code="'. ($deleted ? 'done' : 'something went wrong') .'" />';
?> ?>

View file

@ -25,6 +25,7 @@
*/ */
// Force HTTP authentication first! // Force HTTP authentication first!
$httpContentType = 'text/xml';
require_once 'httpauth.inc.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
@ -54,7 +55,6 @@ $bookmarks = $bookmarkservice->getBookmarks(
// Set up the XML file and output all the tags. // Set up the XML file and output all the tags.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo '<posts'. (is_null($dtstart) ? '' : ' dt="'. $dtstart .'"') .' tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentUser->getUsername(), 'xml') ."\">\r\n"; echo '<posts'. (is_null($dtstart) ? '' : ' dt="'. $dtstart .'"') .' tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentUser->getUsername(), 'xml') ."\">\r\n";

View file

@ -6,6 +6,7 @@
// Force HTTP authentication first! // Force HTTP authentication first!
//require_once('httpauth.inc.php'); //require_once('httpauth.inc.php');
$httpContentType = 'text/xml';
require_once '../www-header.php'; require_once '../www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
@ -22,7 +23,6 @@ else
$bookmarks =& $bookmarkservice->getBookmarks(0, NULL, NULL, $tag); $bookmarks =& $bookmarkservice->getBookmarks(0, NULL, NULL, $tag);
// Set up the XML file and output all the posts. // Set up the XML file and output all the posts.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo '<posts update="'. gmdate('Y-m-d\TH:i:s\Z') .'" '. (is_null($tag) ? '' : ' tag="'. htmlspecialchars($tag) .'"') .">\r\n"; echo '<posts update="'. gmdate('Y-m-d\TH:i:s\Z') .'" '. (is_null($tag) ? '' : ' tag="'. htmlspecialchars($tag) .'"') .">\r\n";

View file

@ -22,6 +22,7 @@ $countDefault = 15;
$countMax = 100; $countMax = 100;
// Force HTTP authentication first! // Force HTTP authentication first!
$httpContentType = 'text/xml';
require_once 'httpauth.inc.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
@ -54,7 +55,6 @@ $bookmarks = $bookmarkservice->getBookmarks(
// Set up the XML file and output all the tags. // Set up the XML file and output all the tags.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo '<posts tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentUser->getUsername(), 'xml') ."\">\r\n"; echo '<posts tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentUser->getUsername(), 'xml') ."\">\r\n";

View file

@ -5,8 +5,8 @@
// - doesn't set the Content-Type to text/xml (we do). // - doesn't set the Content-Type to text/xml (we do).
// Force HTTP authentication first! // Force HTTP authentication first!
require_once('httpauth.inc.php'); $httpContentType = 'text/xml';
require_once '../www-header.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark'); $bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
@ -17,7 +17,6 @@ $bookmarks =& $bookmarkservice->getBookmarks(0, 1, $userservice->getCurrentUserI
// Set up the XML file and output all the tags. // Set up the XML file and output all the tags.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
foreach($bookmarks['bookmarks'] as $row) { foreach($bookmarks['bookmarks'] as $row) {
echo '<update time="'. gmdate('Y-m-d\TH:i:s\Z', strtotime($row['bDatetime'])) .'" />'; echo '<update time="'. gmdate('Y-m-d\TH:i:s\Z', strtotime($row['bDatetime'])) .'" />';

View file

@ -5,8 +5,8 @@
// - tags can't have spaces // - tags can't have spaces
// Force HTTP authentication first! // Force HTTP authentication first!
require_once('httpauth.inc.php'); $httpContentType = 'text/xml';
require_once '../www-header.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag'); $b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
@ -16,7 +16,6 @@ $b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
$tags =& $b2tservice->getTags($userservice->getCurrentUserId()); $tags =& $b2tservice->getTags($userservice->getCurrentUserId());
// Set up the XML file and output all the tags. // Set up the XML file and output all the tags.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo "<tags>\r\n"; echo "<tags>\r\n";
foreach($tags as $row) { foreach($tags as $row) {

View file

@ -5,8 +5,8 @@
// - oddly, returns an entirely different result (<result></result>) than the other API calls. // - oddly, returns an entirely different result (<result></result>) than the other API calls.
// Force HTTP authentication first! // Force HTTP authentication first!
require_once('httpauth.inc.php'); $httpContentType = 'text/xml';
require_once '../www-header.php'; require_once 'httpauth.inc.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag'); $b2tservice =SemanticScuttle_Service_Factory::get('Bookmark2Tag');
@ -31,7 +31,6 @@ if (is_null($old) || is_null($new)) {
} }
// Set up the XML file and output the result. // Set up the XML file and output the result.
header('Content-Type: text/xml');
echo '<?xml version="1.0" standalone="yes" ?'.">\r\n"; echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
echo '<result>'. ($renamed ? 'done' : 'something went wrong') .'</result>'; echo '<result>'. ($renamed ? 'done' : 'something went wrong') .'</result>';
?> ?>

View file

@ -134,7 +134,7 @@ if ($userservice->isLoggedOn() && POST_SUBMITTED != '') {
$address = trim(POST_ADDRESS); $address = trim(POST_ADDRESS);
// If the bookmark exists already, edit the original // If the bookmark exists already, edit the original
if ($bookmarkservice->bookmarkExists($address, $currentUserID)) { if ($bookmarkservice->bookmarkExists($address, $currentUserID)) {
$bookmark =& $bookmarkservice->getBookmarkByAddress($address); $bookmark = $bookmarkservice->getBookmarkByAddress($address);
header('Location: '. createURL('edit', $bookmark['bId'])); header('Location: '. createURL('edit', $bookmark['bId']));
exit(); exit();
// If it's new, save it // If it's new, save it
@ -167,7 +167,7 @@ if ($userservice->isLoggedOn() && POST_SUBMITTED != '') {
if (GET_ACTION == "add") { if (GET_ACTION == "add") {
// If the bookmark exists already, edit the original // If the bookmark exists already, edit the original
if ($bookmarkservice->bookmarkExists(stripslashes(GET_ADDRESS), $currentUserID)) { if ($bookmarkservice->bookmarkExists(stripslashes(GET_ADDRESS), $currentUserID)) {
$bookmark =& $bookmarkservice->getBookmarks(0, NULL, $currentUserID, NULL, NULL, NULL, NULL, NULL, NULL, md5($bookmarkservice->normalize(stripslashes(GET_ADDRESS)))); $bookmark =& $bookmarkservice->getBookmarks(0, NULL, $currentUserID, NULL, NULL, NULL, NULL, NULL, NULL, $bookmarkservice->getHash(stripslashes(GET_ADDRESS)));
$popup = (GET_POPUP!='') ? '?popup=1' : ''; $popup = (GET_POPUP!='') ? '?popup=1' : '';
header('Location: '. createURL('edit', $bookmark['bookmarks'][0]['bId'] . $popup)); header('Location: '. createURL('edit', $bookmark['bookmarks'][0]['bId'] . $popup));
exit(); exit();

View file

@ -15,6 +15,7 @@
* @license GPL http://www.gnu.org/licenses/gpl.html * @license GPL http://www.gnu.org/licenses/gpl.html
* @link http://sourceforge.net/projects/semanticscuttle * @link http://sourceforge.net/projects/semanticscuttle
*/ */
$httpContentType = false;
require_once 'www-header.php'; require_once 'www-header.php';
if (!$GLOBALS['shorturl']) { if (!$GLOBALS['shorturl']) {

View file

@ -67,19 +67,16 @@ if (intval(GET_PAGE) > 1) {
$start = 0; $start = 0;
} }
$dtend = date('Y-m-d H:i:s', strtotime('tomorrow')); $tplVars['page'] = $page;
/*$dtstart = date('Y-m-d H:i:s', strtotime($dtend .' -'. $defaultRecentDays .' days'));*/ $tplVars['start'] = $start;
$tplVars['page'] = $page;
$tplVars['start'] = $start;
$tplVars['popCount'] = 30; $tplVars['popCount'] = 30;
$tplVars['sidebar_blocks'] = $GLOBALS["index_sidebar_blocks"]; $tplVars['sidebar_blocks'] = $GLOBALS["index_sidebar_blocks"];
$tplVars['range'] = 'all'; $tplVars['range'] = 'all';
$tplVars['pagetitle'] = T_('Store, share and tag your favourite links'); $tplVars['pagetitle'] = T_('Store, share and tag your favourite links');
$tplVars['subtitle'] = T_('All Bookmarks'); $tplVars['subtitle'] = T_('All Bookmarks');
$tplVars['bookmarkCount'] = $start + 1; $tplVars['bookmarkCount'] = $start + 1;
$bookmarks =& $bookmarkservice->getBookmarks($start, $perpage, NULL, NULL, NULL, getSortOrder(), NULL, 0, $dtend); $bookmarks = $bookmarkservice->getBookmarks($start, $perpage, NULL, NULL, NULL, getSortOrder(), NULL, 0, NULL);
$tplVars['total'] = $bookmarks['total']; $tplVars['total'] = $bookmarks['total'];
$tplVars['bookmarks'] =& $bookmarks['bookmarks']; $tplVars['bookmarks'] =& $bookmarks['bookmarks'];

View file

@ -1,6 +1,6 @@
<?php <?php
header('Content-Type: text/javascript');
$GLOBALS['saveInLastUrl'] = false; $GLOBALS['saveInLastUrl'] = false;
$httpContentType = 'text/javascript';
require_once 'www-header.php'; require_once 'www-header.php';
require_once 'SemanticScuttle/functions.php'; require_once 'SemanticScuttle/functions.php';
$player_root = ROOT .'includes/player/'; $player_root = ROOT .'includes/player/';

View file

@ -19,14 +19,13 @@
* @link http://sourceforge.net/projects/semanticscuttle * @link http://sourceforge.net/projects/semanticscuttle
*/ */
$httpContentType = 'application/rss+xml';
require_once 'www-header.php'; require_once 'www-header.php';
/* Service creation: only useful services are created */ /* Service creation: only useful services are created */
$bookmarkservice = SemanticScuttle_Service_Factory::get('Bookmark'); $bookmarkservice = SemanticScuttle_Service_Factory::get('Bookmark');
$cacheservice = SemanticScuttle_Service_Factory::get('Cache'); $cacheservice = SemanticScuttle_Service_Factory::get('Cache');
header('Content-Type: application/rss+xml; charset=utf-8');
if (isset($_SERVER['PATH_INFO']) && strlen($_SERVER['PATH_INFO']) >1) { if (isset($_SERVER['PATH_INFO']) && strlen($_SERVER['PATH_INFO']) >1) {
list($url, $user, $cat) = explode('/', $_SERVER['PATH_INFO']); list($url, $user, $cat) = explode('/', $_SERVER['PATH_INFO']);
} else { } else {