diff --git a/build.xml b/build.xml
index a173a660..7ba32af3 100644
--- a/build.xml
+++ b/build.xml
@@ -106,7 +106,7 @@
minimum_version="0.4.0"
/>
-
diff --git a/data/config.default.php b/data/config.default.php
index 8af04ba9..2562cb4e 100644
--- a/data/config.default.php
+++ b/data/config.default.php
@@ -612,7 +612,12 @@
'menu2', 'tags', 'configurable', 'in', 'data/config.php'
);
-
+/**
+ * Automatic tag extraction
+ *
+ * @var boolean
+ */
+$tagExtraction = true;
/****************************
* Search
@@ -655,7 +660,7 @@
* a simple value "xxx" (like "author") automatically associates xxx with
* [xxx][/xxx].
* A complex value "xxx"=>"yyy" (like "address") directly
- * associates xxx with yyy.
+ * associates xxx with yyy.
*
* @var array
*/
diff --git a/data/templates/default/dynamictags.inc.php b/data/templates/default/dynamictags.inc.php
index c2ab6d4e..eb2f7e4a 100644
--- a/data/templates/default/dynamictags.inc.php
+++ b/data/templates/default/dynamictags.inc.php
@@ -34,6 +34,8 @@
$allPopularTagsCloud = $b2tservice->tagCloud($allPopularTags, 5, 90, 175);
$allPopularTagsCount = count($allPopularTags);
+$suggestedTagsCloud = $b2tservice->tagCloud($row['extractedTags'], 5, 90, 175);
+$suggestedTagsCount = count($row['extractedTags']);
// function printing the cloud
function writeTagsProposition($tagsCloud, $title)
@@ -49,7 +51,7 @@ function writeTagsProposition($tagsCloud, $title)
+ '
style="display:none">
|
|
←
diff --git a/src/SemanticScuttle/Service/AuthUser.php b/src/SemanticScuttle/Service/AuthUser.php
index 9447ee4b..1c43776a 100644
--- a/src/SemanticScuttle/Service/AuthUser.php
+++ b/src/SemanticScuttle/Service/AuthUser.php
@@ -53,7 +53,7 @@ class SemanticScuttle_Service_AuthUser extends SemanticScuttle_Service_User
* @link http://pear.php.net/manual/en/package.authentication.auth.intro-storage.php
*/
var $authtype = null;
-
+
/**
* Authentication options
*
@@ -86,7 +86,7 @@ public static function getInstance($db)
/**
* Create new instance
*
- * @var sql_db $db Database object
+ * @param sql_db $db Database object
*/
protected function __construct($db)
{
@@ -100,11 +100,11 @@ protected function __construct($db)
if (!$this->authtype) {
return;
}
- require_once 'Auth.php';
+ include_once 'Auth.php';
$this->auth = new Auth($this->authtype, $this->authoptions);
//FIXME: check if it worked (i.e. db connection)
if ($this->authdebug) {
- require_once 'Log.php';
+ include_once 'Log.php';
$this->auth->logger = Log::singleton(
'display', '', '', array(), PEAR_LOG_DEBUG
);
@@ -208,7 +208,7 @@ public function loginAuth($username, $password)
}
return true;
- }
+ }
@@ -229,4 +229,4 @@ public function logout()
}
}
-?>
\ No newline at end of file
+?>
diff --git a/src/SemanticScuttle/Service/Bookmark2Tag.php b/src/SemanticScuttle/Service/Bookmark2Tag.php
index a01b5d70..a14bad30 100644
--- a/src/SemanticScuttle/Service/Bookmark2Tag.php
+++ b/src/SemanticScuttle/Service/Bookmark2Tag.php
@@ -135,7 +135,7 @@ public function attachTags(
$this->db->sql_transaction('begin');
if ($replace) {
- if (!$this->deleteTagsForBookmark($bookmarkid)){
+ if (!$this->deleteTagsForBookmark($bookmarkid)) {
$this->db->sql_transaction('rollback');
message_die(GENERAL_ERROR, 'Could not attach tags (deleting old ones failed)', '', __LINE__, __FILE__, $sql, $this->db);
return false;
@@ -379,6 +379,51 @@ function &getTags($userid = NULL) {
return $output;
}
+ /**
+ * Given an array of named tags, return an array containing them and the
+ * count of occurrences of them. Much the same as what getTags returns but
+ * a subset of it.
+ *
+ * @param array $tags
+ * @param null|id $userid
+ *
+ * @return array
+ */
+ function getChoiceTags($tags, $userid = NULL) {
+ $userservice =SemanticScuttle_Service_Factory::get('User');
+ $logged_on_user = $userservice->getCurrentUserId();
+
+ $ftags = array();
+ foreach($tags as $tag) {
+ $ftags[] = $this->db->sql_escape(trim($tag));
+ }
+
+ $imp = implode('\',\'', $ftags);
+ $imp = '\'' . $imp . '\'';
+
+ $query = 'SELECT T.tag, COUNT(B.bId) AS bCount FROM '. $GLOBALS['tableprefix'] .'bookmarks AS B INNER JOIN '. $userservice->getTableName() .' AS U ON B.uId = U.'. $userservice->getFieldName('primary') .' INNER JOIN '. $GLOBALS['tableprefix'] .'bookmarks2tags AS T ON B.bId = T.bId';
+
+ $conditions = array();
+ if (!is_null($userid)) {
+ $conditions['U.'. $userservice->getFieldName('primary')] = intval($userid);
+ if ($logged_on_user != $userid)
+ $conditions['B.bStatus'] = 0;
+ } else {
+ $conditions['B.bStatus'] = 0;
+ }
+
+ $query .= ' WHERE '. $this->db->sql_build_array('SELECT', $conditions) .' AND T.tag in ('. $imp .') GROUP BY T.tag ORDER BY bCount DESC, tag';
+
+ if (!($dbresult = $this->db->sql_query($query))) {
+ message_die(GENERAL_ERROR, 'Could not get tags', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ $output = $this->db->sql_fetchrowset($dbresult);
+ $this->db->sql_freeresult($dbresult);
+ return $output;
+ }
+
// Returns the tags related to the specified tags; i.e. attached to the same bookmarks
function &getRelatedTags($tags, $for_user = NULL, $logged_on_user = NULL, $limit = 10) {
@@ -417,7 +462,7 @@ function &getRelatedTags($tags, $for_user = NULL, $logged_on_user = NULL, $limit
$query_5 = ' AND LEFT(T0.tag, 7) <> "system:" GROUP BY T0.tag ORDER BY bCount DESC, T0.tag';
$query = $query_1 . $query_2 . $query_3 . $query_4 . $query_5;
- if (! ($dbresult = $this->db->sql_query_limit($query, $limit)) ){
+ 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;
}
diff --git a/src/SemanticScuttle/Service/TagExtractor.php b/src/SemanticScuttle/Service/TagExtractor.php
new file mode 100644
index 00000000..d5743c1f
--- /dev/null
+++ b/src/SemanticScuttle/Service/TagExtractor.php
@@ -0,0 +1,167 @@
+
+ * @author Christian Weiske
+ * @author Eric Dane
+ * @license GPL http://www.gnu.org/licenses/gpl.html
+ * @link http://sourceforge.net/projects/semanticscuttle
+ */
+
+/**
+ * Extract recommended tags for new URL not yet saved as a bookmark.
+ *
+ * @category Bookmarking
+ * @package SemanticScuttle
+ * @author Ken Guest
+ * @license GPL http://www.gnu.org/licenses/gpl.html
+ * @link http://sourceforge.net/projects/semanticscuttle
+ */
+
+class SemanticScuttle_Service_TagExtractor
+{
+
+ /**
+ * Client used for making HTTP requests
+ *
+ * @var HTTP_Request2
+ */
+ protected $httpClient;
+
+ /**
+ * Create simple HTTP_Request2 client/instance
+ *
+ * @return HTTP_Request2
+ */
+ private function _createClient()
+ {
+ include "HTTP/Request2.php";
+ $client = new HTTP_Request2();
+ return $client;
+ }
+
+ /**
+ * Get content from some URL
+ *
+ * @param string $url URL to retrieve content from.
+ *
+ * @return string
+ */
+ private function _getContent($url)
+ {
+ if (is_file($url)) {
+ return file_get_contents($url);
+ }
+ $content = null;
+ if ($this->httpClient === null) {
+ $client = $this->_createClient();
+ $this->httpClient = $client;
+ } else {
+ $client = $this->httpClient;
+ }
+ $client->setUrl($url);
+ $res = $client->send();
+ $code = $res->getStatus();
+ if ($code == 200) {
+ $content = $res->getBody();
+ }
+ return $content;
+ }
+
+ private function _getExtractor($metaTags)
+ {
+ $class = "TagExtractor_Basic";
+ if (!empty ($metaTags)) {
+ if (isset($metaTags['generator'])) {
+ if (stripos($metaTags['generator'], 'MediaWiki') !== false) {
+ $class = "TagExtractor_MediaWiki";
+ } elseif (stripos($metaTags['generator'], 'WordPress') !== false) {
+ $class = "TagExtractor_WordPress";
+ }
+ }
+ }
+ $class = "SemanticScuttle_Service_" . $class;
+ ini_set('display_errors', 1);
+ error_reporting(E_ALL);
+ $file = str_replace('_', '/', $class) . '.php';
+ include_once "SemanticScuttle/Service/TagExtractor/Basic.php";
+ include_once $file;
+ return new $class();
+ }
+
+ /**
+ * getInstance
+ *
+ * @param mixed $db ...
+ *
+ * @return SemanticScuttle_Service_TagExtractor
+ */
+ public static function getInstance($db)
+ {
+ static $instance;
+ if (!isset($instance)) {
+ $instance = new self($db);
+ }
+ return $instance;
+ }
+
+ /**
+ * Extract/return tags based on passed URL.
+ *
+ * @param string $url URL being saved/bookmarked.
+ *
+ * @return array
+ */
+ public function extractFromUrl($url)
+ {
+ $tags = array();
+ $parsed = parse_url($url);
+ $mUrl = $url;
+ if ($parsed['scheme'] === 'file') {
+ $mUrl = $parsed['path'];
+ }
+ $metaTags = get_meta_tags($mUrl);
+
+ $extractor = null;
+ if ($metaTags !== false) {
+ $extractor = $this->_getExtractor($metaTags);
+ } else {
+ $extractor = $this->_getExtractor('');
+ }
+
+ try {
+ $content = $this->_getContent($mUrl);
+ } catch(Exception $ex) {
+ $content = null;
+ }
+
+ $extractor->setUrl($mUrl)->setContent($content)->setMetaTags($metaTags);
+ $extracted = $extractor->getTags();
+ $tags = array_merge($extracted, $tags);
+
+ // Also check
+ // category
+
+ return array_unique($tags);
+ }
+
+ /**
+ * set HttpClient
+ *
+ * @param HTTP_Request2 $client Custom HTTP_Request2 instance
+ *
+ * @return SemanticScuttle_Service_TagExtractor Provide Fluent interface
+ */
+ public function setHttpClient(HTTP_Request2 $client)
+ {
+ $this->httpClient = $client;
+ return $this;
+ }
+
+}
+?>
diff --git a/src/SemanticScuttle/Service/TagExtractor/Basic.php b/src/SemanticScuttle/Service/TagExtractor/Basic.php
new file mode 100644
index 00000000..5554fb36
--- /dev/null
+++ b/src/SemanticScuttle/Service/TagExtractor/Basic.php
@@ -0,0 +1,149 @@
+
+ * @author Christian Weiske
+ * @author Eric Dane
+ * @license GPL http://www.gnu.org/licenses/gpl.html
+ * @link http://sourceforge.net/projects/semanticscuttle
+ */
+
+/**
+ * SemanticScuttle_Service_TagExtractor_Basic
+ *
+ * @category Bookmarking
+ * @package SemanticScuttle
+ * @author Ken Guest
+ * @license GPL http://www.gnu.org/licenses/gpl.html
+ * @link http://sourceforge.net/projects/semanticscuttle
+ */
+class SemanticScuttle_Service_TagExtractor_Basic
+{
+ /**
+ * @var content string content retrieved
+ */
+ protected $content = null;
+ /**
+ * @var metaTags Associated meta tags.
+ */
+ protected $metaTags = null;
+ /**
+ * @var url string URL to work with
+ */
+ protected $url = null;
+
+ /**
+ * Set the content of this resource.
+ *
+ * @param string $content Content of this resource.
+ *
+ * @return SemanticScuttle_Service_TagExtractor_Basic
+ */
+ public function setContent($content)
+ {
+ $this->content = $content;
+ return $this;
+ }
+
+ /**
+ * setMetaTags
+ *
+ * @param mixed $metaTags Metatags for this resource
+ *
+ * @return SemanticScuttle_Service_TagExtractor_Basic
+ */
+ public function setMetaTags($metaTags)
+ {
+ $this->metaTags = $metaTags;
+ return $this;
+ }
+
+
+ /**
+ * Set the URL/Resource to work with.
+ *
+ * @param string $url URL
+ *
+ * @return SemanticScuttle_Service_TagExtractor_Basic
+ */
+ public function setUrl($url)
+ {
+ $this->url = $url;
+ return $this;
+ }
+
+ /**
+ * Determine tags associated with given resource
+ *
+ * @return array
+ */
+ public function getTags()
+ {
+
+ $url = $this->url;
+ $metaTags = $this->metaTags;
+ $content = $this->content;
+
+ $tags = array();
+
+ $parsed = parse_url($url);
+ /*
+ // stackexchange sites...
+ if (isset($parsed['host'])) {
+ if (stripos($parsed['host'], 'stackexchange.com') !== false) {
+ $tags[] = str_replace('.stackexchange.com', '', $parsed['host']);
+ }
+
+ $hostArray = explode('.', $parsed['host']);
+ $sub = strtolower($hostArray[0]);
+ if (($sub == 'help') || ($sub == 'hilfe')) {
+ $tags[] = $hostArray[1];
+ }
+ }
+
+ if (strpos($parsed['path'], "/questions/tagged/") === 0) {
+ $tags[] = str_replace('+', ', ', substr($parsed['path'], 18));
+ }
+ if (strpos($parsed['path'], "/unanswered/tagged/") === 0) {
+ $tags[] = str_replace('+', ', ', substr($parsed['path'], 19));
+ }
+
+ // common/favourite keywords.
+ if (stripos($url, "ubuntu") !== false) {
+ $tags[] = "ubuntu";
+ } elseif (stripos($url, "voip") !== false) {
+ $tags[] = "voip";
+ } elseif (stripos($url, "magento") !== false) {
+ $tags[] = "magento";
+ }
+ */
+
+ if ($metaTags !== false && !empty($metaTags)) {
+ if (isset($metaTags['keywords'])) {
+ $w = explode(",", $metaTags['keywords']);
+ $tags = array_merge($w, $tags);
+ }
+ }
+ if ($content !== null) {
+ include 'php-mf2/Mf2/Parser.php';
+ $mf2Parsed = Mf2\parse($content, $url);
+ $rels = $mf2Parsed['rels'];
+ if (is_array($rels) && isset($rels['tag'])) {
+ foreach ($rels['tag'] as $tag) {
+ $tag = trim($tag, '/');
+ $temp = explode('/', $tag);
+ $tags[] = urldecode(array_pop($temp));
+ }
+ }
+ }
+
+ return $tags;
+ }
+}
+
+?>
diff --git a/src/SemanticScuttle/Service/TagExtractor/MediaWiki.php b/src/SemanticScuttle/Service/TagExtractor/MediaWiki.php
new file mode 100644
index 00000000..bfa90fdd
--- /dev/null
+++ b/src/SemanticScuttle/Service/TagExtractor/MediaWiki.php
@@ -0,0 +1,63 @@
+
+ * @author Christian Weiske
+ * @author Eric Dane
+ * @license GPL http://www.gnu.org/licenses/gpl.html
+ * @link http://sourceforge.net/projects/semanticscuttle
+ */
+
+/**
+ * SemanticScuttle_Service_TagExtractor_MediaWiki
+ *
+ * @category Bookmarking
+ * @package SemanticScuttle
+ * @author Ken Guest
+ * @license GPL http://www.gnu.org/licenses/gpl.html
+ * @link http://sourceforge.net/projects/semanticscuttle
+ */
+class SemanticScuttle_Service_TagExtractor_MediaWiki
+extends SemanticScuttle_Service_TagExtractor_Basic
+{
+ const MAX_WORDS = 2;
+
+ /**
+ * getTags
+ *
+ * @return array
+ */
+ public function getTags()
+ {
+ $content = $this->content;
+ $tags = parent::getTags();
+ $start = 0;
+ $categories = array();
+ do {
+ if ($sPos = strpos($content, '"Category:', $start)) {
+ $ePos = strpos($content, '"', $sPos + 1);
+ $cat = substr($content, $sPos + 1, $ePos - $sPos - 1);
+ $temp = explode(':', $cat);
+ $category = strtolower($temp[1]);
+ $para = strpos($category, ' (');
+ if ($para !== false) {
+ $category = substr($category, 0, $para - 1);
+ }
+ $category = trim($category);
+ // Ignore category if there are too many words in its name.
+ if (substr_count($category, ' ') <= (self::MAX_WORDS - 1)) {
+ $categories[] = $category;
+ }
+ $start = $ePos;
+ }
+ } while ($sPos !== false);
+ return array_merge($tags, $categories);
+ }
+}
+
+?>
diff --git a/src/SemanticScuttle/Service/TagExtractor/WordPress.php b/src/SemanticScuttle/Service/TagExtractor/WordPress.php
new file mode 100644
index 00000000..2119439b
--- /dev/null
+++ b/src/SemanticScuttle/Service/TagExtractor/WordPress.php
@@ -0,0 +1,52 @@
+
+ * @author Christian Weiske
+ * @author Eric Dane
+ * @license GPL http://www.gnu.org/licenses/gpl.html
+ * @link http://sourceforge.net/projects/semanticscuttle
+ */
+
+/**
+ * SemanticScuttle_Service_TagExtractor_WordPress
+ *
+ * @category Bookmarking
+ * @package SemanticScuttle
+ * @author Ken Guest
+ * @license GPL http://www.gnu.org/licenses/gpl.html
+ * @link http://sourceforge.net/projects/semanticscuttle
+ */
+class SemanticScuttle_Service_TagExtractor_WordPress
+extends SemanticScuttle_Service_TagExtractor_Basic
+{
+ /**
+ * getTags
+ *
+ * @return array
+ */
+ public function getTags()
+ {
+ $content = $this->content;
+ $tags = parent::getTags();
+
+ $meta = $this->metaTags;
+ if (isset($meta['wp-parsely_version'])
+ && $meta['wp-parsely_version'] === "1.5"
+ && isset($meta['parsely-page'])
+ ) {
+ $parsely = json_decode($meta['parsely-page']);
+ if (isset($parsely->tags)) {
+ $tags = array_merge($tags, $parsely->tags);
+ }
+ }
+ return $tags;
+ }
+}
+
+?>
diff --git a/src/php-mf2 b/src/php-mf2
new file mode 160000
index 00000000..ab3ea1b3
--- /dev/null
+++ b/src/php-mf2
@@ -0,0 +1 @@
+Subproject commit ab3ea1b30c3bf1e1d9f50d2580cb79b7e80c37a4
diff --git a/www/bookmarks.php b/www/bookmarks.php
index bf06fb6a..91c071a7 100644
--- a/www/bookmarks.php
+++ b/www/bookmarks.php
@@ -21,33 +21,84 @@
require_once 'www-header.php';
-/* Service creation: only useful services are created */
-$bookmarkservice =SemanticScuttle_Service_Factory::get('Bookmark');
-$cacheservice =SemanticScuttle_Service_Factory::get('Cache');
-
-/* Managing all possible inputs */
-isset($_GET['action']) ? define('GET_ACTION', $_GET['action']): define('GET_ACTION', '');
-isset($_POST['submitted']) ? define('POST_SUBMITTED', $_POST['submitted']): define('POST_SUBMITTED', '');
+/**
+ * Define a constant to a key/value if present in associative array
+ * or to a default value.
+ *
+ * @param string $name Name of constant.
+ * @param array $array Typically $_GET or $_POST.
+ * @param string $key Associated key.
+ * @param mixed $default Default value, optional. Defaults to empty string.
+ * @param bool $case Whether to define constant as case-insensitive.
+ *
+ * @access public
+ *
+ * @return void
+ */
+function defineWithDefault($name, $array, $key, $default = '', $case = false)
+{
+ if (isset($array[$key])) {
+ return define($name, $array[$key], (bool) $case);
+ } else {
+ return define($name, $default, (bool) $case);
+ }
+}
-isset($_GET['title']) ? define('GET_TITLE', $_GET['title']): define('GET_TITLE', '');
-isset($_GET['address']) ? define('GET_ADDRESS', $_GET['address']): define('GET_ADDRESS', '');
-isset($_GET['description']) ? define('GET_DESCRIPTION', $_GET['description']): define('GET_DESCRIPTION', '');
-isset($_GET['privateNote']) ? define('GET_PRIVATENOTE', $_GET['privateNote']): define('GET_PRIVATENOTE', '');
-isset($_GET['tags']) ? define('GET_TAGS', $_GET['tags']): define('GET_TAGS', '');
-isset($_GET['copyOf']) ? define('GET_COPYOF', $_GET['copyOf']): define('GET_COPYOF', '');
+/**
+ * Filter tags based on whether they are already used by the current user.
+ *
+ * @param array $tags Array of tags
+ * @param boolean $includeAll Whether to exclude tags not present in db, or
+ * adjust resultset.
+ *
+ * @return array
+ */
+function filterTags($tags, $includeAll = false)
+{
+ $b2tservice = SemanticScuttle_Service_Factory::get('Bookmark2Tag');
+ $rTags = $b2tservice->getChoiceTags($tags);
+ /** proof of concept - later just return rTags for a tag cloud representation */
+ $ret = array();
+ $found = array();
+ foreach ($rTags as $rTag) {
+ $rTag['bCount']++;
+ $ret[] = $rTag;
+ $found[] = $rTag['tag'];
+ }
-isset($_POST['title']) ? define('POST_TITLE', $_POST['title']): define('POST_TITLE', '');
-isset($_POST['address']) ? define('POST_ADDRESS', $_POST['address']): define('POST_ADDRESS', '');
-isset($_POST['description']) ? define('POST_DESCRIPTION', $_POST['description']): define('POST_DESCRIPTION', '');
-isset($_POST['privateNote']) ? define('POST_PRIVATENOTE', $_POST['privateNote']): define('POST_PRIVATENOTE', '');
-isset($_POST['status']) ? define('POST_STATUS', $_POST['status']): define('POST_STATUS', '');
-isset($_POST['referrer']) ? define('POST_REFERRER', $_POST['referrer']): define('POST_REFERRER', '');
+ if ($includeAll) {
+ $not_found = array_diff($tags, $found);
+ foreach ($not_found as $element) {
+ $ret[] = array('bCount' => 0, 'tag' => $element);
+ }
+ }
+ return $ret;
+}
-isset($_GET['popup']) ? define('GET_POPUP', $_GET['popup']): define('GET_POPUP', '');
-isset($_POST['popup']) ? define('POST_POPUP', $_POST['popup']): define('POST_POPUP', '');
+/* Service creation: only useful services are created */
+$bookmarkservice = SemanticScuttle_Service_Factory::get('Bookmark');
+$cacheservice = SemanticScuttle_Service_Factory::get('Cache');
+$tagextractorservice = SemanticScuttle_Service_Factory::get('TagExtractor');
-isset($_GET['page']) ? define('GET_PAGE', $_GET['page']): define('GET_PAGE', 0);
-isset($_GET['sort']) ? define('GET_SORT', $_GET['sort']): define('GET_SORT', '');
+/* Managing all possible inputs */
+defineWithDefault('GET_ACTION', $_GET, 'action');
+defineWithDefault('GET_ADDRESS', $_GET, 'address');
+defineWithDefault('GET_COPYOF', $_GET, 'copyOf');
+defineWithDefault('GET_DESCRIPTION', $_GET, 'description');
+defineWithDefault('GET_PAGE', $_GET, 'page', 0);
+defineWithDefault('GET_POPUP', $_GET, 'popup');
+defineWithDefault('GET_PRIVATENOTE', $_GET, 'privateNote');
+defineWithDefault('GET_SORT', $_GET, 'sort');
+defineWithDefault('GET_TAGS', $_GET, 'tags');
+defineWithDefault('GET_TITLE', $_GET, 'title');
+defineWithDefault('POST_ADDRESS', $_POST, 'address');
+defineWithDefault('POST_DESCRIPTION', $_POST, 'description');
+defineWithDefault('POST_POPUP', $_POST, 'popup');
+defineWithDefault('POST_PRIVATENOTE', $_POST, 'privateNote');
+defineWithDefault('POST_REFERRER', $_POST, 'referrer');
+defineWithDefault('POST_STATUS', $_POST, 'status');
+defineWithDefault('POST_SUBMITTED', $_POST, 'submitted');
+defineWithDefault('POST_TITLE', $_POST, 'title');
if (!isset($_POST['tags'])) {
$_POST['tags'] = array();
@@ -56,70 +107,82 @@
if ((GET_ACTION == "add") && !$userservice->isLoggedOn()) {
- $loginqry = str_replace("'", '%27', stripslashes($_SERVER['QUERY_STRING']));
- header('Location: '. createURL('login', '?'. $loginqry));
- exit();
+ $loginqry = str_replace("'", '%27', stripslashes($_SERVER['QUERY_STRING']));
+ header('Location: '. createURL('login', '?'. $loginqry));
+ exit();
}
if ($userservice->isLoggedOn()) {
- $currentUser = $userservice->getCurrentObjectUser();
- $currentUserID = $currentUser->getId();
- $currentUsername = $currentUser->getUsername();
+ $currentUser = $userservice->getCurrentObjectUser();
+ $currentUserID = $currentUser->getId();
+ $currentUsername = $currentUser->getUsername();
}
-@list($url, $user, $cat) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
+@list($url, $user, $cat) = isset($_SERVER['PATH_INFO']) ?
+ explode('/', $_SERVER['PATH_INFO']) : null;
$endcache = false;
if ($usecache) {
- // Generate hash for caching on
- $hash = md5($_SERVER['REQUEST_URI'] . $user);
-
- // Don't cache if its users' own bookmarks
- if ($userservice->isLoggedOn()) {
- if ($currentUsername != $user) {
- // Cache for 5 minutes
- $cacheservice->Start($hash);
- $endcache = true;
- }
- } else {
- // Cache for 30 minutes
- $cacheservice->Start($hash, 1800);
- $endcache = true;
- }
+ // Generate hash for caching on
+ $hash = md5($_SERVER['REQUEST_URI'] . $user);
+
+ // Don't cache if its users' own bookmarks
+ if ($userservice->isLoggedOn()) {
+ if ($currentUsername != $user) {
+ // Cache for 5 minutes
+ $cacheservice->Start($hash);
+ $endcache = true;
+ }
+ } else {
+ // Cache for 30 minutes
+ $cacheservice->Start($hash, 1800);
+ $endcache = true;
+ }
}
$pagetitle = $rssCat = $catTitle = '';
if ($user) {
- if (is_int($user)) {
- $userid = intval($user);
- } else {
- if (!($userinfo = $userservice->getUserByUsername($user))) {
- $tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
- $templateservice->loadTemplate('error.404.tpl', $tplVars);
- exit();
- } else {
- $userid = $userinfo['uId'];
- }
- }
- $pagetitle .= ': '. $user;
+ if (is_int($user)) {
+ $userid = intval($user);
+ } else {
+ if (!($userinfo = $userservice->getUserByUsername($user))) {
+ $tplVars['error'] = sprintf(
+ T_('User with username %s was not found'),
+ $user
+ );
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+ } else {
+ $userid = $userinfo['uId'];
+ }
+ }
+ $pagetitle .= ': '. $user;
}
if ($cat) {
- $catTitle = ': '. str_replace('+', ' + ', $cat);
-
- $catTitleWithUrls = ': ';
- $titleTags = explode('+', filter($cat));
- for($i = 0; $i* + ';
- }
- $catTitleWithUrls = substr($catTitleWithUrls, 0, strlen($catTitleWithUrls) - strlen(' + '));
-
- $pagetitle .= $catTitleWithUrls;
-}
-else
-{
- $catTitleWithUrls = '';
+ $catTitle = ': '. str_replace('+', ' + ', $cat);
+
+ $catTitleWithUrls = ': ';
+ $titleTags = explode('+', filter($cat));
+ $title = T_('Remove the tag from the selection');
+ for ($i = 0; $i* + ";
+ }
+ $catTitleWithUrls = substr(
+ $catTitleWithUrls,
+ 0,
+ strlen($catTitleWithUrls) - strlen(' + ')
+ );
+
+ $pagetitle .= $catTitleWithUrls;
+} else {
+ $catTitleWithUrls = '';
}
$pagetitle = substr($pagetitle, 2);
@@ -130,148 +193,195 @@
$saved = false;
$templatename = 'bookmarks.tpl';
if ($userservice->isLoggedOn() && POST_SUBMITTED != '') {
- if (!POST_TITLE || !POST_ADDRESS) {
- $tplVars['error'] = T_('Your bookmark must have a title and an address');
- $templatename = 'editbookmark.tpl';
- } else {
- $address = trim(POST_ADDRESS);
+ if (!POST_TITLE || !POST_ADDRESS) {
+ $tplVars['error'] = T_('Your bookmark must have a title and an address');
+ $templatename = 'editbookmark.tpl';
+ } else {
+ $address = trim(POST_ADDRESS);
if (!SemanticScuttle_Model_Bookmark::isValidUrl($address)) {
$tplVars['error'] = T_('This bookmark URL may not be added');
$templatename = 'editbookmark.tpl';
} else if ($bookmarkservice->bookmarkExists($address, $currentUserID)) {
// If the bookmark exists already, edit the original
- $bookmark = $bookmarkservice->getBookmarkByAddress($address);
- header('Location: '. createURL('edit', $bookmark['bId']));
- exit();
- // If it's new, save it
- } else {
- $title = trim(POST_TITLE);
- $description = trim(POST_DESCRIPTION);
- $privateNote = trim(POST_PRIVATENOTE);
- $status = intval(POST_STATUS);
- $categories = explode(',', $_POST['tags']);
- $saved = true;
- if ($bookmarkservice->addBookmark($address, $title, $description, $privateNote, $status, $categories)) {
- if (POST_POPUP != '') {
- $tplVars['msg'] = '';
- } else {
- $tplVars['msg'] = T_('Bookmark saved') . ' '.T_('(Come back to previous page.)').'';
- // Redirection option
- if ($GLOBALS['useredir']) {
- $address = $GLOBALS['url_redir'] . $address;
- }
- }
- } else {
- $tplVars['error'] = T_('There was an error saving your bookmark. Please try again or contact the administrator.');
- $templatename = 'editbookmark.tpl';
- $saved = false;
- }
- }
- }
+ $bookmark = $bookmarkservice->getBookmarkByAddress($address);
+ header('Location: '. createURL('edit', $bookmark['bId']));
+ exit();
+ // If it's new, save it
+ } else {
+ $title = trim(POST_TITLE);
+ $description = trim(POST_DESCRIPTION);
+ $privateNote = trim(POST_PRIVATENOTE);
+ $status = intval(POST_STATUS);
+ $categories = explode(',', $_POST['tags']);
+ $saved = true;
+ if ($bookmarkservice->addBookmark(
+ $address,
+ $title,
+ $description,
+ $privateNote,
+ $status,
+ $categories
+ )) {
+ if (POST_POPUP != '') {
+ $tplVars['msg'] = '';
+ } else {
+ $tplVars['msg'] = T_('Bookmark saved')
+ . ' '
+ . T_('(Come back to previous page.)')
+ . '';
+ // Redirection option
+ if ($GLOBALS['useredir']) {
+ $address = $GLOBALS['url_redir'] . $address;
+ }
+ }
+ } else {
+ $tplVars['error'] = T_(
+ 'There was an error saving your bookmark. ' .
+ 'Please try again or contact the administrator.'
+ );
+ $templatename = 'editbookmark.tpl';
+ $saved = false;
+ }
+ }
+ }
}
if (GET_ACTION == "add") {
- // If the bookmark exists already, edit the original
- if ($bookmarkservice->bookmarkExists(stripslashes(GET_ADDRESS), $currentUserID)) {
- $bookmark = $bookmarkservice->getBookmarks(0, NULL, $currentUserID, NULL, NULL, NULL, NULL, NULL, NULL, $bookmarkservice->getHash(stripslashes(GET_ADDRESS)));
- $popup = (GET_POPUP!='') ? '?popup=1' : '';
- header('Location: '. createURL('edit', $bookmark['bookmarks'][0]['bId'] . $popup));
- exit();
- }
- $templatename = 'editbookmark.tpl';
+ // If the bookmark exists already, edit the original
+ if ($bookmarkservice->bookmarkExists(
+ stripslashes(GET_ADDRESS),
+ $currentUserID
+ )) {
+ $bookmark = $bookmarkservice->getBookmarks(
+ 0,
+ null,
+ $currentUserID,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ $bookmarkservice->getHash(stripslashes(GET_ADDRESS))
+ );
+ $popup = (GET_POPUP!='') ? '?popup=1' : '';
+ $url = createURL('edit', $bookmark['bookmarks'][0]['bId'] . $popup);
+ header('Location: '. $url);
+ exit();
+ }
+ $templatename = 'editbookmark.tpl';
}
if ($templatename == 'editbookmark.tpl') {
- if ($userservice->isLoggedOn()) {
- $tplVars['formaction'] = createURL('bookmarks', $currentUsername);
- if (POST_SUBMITTED != '') {
- $tplVars['row'] = array(
+ if ($userservice->isLoggedOn()) {
+ $tplVars['formaction'] = createURL('bookmarks', $currentUsername);
+ if (POST_SUBMITTED != '') {
+ $tplVars['row'] = array(
'bTitle' => stripslashes(POST_TITLE),
'bAddress' => stripslashes(POST_ADDRESS),
'bDescription' => stripslashes(POST_DESCRIPTION),
- 'bPrivateNote' => stripslashes(POST_PRIVATENOTE),
+ 'bPrivateNote' => stripslashes(POST_PRIVATENOTE),
'tags' => ($_POST['tags'] ? $_POST['tags'] : array()),
- 'bStatus' => $GLOBALS['defaults']['privacy'],
- );
- $tplVars['tags'] = $_POST['tags'];
- } else {
- if(GET_COPYOF != '') { //copy from bookmarks page
- $tplVars['row'] = $bookmarkservice->getBookmark(intval(GET_COPYOF), true);
- if(!$currentUser->isAdmin()) {
- $tplVars['row']['bPrivateNote'] = ''; //only admin can copy private note
- }
- }else { //copy from pop-up bookmarklet
- $tplVars['row'] = array(
- 'bTitle' => stripslashes(GET_TITLE),
- 'bAddress' => stripslashes(GET_ADDRESS),
- 'bDescription' => stripslashes(GET_DESCRIPTION),
- 'bPrivateNote' => stripslashes(GET_PRIVATENOTE),
- 'tags' => (GET_TAGS ? explode(',', stripslashes(GET_TAGS)) : array()),
- 'bStatus' => $GLOBALS['defaults']['privacy']
- );
- }
-
- }
- $title = T_('Add a Bookmark');
- $tplVars['referrer'] = '';;
- if (isset($_SERVER['HTTP_REFERER'])) {
- $tplVars['referrer'] = $_SERVER['HTTP_REFERER'];
- }
- $tplVars['pagetitle'] = $title;
- $tplVars['subtitle'] = $title;
- $tplVars['btnsubmit'] = T_('Add Bookmark');
- $tplVars['popup'] = (GET_POPUP!='') ? GET_POPUP : null;
- } else {
- $tplVars['error'] = T_('You must be logged in before you can add bookmarks.');
- }
+ 'bStatus' => $GLOBALS['defaults']['privacy'],
+ );
+ $tplVars['tags'] = $_POST['tags'];
+ } else {
+ if (GET_COPYOF != '') { //copy from bookmarks page
+ $tplVars['row'] = $bookmarkservice->getBookmark(
+ intval(GET_COPYOF), true
+ );
+ if (!$currentUser->isAdmin()) {
+ //only admin can copy private note
+ $tplVars['row']['bPrivateNote'] = '';
+ }
+ } else {
+ //copy from pop-up bookmarklet
+ $extractedTags = array();
+ if ($GLOBALS['tagExtraction']) {
+ $extractedTags = $tagextractorservice->extractFromUrl(
+ stripslashes(GET_ADDRESS)
+ );
+ $filteredTags = filterTags($extractedTags, $bIncludeAll = true);
+ $extractedTags = $filteredTags;
+ }
+ $tplVars['row'] = array(
+ 'bTitle' => stripslashes(GET_TITLE),
+ 'bAddress' => stripslashes(GET_ADDRESS),
+ 'bDescription' => stripslashes(GET_DESCRIPTION),
+ 'bPrivateNote' => stripslashes(GET_PRIVATENOTE),
+ 'tags' => (
+ GET_TAGS ?
+ explode(',', stripslashes(GET_TAGS)) : array()
+ ),
+ 'extractedTags' => $extractedTags,
+ 'bStatus' => $GLOBALS['defaults']['privacy']
+ );
+ }
+
+ }
+ $title = T_('Add a Bookmark');
+ $tplVars['referrer'] = '';;
+ if (isset($_SERVER['HTTP_REFERER'])) {
+ $tplVars['referrer'] = $_SERVER['HTTP_REFERER'];
+ }
+ $tplVars['pagetitle'] = $title;
+ $tplVars['subtitle'] = $title;
+ $tplVars['btnsubmit'] = T_('Add Bookmark');
+ $tplVars['popup'] = (GET_POPUP!='') ? GET_POPUP : null;
+ } else {
+ $tplVars['error'] = T_(
+ 'You must be logged in before you can add bookmarks.'
+ );
+ }
} else if ($user && GET_POPUP == '') {
- $tplVars['sidebar_blocks'] = array('watchstatus');
+ $tplVars['sidebar_blocks'] = array('watchstatus');
- if (!$cat) { //user page without tags
+ if (!$cat) { //user page without tags
$rssTitle = "My Bookmarks";
- $cat = NULL;
- $tplVars['currenttag'] = NULL;
- //$tplVars['sidebar_blocks'][] = 'menu2';
- $tplVars['sidebar_blocks'][] = 'linked';
- $tplVars['sidebar_blocks'][] = 'popular';
- } else { //pages with tags
+ $cat = null;
+ $tplVars['currenttag'] = null;
+ //$tplVars['sidebar_blocks'][] = 'menu2';
+ $tplVars['sidebar_blocks'][] = 'linked';
+ $tplVars['sidebar_blocks'][] = 'popular';
+ } else { //pages with tags
$rssTitle = "Tags" . $catTitle;
- $rssCat = '/'. filter($cat, 'url');
- $tplVars['currenttag'] = $cat;
- $tplVars['sidebar_blocks'][] = 'tagactions';
- //$tplVars['sidebar_blocks'][] = 'menu2';
- $tplVars['sidebar_blocks'][] = 'linked';
- $tplVars['sidebar_blocks'][] = 'related';
- /*$tplVars['sidebar_blocks'][] = 'menu';*/
- }
- $tplVars['sidebar_blocks'][] = 'menu2';
- $tplVars['popCount'] = 30;
- //$tplVars['sidebar_blocks'][] = 'popular';
-
- $tplVars['userid'] = $userid;
- $tplVars['userinfo'] = $userinfo;
- $tplVars['user'] = $user;
- $tplVars['range'] = 'user';
-
- // Pagination
- $perpage = getPerPageCount($currentUser);
- if (intval(GET_PAGE) > 1) {
- $page = intval(GET_PAGE);
- $start = ($page - 1) * $perpage;
- } else {
- $page = 0;
- $start = 0;
- }
-
- // Set template vars
- $tplVars['rsschannels'] = array(
+ $rssCat = '/'. filter($cat, 'url');
+ $tplVars['currenttag'] = $cat;
+ $tplVars['sidebar_blocks'][] = 'tagactions';
+ //$tplVars['sidebar_blocks'][] = 'menu2';
+ $tplVars['sidebar_blocks'][] = 'linked';
+ $tplVars['sidebar_blocks'][] = 'related';
+ /*$tplVars['sidebar_blocks'][] = 'menu';*/
+ }
+ $tplVars['sidebar_blocks'][] = 'menu2';
+ $tplVars['popCount'] = 30;
+ //$tplVars['sidebar_blocks'][] = 'popular';
+
+ $tplVars['userid'] = $userid;
+ $tplVars['userinfo'] = $userinfo;
+ $tplVars['user'] = $user;
+ $tplVars['range'] = 'user';
+
+ // Pagination
+ $perpage = getPerPageCount($currentUser);
+ if (intval(GET_PAGE) > 1) {
+ $page = intval(GET_PAGE);
+ $start = ($page - 1) * $perpage;
+ } else {
+ $page = 0;
+ $start = 0;
+ }
+
+ // Set template vars
+ $tplVars['rsschannels'] = array(
array(
sprintf(T_('%s: %s'), $sitename, $rssTitle),
createURL('rss', filter($user, 'url'))
. $rssCat . '?sort='.getSortOrder()
)
- );
+ );
if ($userservice->isLoggedOn()) {
$currentUsername = $currentUser->getUsername();
@@ -292,32 +402,38 @@
}
}
- $tplVars['page'] = $page;
- $tplVars['start'] = $start;
- $tplVars['bookmarkCount'] = $start + 1;
-
- $bookmarks = $bookmarkservice->getBookmarks($start, $perpage, $userid, $cat, null, getSortOrder());
- $tplVars['total'] = $bookmarks['total'];
- $tplVars['bookmarks'] = $bookmarks['bookmarks'];
- $tplVars['cat_url'] = createURL('bookmarks', '%s/%s');
- $tplVars['nav_url'] = createURL('bookmarks', '%s/%s%s');
- if ($userservice->isLoggedOn() && $user == $currentUsername) {
- $tplVars['pagetitle'] = T_('My Bookmarks') . $catTitle;
- $tplVars['subtitlehtml'] = T_('My Bookmarks') . $catTitleWithUrls;
- } else {
- $tplVars['pagetitle'] = $user.': '.$cat;
- $tplVars['subtitlehtml'] = $user . $catTitleWithUrls;
- }
+ $tplVars['page'] = $page;
+ $tplVars['start'] = $start;
+ $tplVars['bookmarkCount'] = $start + 1;
+
+ $bookmarks = $bookmarkservice->getBookmarks(
+ $start,
+ $perpage,
+ $userid,
+ $cat,
+ null,
+ getSortOrder()
+ );
+ $tplVars['total'] = $bookmarks['total'];
+ $tplVars['bookmarks'] = $bookmarks['bookmarks'];
+ $tplVars['cat_url'] = createURL('bookmarks', '%s/%s');
+ $tplVars['nav_url'] = createURL('bookmarks', '%s/%s%s');
+ if ($userservice->isLoggedOn() && $user == $currentUsername) {
+ $tplVars['pagetitle'] = T_('My Bookmarks') . $catTitle;
+ $tplVars['subtitlehtml'] = T_('My Bookmarks') . $catTitleWithUrls;
+ } else {
+ $tplVars['pagetitle'] = $user.': '.$cat;
+ $tplVars['subtitlehtml'] = $user . $catTitleWithUrls;
+ }
}
$tplVars['summarizeLinkedTags'] = true;
$tplVars['pageName'] = PAGE_BOOKMARKS;
-
$templateservice->loadTemplate($templatename, $tplVars);
if ($usecache && $endcache) {
- // Cache output if existing copy has expired
- $cacheservice->End($hash);
+ // Cache output if existing copy has expired
+ $cacheservice->End($hash);
}
?>
diff --git a/www/jsScuttle.php b/www/jsScuttle.php
index de97fd2b..41d47cac 100644
--- a/www/jsScuttle.php
+++ b/www/jsScuttle.php
@@ -20,9 +20,9 @@ function _playerAdd(anchor) {
};
var deleted = false;
-function deleteBookmark(ele, input){
+function deleteBookmark(ele, input) {
var confirmDelete = " - ";
- ele.style.display = 'none';
+ ele.style.display = 'none';
ele.parentNode.innerHTML = ele.parentNode.innerHTML + confirmDelete;
}
@@ -36,15 +36,15 @@ function deleteCancelled(ele) {
function deleteConfirmed(ele, input, response) {
//if (deleted == false) {
deleted = ele.parentNode.parentNode.parentNode.parentNode;
- //}
+ //}
var post = deleted;
- post.className = 'xfolkentry deleted';
+ post.className = 'xfolkentry deleted';
if (response != '') {
post.style.display = 'none';
deleted = false;
} else {
- loadXMLDocProc('ajaxDelete.php?id=' + input);
- post.style.display = 'none';
+ loadXMLDocProc('ajaxDelete.php?id=' + input);
+ post.style.display = 'none';
}
}
@@ -56,7 +56,7 @@ function previousElement(ele) {
return ele;
}
-function isAvailable(input, response){
+function isAvailable(input, response) {
var usernameField = document.getElementById("username");
var username = usernameField.value;
username = username.toLowerCase();
@@ -87,6 +87,7 @@ function useAddress(ele) {
}
getTitle(address, null);
ele.value = address;
+ suggestTags(address);
}
}
@@ -98,7 +99,7 @@ function useAddress(ele) {
*
* @return boolean Returns false to halt execution after call
*/
-function getNewPrivateKey(input, response){
+function getNewPrivateKey(input, response) {
var pk = document.getElementById('pPrivateKey');
if (response != null) {
pk.value = response.trim();
@@ -108,7 +109,25 @@ function getNewPrivateKey(input, response){
return false;
}
-function getTitle(input, response){
+function suggestTags(url) {
+ // only prepend the div if there is not an h3 tag w Suggested Tags as the content.
+ var h3s = $('h3');
+ var suggest = 1;
+ var tags = null;
+
+ for (var ih = 0; ih < h3s.length; ih++) {
+ if (h3s[ih].innerHTML == 'Suggested Tags') {
+ suggest = 0;
+ ih = h3s.length;
+ }
+ }
+ if (suggest == 0) {
+ return;
+ }
+ $('.edit-tagclouds').prepend('');
+}
+
+function getTitle(input, response) {
var title = document.getElementById('titleField');
if (title.value == '') {
title.style.backgroundImage = 'url(resource('images/loading.gif');?>)';
@@ -193,7 +212,7 @@ function playerLoad() {
}
function addAnchor(anchorForm, where) {
- var whereZone = document.getElementById(where);
- whereZone.value = whereZone.value + anchorForm;
+ var whereZone = document.getElementById(where);
+ whereZone.value = whereZone.value + anchorForm;
document.getElementById(where).focus();
}
|