]> gitweb.fluxo.info Git - semanticscuttle.git/commitdiff
Structured tags '>' for each user
authormensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f>
Wed, 9 Jan 2008 15:51:35 +0000 (15:51 +0000)
committermensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f>
Wed, 9 Jan 2008 15:51:35 +0000 (15:51 +0000)
git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@3 b3834d28-1941-0410-a4f8-b48e95affb8f

15 files changed:
bookmarks.php
header.inc.php
services/bookmarkservice.php
services/servicefactory.php
services/tag2tagservice.php [new file with mode: 0644]
services/tagservice.php
services/userservice.php
tables.sql
tag2tagadd.php [new file with mode: 0644]
tag2tagdelete.php [new file with mode: 0644]
templates/editbookmark.tpl.php
templates/sidebar.block.linked.php [new file with mode: 0644]
templates/tag2tagadd.tpl.php [new file with mode: 0644]
templates/tag2tagdelete.tpl.php [new file with mode: 0644]
tests/tag2TagTest.php [new file with mode: 0644]

index cc5eba4582286f20b9acbb220f957db910522d8e..b397c6c98d63aec6839c91b0e743a5fc61d78781 100644 (file)
@@ -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';
     }
index 751e4e81ca8622a054ad71bc1eb781f818174bba..6b4e76b51c9006efdc024cf6d2548c36d7c0cf35 100644 (file)
@@ -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
+?>
index afc717973c664e67b917f3286109d3fbce049217..fdb49a039ba4dae8e364fbe6ef8087a8d7152906 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 class BookmarkService {
     var $db;
+    var $tablename;
 
     function & getInstance(& $db) {
         static $instance;
@@ -11,6 +12,7 @@ class BookmarkService {
 
     function BookmarkService(& $db) {
         $this->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; }
+
 }
+
+
+
 ?>
index ba2d6d7910a1ecc459d1ac09008847b0ba831f16..9d508415d634936dcc5b02c69917af6ad9b280d9 100644 (file)
@@ -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 (file)
index 0000000..0b53d64
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+class Tag2TagService {
+    var $db;
+    var $tablename;
+
+    function &getInstance(&$db) {
+        static $instance;
+        if (!isset($instance))
+            $instance =& new Tag2TagService($db);
+        return $instance;
+    }
+
+    function Tag2TagService(&$db) {
+        $this->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; }
+}
+?>
index 6bfbf151d582a24401c121697832a5c14df9b2ca..509e5759d0879a81f939fa5b36b26ae01f965cee 100644 (file)
@@ -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
+?>
index 1e7ed46981a39e46b0a4370d2b8735246ffd65d5..b5853889dba8a916cca061918dcffae53897888b 100644 (file)
@@ -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';
index 578fa0670986a4e1dcf87cf65013ed61e0910ff5..fc38621d8732e7267b8ad31a8190fafef858eeca 100644 (file)
@@ -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 (file)
index 0000000..916c388
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/***************************************************************************
+Copyright (C) 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.org/
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+***************************************************************************/
+
+require_once('header.inc.php');
+$tag2tagservice = & ServiceFactory :: getServiceInstance('Tag2TagService');
+$templateservice = & ServiceFactory :: getServiceInstance('TemplateService');
+$userservice = & ServiceFactory :: getServiceInstance('UserService');
+
+list ($url, $tag) = explode('/', $_SERVER['PATH_INFO']);
+
+if ($_POST['confirm']) {
+    $newTag = $_POST['newTag'];
+    if ($tag2tagservice->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 (file)
index 0000000..e75e60a
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/***************************************************************************
+Copyright (C) 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.org/
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+***************************************************************************/
+
+require_once('header.inc.php');
+$tag2tagservice = & ServiceFactory :: getServiceInstance('Tag2TagService');
+$templateservice = & ServiceFactory :: getServiceInstance('TemplateService');
+$userservice = & ServiceFactory :: getServiceInstance('UserService');
+
+list ($url, $tag1, $tag2) = explode('/', $_SERVER['PATH_INFO']);
+
+if ($_POST['confirm']) {
+    if ($tag2tagservice->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);
+?>
index a590d818aa54fa0806de91ce25879ce80c3b02e2..f7076685cef8cf9dfe3539ad908c24e77a3217c2 100644 (file)
@@ -45,6 +45,10 @@ window.onload = function() {
     <td><input type="text" id="tags" name="tags" size="75" value="<?php echo filter(implode(', ', $row['tags']), 'xml'); ?>" /></td>
     <td>&larr; <?php echo T_('Comma-separated'); ?></td>
 </tr>
+<tr>
+    <th></th>
+    <td align="right"><small><?php echo T_('Note: use ">" to include one tag in another. e.g.: europe>france>paris')?><small></td>
+</tr>
 <tr>
     <th align="left"><?php echo T_('Privacy'); ?></th>
     <td>
@@ -117,4 +121,4 @@ document.write('<\/ul>');
 <?php
 }
 $this->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 (file)
index 0000000..23bcb0c
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+$tag2tagservice =& ServiceFactory::getServiceInstance('Tag2TagService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+function displayLinkedTags($tag, $linkType, $uId, $cat_url, $user, $editingMode =false, $precedentTag =null, $level=0, $stopList=array()) {
+    $tag2tagservice =& ServiceFactory::getServiceInstance('Tag2TagService');
+
+    $output = '';
+    $output.= '<tr>';
+    $output.= '<td></td>';
+    $output.= '<td>'. str_repeat('&nbsp;', $level*2) .'<a href="'. sprintf($cat_url, filter($user, 'url'), filter($tag, 'url')) .'" rel="tag">'. filter($tag) .'</a>';
+    if($editingMode) {
+       $output.= ' (';
+       $output.= '<a href="'.createURL('tag2tagadd', $tag).'">add</a>';
+       if($precedentTag != null) {
+           $output.= ' - ';
+           $output.= '<a href="'.createURL('tag2tagdelete', $precedentTag.'/'.$tag).'">del</a>';
+       }
+       $output.= ')';
+    }
+    $output.= '</td>';
+    $output.= '</tr>';
+
+    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) {
+?>
+
+<h2><?php echo T_('Linked Tags'); ?></h2>
+<div id="linked">
+    <table>
+    <?php
+       $editingMode = ($userid === $logged_on_userid);
+       foreach($explodedTags as $explodedTag) {
+               echo displayLinkedTags($explodedTag, '>', $userid, $cat_url, $user, $editingMode);
+       }
+    ?>
+    </table>
+</div>
+
+<?php
+    }
+}
+?>
diff --git a/templates/tag2tagadd.tpl.php b/templates/tag2tagadd.tpl.php
new file mode 100644 (file)
index 0000000..5b5ea58
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<form action="<?= $formaction ?>" method="post">
+<input type="hidden" name="tag" value="<?php echo $tag ?>" />
+<p><?php echo T_('Create new link :')?></p>
+<p><?php echo $tag ?> > <input type="text" name="newTag" /></p>
+<!--p><?php echo T_('Are you sure?'); ?></p-->
+<p>
+    <input type="submit" name="confirm" value="<?php echo T_('Create'); ?>" />
+    <input type="submit" name="cancel" value="<?php echo T_('Cancel'); ?>" />
+</p>
+
+<?php if (isset($referrer)): ?>
+<div><input type="hidden" name="referrer" value="<?php echo $referrer; ?>" /></div>
+<?php endif; ?>
+
+</form>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']); 
+?>
diff --git a/templates/tag2tagdelete.tpl.php b/templates/tag2tagdelete.tpl.php
new file mode 100644 (file)
index 0000000..9a276d1
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<form action="<?= $formaction ?>" method="post">
+<input type="hidden" name="tag1" value="<?php echo $tag1 ?>" />
+<input type="hidden" name="tag2" value="<?php echo $tag2 ?>" />
+<p><?php echo T_('Are you sure?'); ?></p>
+<p>
+    <input type="submit" name="confirm" value="<?php echo T_('Yes'); ?>" />
+    <input type="submit" name="cancel" value="<?php echo T_('No'); ?>" />
+</p>
+
+<?php if (isset($referrer)): ?>
+<div><input type="hidden" name="referrer" value="<?php echo $referrer; ?>" /></div>
+<?php endif; ?>
+
+</form>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']); 
+?>
diff --git a/tests/tag2TagTest.php b/tests/tag2TagTest.php
new file mode 100644 (file)
index 0000000..6660761
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+require_once 'PHPUnit/Framework.php';
+
+/*
+To launch this test, type the following line into a shell
+at the root of the scuttlePlus directory :
+     phpunit Tag2TagTest tests/tag2TagTest.php
+*/
+
+class Tag2TagTest extends PHPUnit_Framework_TestCase
+{
+    protected $us;
+    protected $bs;
+    protected $ts;
+    protected $tts;
+    protected function setUp()
+    {
+        global $dbhost, $dbuser, $dbpass, $dbname, $dbport, $dbpersist, $dbtype, $tableprefix;
+       require_once('./header.inc.php');
+
+       $this->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']);
+
+    }
+
+}
+?>