diff --git a/bookmarks.php b/bookmarks.php index cc5eba4..b397c6c 100644 --- a/bookmarks.php +++ b/bookmarks.php @@ -173,9 +173,11 @@ if ($templatename == 'editbookmark.tpl') { if (!$cat) { $cat = NULL; $tplVars['currenttag'] = NULL; + $tplVars['sidebar_blocks'][] = 'linked'; //test } else { $rssCat = '/'. filter($cat, 'url'); $tplVars['currenttag'] = $cat; + $tplVars['sidebar_blocks'][] = 'linked'; $tplVars['sidebar_blocks'][] = 'related'; $tplVars['sidebar_blocks'][] = 'tagactions'; } diff --git a/header.inc.php b/header.inc.php index 751e4e8..6b4e76b 100644 --- a/header.inc.php +++ b/header.inc.php @@ -31,4 +31,4 @@ define('GENERAL_MESSAGE', 200); define('GENERAL_ERROR', 202); define('CRITICAL_MESSAGE', 203); define('CRITICAL_ERROR', 204); -?> \ No newline at end of file +?> diff --git a/services/bookmarkservice.php b/services/bookmarkservice.php index afc7179..fdb49a0 100644 --- a/services/bookmarkservice.php +++ b/services/bookmarkservice.php @@ -1,6 +1,7 @@ db = & $db; + $this->tablename = $GLOBALS['tableprefix'] .'bookmarks'; } function _getbookmark($fieldname, $value, $all = false) { @@ -20,7 +22,7 @@ class BookmarkService { $range = ' AND uId = '. $sId; } - $query = 'SELECT * FROM '. $GLOBALS['tableprefix'] .'bookmarks WHERE '. $fieldname .' = "'. $this->db->sql_escape($value) .'"'. $range; + $query = 'SELECT * FROM '. $this->getTableName() .' WHERE '. $fieldname .' = "'. $this->db->sql_escape($value) .'"'. $range; if (!($dbresult = & $this->db->sql_query_limit($query, 1, 0))) { message_die(GENERAL_ERROR, 'Could not get bookmark', '', __LINE__, __FILE__, $query, $this->db); @@ -38,7 +40,7 @@ class BookmarkService { if (!is_numeric($bid)) return; - $sql = 'SELECT * FROM '. $GLOBALS['tableprefix'] .'bookmarks WHERE bId = '. $this->db->sql_escape($bid); + $sql = 'SELECT * FROM '. $this->getTableName() .' WHERE bId = '. $this->db->sql_escape($bid); if (!($dbresult = & $this->db->sql_query($sql))) message_die(GENERAL_ERROR, 'Could not get vars', '', __LINE__, __FILE__, $sql, $this->db); @@ -103,9 +105,11 @@ class BookmarkService { // Adds a bookmark to the database. // Note that date is expected to be a string that's interpretable by strtotime(). - function addBookmark($address, $title, $description, $status, $categories, $date = NULL, $fromApi = false, $fromImport = false) { - $userservice = & ServiceFactory :: getServiceInstance('UserService'); - $sId = $userservice->getCurrentUserId(); + function addBookmark($address, $title, $description, $status, $categories, $date = NULL, $fromApi = false, $fromImport = false, $sId = -1) { + if($sId == -1) { + $userservice = & ServiceFactory :: getServiceInstance('UserService'); + $sId = $userservice->getCurrentUserId(); + } // If bookmark address doesn't contain ":", add "http://" to the start as a default protocol if (strpos($address, ':') === false) { @@ -131,7 +135,7 @@ class BookmarkService { // Set up the SQL insert statement and execute it. $values = array('uId' => intval($sId), 'bIp' => $ip, 'bDatetime' => $datetime, 'bModified' => $datetime, 'bTitle' => $title, 'bAddress' => $address, 'bDescription' => $description, 'bStatus' => intval($status), 'bHash' => md5($address)); - $sql = 'INSERT INTO '. $GLOBALS['tableprefix'] .'bookmarks '. $this->db->sql_build_array('INSERT', $values); + $sql = 'INSERT INTO '. $this->getTableName() .' '. $this->db->sql_build_array('INSERT', $values); $this->db->sql_transaction('begin'); if (!($dbresult = & $this->db->sql_query($sql))) { $this->db->sql_transaction('rollback'); @@ -220,6 +224,7 @@ class BookmarkService { // - if the $user is set and IS the logged-in user, then get all bookmarks. $userservice =& ServiceFactory::getServiceInstance('UserService'); $tagservice =& ServiceFactory::getServiceInstance('TagService'); + $tag2tagservice =& ServiceFactory::getServiceInstance('Tag2TagService'); $sId = $userservice->getCurrentUserId(); if ($userservice->isLoggedOn()) { @@ -252,7 +257,7 @@ class BookmarkService { } $query_1 .= 'B.*, U.'. $userservice->getFieldName('username'); - $query_2 = ' FROM '. $userservice->getTableName() .' AS U, '. $GLOBALS['tableprefix'] .'bookmarks AS B'; + $query_2 = ' FROM '. $userservice->getTableName() .' AS U, '. $this->getTableName() .' AS B'; $query_3 = ' WHERE B.uId = U.'. $userservice->getFieldName('primary') . $privacy; if (is_null($watched)) { @@ -295,8 +300,23 @@ class BookmarkService { // Handle the parts of the query that depend on any tags that are present. $query_4 = ''; for ($i = 0; $i < $tagcount; $i ++) { - $query_2 .= ', '. $GLOBALS['tableprefix'] .'tags AS T'. $i; - $query_4 .= ' AND T'. $i .'.tag = "'. $this->db->sql_escape($tags[$i]) .'" AND T'. $i .'.bId = B.bId'; + $query_2 .= ', '. $tagservice->getTableName() .' AS T'. $i; + $query_4 .= ' AND ('; + + $allLinkedTags = $tag2tagservice->getAllLinkedTags($this->db->sql_escape($tags[$i]), '>', $user); + while (count($allLinkedTags)>1) { + $query_4 .= ' T'. $i .'.tag = "'. array_pop($allLinkedTags) .'"'; + $query_4 .= ' OR'; + } + if(is_array($allLinkedTags)) { + $query_4 .= ' T'. $i .'.tag = "'. array_pop($allLinkedTags) .'"'; + } else { + $query_4 .= ' T'. $i .'.tag = "'. $allLinkedTags .'"'; + } + + + $query_4 .= ') AND T'. $i .'.bId = B.bId'; +//die($query_4); } // Search terms @@ -307,7 +327,7 @@ class BookmarkService { // Search terms in tags as well when none given if (!count($tags)) { - $query_2 .= ' LEFT JOIN '. $GLOBALS['tableprefix'] .'tags AS T ON B.bId = T.bId'; + $query_2 .= ' LEFT JOIN '. $tagservice->getTableName() .' AS T ON B.bId = T.bId'; $dotags = true; } else { $dotags = false; @@ -336,8 +356,8 @@ class BookmarkService { if ($hash) { $query_4 .= ' AND B.bHash = "'. $hash .'"'; } - $query = $query_1 . $query_2 . $query_3 . $query_4 . $query_5; +//die($query); if (!($dbresult = & $this->db->sql_query_limit($query, intval($perpage), intval($start)))) { message_die(GENERAL_ERROR, 'Could not get bookmarks', '', __LINE__, __FILE__, $query, $this->db); return false; @@ -412,5 +432,18 @@ class BookmarkService { } return $this->db->sql_fetchfield(0, 0) - 1; } + + function deleteAll() { + $query = 'TRUNCATE TABLE `'. $this->getTableName() .'`'; + $this->db->sql_query($query); + } + + // Properties + function getTableName() { return $this->tablename; } + function setTableName($value) { $this->tablename = $value; } + } + + + ?> diff --git a/services/servicefactory.php b/services/servicefactory.php index ba2d6d7..9d50841 100644 --- a/services/servicefactory.php +++ b/services/servicefactory.php @@ -30,4 +30,4 @@ class ServiceFactory { return $instances[$name]; } } -?> \ No newline at end of file +?> diff --git a/services/tag2tagservice.php b/services/tag2tagservice.php new file mode 100644 index 0000000..0b53d64 --- /dev/null +++ b/services/tag2tagservice.php @@ -0,0 +1,143 @@ +db =& $db; + $this->tablename = $GLOBALS['tableprefix'] .'tags2tags'; + } + + function addLinkedTags($tag1, $tag2, $relationType, $uId) { + if($tag1 == $tag2) { + return false; + } + $values = array('tag1' => $tag1, 'tag2' => $tag2, 'relationType'=> $relationType, 'uId'=> $uId); + $query = 'INSERT INTO '. $this->getTableName() .' '. $this->db->sql_build_array('INSERT', $values); +//die($query); + if (!($dbresult =& $this->db->sql_query($query))) { + $this->db->sql_transaction('rollback'); + message_die(GENERAL_ERROR, 'Could not attach tag to tag', '', __LINE__, __FILE__, $query, $this->db); + return false; + } + $this->db->sql_transaction('commit'); + return true; + } + + function getLinkedTags($tag1, $relationType, $uId) { + // Set up the SQL query. + $query = "SELECT DISTINCT tag2 as 'tag' FROM `". $this->getTableName() ."`"; + $query.= " WHERE tag1 = '" .$tag1 ."'"; + if($relationType) { + $query.= " AND relationType = '". $relationType ."'"; + } + if($uId) { + $query.= " AND uId = '".$uId."'"; + } + + if (! ($dbresult =& $this->db->sql_query_limit($query, $limit)) ){ + message_die(GENERAL_ERROR, 'Could not get related tags', '', __LINE__, __FILE__, $query, $this->db); + return false; + } + + $rowset = $this->db->sql_fetchrowset($dbresult); + $output = array(); + foreach($rowset as $row) { + $output[] = $row['tag']; + } + return $output; + } + + /* TODO: clean the outputs to obtain homogenous ones*/ + function getAllLinkedTags($tag1, $relationType, $uId, $asFlatList=true, $stopList=array()) { + if(in_array($tag1, $stopList)) { + return $tag1; + } + $linkedTags = $this->getLinkedTags($tag1, $relationType, $uId); + if(count($linkedTags) == 0) { + return $tag1; + } else { + $output = array(); + if($asFlatList == true) { + $output[$tag1] = $tag1; + } else { + $output = array('node'=>$tag1); + } + + $stopList[] = $tag1; + foreach($linkedTags as $linkedTag) { + $allLinkedTags = $this->getAllLinkedTags($linkedTag, $relationType, $uId, $asFlatList, $stopList); + if($asFlatList == true) { + if(is_array($allLinkedTags)) { + $output = array_merge($output, $allLinkedTags); + } else { + $output[$allLinkedTags] = $allLinkedTags; + } + } else { + $output[] = $allLinkedTags; + } + } + } + return $output; + } + + function getOrphewTags($relationType, $uId) { + $query = "SELECT DISTINCT tag1 as tag FROM `". $this->getTableName() ."`"; + $query.= " WHERE tag1 <> ALL"; + $query.= " (SELECT DISTINCT tag2 FROM `". $this->getTableName() ."`"; + $query.= " WHERE relationType = '".$relationType."'"; + $query.= " AND uId = '".$uId."'"; + $query.= ")"; + $query.= " AND uId = '".$uId."'"; + + //die($query); + + if (! ($dbresult =& $this->db->sql_query_limit($query, $limit)) ){ + message_die(GENERAL_ERROR, 'Could not get linked tags', '', __LINE__, __FILE__, $query, $this->db); + return false; + } + return $this->db->sql_fetchrowset($dbresult); + } + + function existsLinkedTags($tag1, $tag2, $relationType, $uId) { + $query = "SELECT tag1, tag2, relationType, uId FROM `". $this->getTableName() ."`"; + $query.= " WHERE tag1 = '" .$tag1 ."'"; + $query.= " AND tag2 = '".$tag2."'"; + $query.= " AND relationType = '". $relationType ."'"; + $query.= " AND uId = '".$uId."'"; + + return $this->db->sql_numrows($dbresult) > 0; + } + + function removeLinkedTags($tag1, $tag2, $relationType, $uId) { + $query = 'DELETE FROM '. $this->getTableName(); + $query.= ' WHERE tag1 = "'. $tag1 .'"'; + $query.= ' AND tag2 = "'. $tag2 .'"'; + $query.= ' AND relationType = "'. $relationType .'"'; + $query.= ' AND uId = "'. $uId .'"'; + + if (!($dbresult =& $this->db->sql_query($query))) { + message_die(GENERAL_ERROR, 'Could not remove tag relation', '', __LINE__, __FILE__, $query, $this->db); + return false; + } + + return true; + } + + function deleteAll() { + $query = 'TRUNCATE TABLE `'. $this->getTableName() .'`'; + $this->db->sql_query($query); + } + + // Properties + function getTableName() { return $this->tablename; } + function setTableName($value) { $this->tablename = $value; } +} +?> diff --git a/services/tagservice.php b/services/tagservice.php index 6bfbf15..509e575 100644 --- a/services/tagservice.php +++ b/services/tagservice.php @@ -86,6 +86,25 @@ class TagService { } } + // Create links between tags + foreach($tags as $key => $tag) { + // case ">" + $pieces = explode('>', $tag); + $nbPieces = count($pieces); + if($nbPieces > 1) { + for($i = 0; $i < $nbPieces-1; $i++) { + $bs =& ServiceFactory::getServiceInstance('BookmarkService'); + $tts =& ServiceFactory::getServiceInstance('Tag2TagService'); + + $bookmark = $bs->getBookmark($bookmarkid); + $uId = $bookmark['uId']; + $tts->addLinkedTags($pieces[$i], $pieces[$i+1], '>', $uId); + } + $tags[$key] = $pieces[$nbPieces-1]; // Attach just the last tag to the bookmark + } + + } + // Add the categories to the DB. for ($i = 0; $i < count($tags); $i++) { if ($tags[$i] != '') { @@ -356,8 +375,14 @@ class TagService { return $output; } + function deleteAll() { + $query = 'TRUNCATE TABLE `'. $this->getTableName() .'`'; + $this->db->sql_query($query); + } + + // Properties function getTableName() { return $this->tablename; } function setTableName($value) { $this->tablename = $value; } } -?> \ No newline at end of file +?> diff --git a/services/userservice.php b/services/userservice.php index 1e7ed46..b585388 100644 --- a/services/userservice.php +++ b/services/userservice.php @@ -20,7 +20,7 @@ class UserService { var $cookiekey; var $cookietime = 1209600; // 2 weeks - function UserService(&$db) { + function UserService(& $db) { $this->db =& $db; $this->tablename = $GLOBALS['tableprefix'] .'users'; $this->sessionkey = $GLOBALS['cookieprefix'] .'-currentuserid'; diff --git a/tables.sql b/tables.sql index 578fa06..fc38621 100644 --- a/tables.sql +++ b/tables.sql @@ -65,4 +65,20 @@ CREATE TABLE `sc_watched` ( `watched` int(11) NOT NULL default '0', PRIMARY KEY (`wId`), KEY `sc_watched_uId` (`uId`) -); \ No newline at end of file +); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `sc_tags_tags` +-- + +CREATE TABLE `sc_tags2tags` ( + `ttId` int(11) NOT NULL auto_increment, + `tag1` varchar(32) NOT NULL default '', + `tag2` varchar(32) NOT NULL default '', + `relationType` varchar(32) NOT NULL default '', + `uId` int(11) NOT NULL default '0', + PRIMARY KEY (`ttId`), + UNIQUE KEY `sc_tags2tags_tag1_tag2_uId` (`tag1`,`tag2`,`relationType`,`uId`) +); diff --git a/tag2tagadd.php b/tag2tagadd.php new file mode 100644 index 0000000..916c388 --- /dev/null +++ b/tag2tagadd.php @@ -0,0 +1,50 @@ +addLinkedTags($tag, $newTag, '>', $userservice->getCurrentUserId())) { + $tplVars['msg'] = T_('Tag link created'); + $logged_on_user = $userservice->getCurrentUser(); + header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')])); + } else { + $tplVars['error'] = T_('Failed to create the link'); + $templateservice->loadTemplate('error.500.tpl', $tplVars); + exit(); + } +} elseif ($_POST['cancel']) { + $logged_on_user = $userservice->getCurrentUser(); + header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')] .'/'. $tags)); +} + +$tplVars['tag'] = $tag; +$tplVars['subtitle'] = T_('Add Tag Link') .': '. $tag; +$tplVars['formaction'] = $_SERVER['SCRIPT_NAME'] .'/'. $tag; +$tplVars['referrer'] = $_SERVER['HTTP_REFERER']; +$templateservice->loadTemplate('tag2tagadd.tpl', $tplVars); +?> diff --git a/tag2tagdelete.php b/tag2tagdelete.php new file mode 100644 index 0000000..e75e60a --- /dev/null +++ b/tag2tagdelete.php @@ -0,0 +1,50 @@ +removeLinkedTags($_POST['tag1'], $_POST['tag2'], '>', $userservice->getCurrentUserId())) { + $tplVars['msg'] = T_('Tag link deleted'); + $logged_on_user = $userservice->getCurrentUser(); + header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')])); + } else { + $tplVars['error'] = T_('Failed to delete the link'); + $templateservice->loadTemplate('error.500.tpl', $tplVars); + exit(); + } +} elseif ($_POST['cancel']) { + $logged_on_user = $userservice->getCurrentUser(); + header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')] .'/'. $tags)); +} + +$tplVars['tag1'] = $tag1; +$tplVars['tag2'] = $tag2; +$tplVars['subtitle'] = T_('Delete Link Between Tags') .': '. $tag1.' > '.$tag2; +$tplVars['formaction'] = $_SERVER['SCRIPT_NAME'] .'/'. $tag; +$tplVars['referrer'] = $_SERVER['HTTP_REFERER']; +$templateservice->loadTemplate('tag2tagdelete.tpl', $tplVars); +?> diff --git a/templates/editbookmark.tpl.php b/templates/editbookmark.tpl.php index a590d81..f707668 100644 --- a/templates/editbookmark.tpl.php +++ b/templates/editbookmark.tpl.php @@ -45,6 +45,10 @@ window.onload = function() { + + + " to include one tag in another. e.g.: europe>france>paris')?> + @@ -117,4 +121,4 @@ document.write('<\/ul>'); includeTemplate($GLOBALS['bottom_include']); -?> \ No newline at end of file +?> diff --git a/templates/sidebar.block.linked.php b/templates/sidebar.block.linked.php new file mode 100644 index 0000000..23bcb0c --- /dev/null +++ b/templates/sidebar.block.linked.php @@ -0,0 +1,78 @@ +'; + $output.= ''; + $output.= ''. str_repeat(' ', $level*2) .''; + if($editingMode) { + $output.= ' ('; + $output.= 'add'; + if($precedentTag != null) { + $output.= ' - '; + $output.= 'del'; + } + $output.= ')'; + } + $output.= ''; + $output.= ''; + + if(!in_array($tag, $stopList)) { + $linkedTags = $tag2tagservice->getLinkedTags($tag, '>', $userid, $level); + $precedentTag = $tag; + $stopList[] = $tag; + $level = $level + 1; + foreach($linkedTags as $linkedTag) { + $output.= displayLinkedTags($linkedTag, $linkType, $uId, $cat_url, $user, $editingMode, $precedentTag, $level, $stopList); + } + } + return $output; +} + + +$logged_on_userid = $userservice->getCurrentUserId(); +if ($logged_on_userid === false) { + $logged_on_userid = NULL; +} + +$explodedTags = array(); +if ($currenttag) { + $explodedTags = explode('+', $currenttag); +} else { + $orphewTags = $tag2tagservice->getOrphewTags('>', $userid); + foreach($orphewTags as $orphewTag) { + $explodedTags[] = $orphewTag['tag']; + } +} + +if(count($explodedTags) > 0) { + $displayLinkedZone = false; + foreach($explodedTags as $explodedTag) { + if($tag2tagservice->getLinkedTags($explodedTag, '>', $userid)) { + $displayLinkedZone = true; + break; + } + } + if ($displayLinkedZone) { +?> + +

+
+ + ', $userid, $cat_url, $user, $editingMode); + } + ?> +
+
+ + diff --git a/templates/tag2tagadd.tpl.php b/templates/tag2tagadd.tpl.php new file mode 100644 index 0000000..5b5ea58 --- /dev/null +++ b/templates/tag2tagadd.tpl.php @@ -0,0 +1,23 @@ +includeTemplate($GLOBALS['top_include']); +?> + +
+ +

+

>

+ +

+ + +

+ + +
+ + +
+ +includeTemplate($GLOBALS['bottom_include']); +?> diff --git a/templates/tag2tagdelete.tpl.php b/templates/tag2tagdelete.tpl.php new file mode 100644 index 0000000..9a276d1 --- /dev/null +++ b/templates/tag2tagdelete.tpl.php @@ -0,0 +1,22 @@ +includeTemplate($GLOBALS['top_include']); +?> + +
+ + +

+

+ + +

+ + +
+ + +
+ +includeTemplate($GLOBALS['bottom_include']); +?> diff --git a/tests/tag2TagTest.php b/tests/tag2TagTest.php new file mode 100644 index 0000000..6660761 --- /dev/null +++ b/tests/tag2TagTest.php @@ -0,0 +1,139 @@ +us =& ServiceFactory::getServiceInstance('UserService'); + $this->bs =& ServiceFactory::getServiceInstance('BookmarkService'); + $this->bs->deleteAll(); + $this->ts =& ServiceFactory::getServiceInstance('TagService'); + $this->ts->deleteAll(); + $this->tts =& ServiceFactory::getServiceInstance('Tag2TagService'); + $this->tts->deleteAll(); + } + + public function testManipulateTag2TagRelations() + { + $tts = $this->tts; + + $tts->addLinkedTags('a', 'b', '>', 1); + $tts->addLinkedTags('a', 'c', '>', 1); + $tts->addLinkedTags('a', 'd', '>', 20); + $tts->addLinkedTags('b', 'a', '>', 1); //warning: recursive link + $tts->addLinkedTags('b', 'd', '>', 1); + $tts->addLinkedTags('d', 'e', '>', 1); + $tts->addLinkedTags('d', 'e', '>', 20); + $tts->addLinkedTags('f', 'g', '>', 20); + + $allLinkedTags = $tts->getAllLinkedTags('a', '>', 1, false); //as tree + $this->assertSame(array('node'=>'a', array('node'=>'b', 'a', array('node'=>'d', 'e')), 'c'), $allLinkedTags); + $allLinkedTags = $tts->getAllLinkedTags('a', '>', 1, true); // as flat list + $this->assertEquals(5, sizeof($allLinkedTags)); + $this->assertTrue(in_array('a', $allLinkedTags)); + $this->assertTrue(in_array('b', $allLinkedTags)); + $this->assertTrue(in_array('c', $allLinkedTags)); + $this->assertTrue(in_array('d', $allLinkedTags)); + $this->assertTrue(in_array('e', $allLinkedTags)); + + $orphewTags = $tts->getOrphewTags('>', 1); + $this->assertEquals(0, sizeof($orphewTags)); + $orphewTags = $tts->getOrphewTags('>', 20); + $this->assertEquals(2, sizeof($orphewTags)); + $this->assertSame('a', $orphewTags[0]['tag']); + $this->assertSame('f', $orphewTags[1]['tag']); + + $linkedTags = $tts->getLinkedTags('a', '>', 1); + $this->assertSame(array('b', 'c'), $linkedTags); + $tts->removeLinkedTags('a', 'b', '>', 1); + $linkedTags = $tts->getLinkedTags('a', '>', 1); + $this->assertSame(array('c'), $linkedTags); + $tts->removeLinkedTags('a', 'c', '>', 1); + $linkedTags = $tts->getLinkedTags('a', '>', 1); + $this->assertEquals(0, sizeof($linkedTags)); + } + + public function testAddLinkedTagsThroughBookmarking() + { + $bs = $this->bs; + $tags = array('a>b', 'b>c', 'a>d>e', 'a>a', 'a'); + $bs->addBookmark("http://google.com", "title", "description", "status", $tags, null, false, false, 1); + $bookmark = $bs->getBookmarkByAddress("http://google.com"); + + $ts = $this->ts; + $savedTags = $ts->getTagsForBookmark(intval($bookmark['bId'])); + $this->assertEquals(4, sizeof($savedTags)); + $this->assertContains('b', $savedTags); + $this->assertContains('c', $savedTags); + $this->assertContains('e', $savedTags); + $this->assertContains('a', $savedTags); + + $tts = $this->tts; + $linkedTags = $tts->getLinkedTags('a', '>', 1); + $this->assertEquals(2, sizeof($linkedTags)); + $this->assertSame('b', $linkedTags[0]['tag']); + $this->assertSame('d', $linkedTags[1]['tag']); + $linkedTags = $tts->getLinkedTags('b', '>', 1); + $this->assertEquals(1, sizeof($linkedTags)); + $this->assertSame('c', $linkedTags[0]['tag']); + $this->assertTrue($tts->existsLinkedTags('d', 'e', '>', 1)); + } + + public function testSearchThroughLinkedTags() + { + $tts = $this->tts; + $bs = $this->bs; + + $tags1 = array('aa>bb>cc', 'dd'); + $bs->addBookmark("web.com", "B1", "description", "status", $tags1, null, false, false, 1); + $tags = array('bb>gg', 'ee>ff'); + $bs->addBookmark("web.com", "B2", "description", "status", $tags, null, false, false, 1); + $tags = array('ee'); + $bs->addBookmark("web.com", "B3", "description", "status", $tags, null, false, false, 1); + + // Query format: + // $bs->getBookmarks($start = 0, $perpage = NULL, $user = NULL, $tags = NULL, $terms = NULL, $sortOrder = NULL, $watched = NULL, $startdate = NULL, $enddate = NULL, $hash = NULL); + + // basic queries + $results = $bs->getBookmarks(0, NULL, 1, 'dd'); + $this->assertSame(1, intval($results['total'])); + $this->assertSame('B1', $results['bookmarks'][0]['bTitle']); + + $results = $bs->getBookmarks(0, NULL, 1, 'cc'); + $this->assertSame(1, intval($results['total'])); + $this->assertSame('B1', $results['bookmarks'][0]['bTitle']); + + //advanced queries + $results = $bs->getBookmarks(0, NULL, 1, 'aa'); + $this->assertSame(2, intval($results['total'])); + $this->assertSame('B1', $results['bookmarks'][0]['bTitle']); + $this->assertSame('B2', $results['bookmarks'][1]['bTitle']); + + $results = $bs->getBookmarks(0, NULL, 1, 'ee'); + $this->assertSame(2, intval($results['total'])); + $this->assertSame('B2', $results['bookmarks'][0]['bTitle']); + $this->assertSame('B3', $results['bookmarks'][1]['bTitle']); + + $results = $bs->getBookmarks(0, NULL, 1, 'aa+ee'); + $this->assertSame(1, intval($results['total'])); + $this->assertSame('B2', $results['bookmarks'][0]['bTitle']); + + } + +} +?>