add('name', PLUGIN_EVENT_FREETAG_TITLE); $propbag->add('description', PLUGIN_EVENT_FREETAG_DESC); $propbag->add('stackable', false); $propbag->add('author', 'Garvin Hicking, Jonathan Arkell, Grischa Brockhaus, Lars Strojny, Malte Paskuda'); $propbag->add('requirements', array( 'serendipity' => '0.8', 'smarty' => '2.6.7', 'php' => '4.1.0' )); $propbag->add('version', '3.45'); $propbag->add('event_hooks', array( 'frontend_fetchentries' => true, 'frontend_fetchentry' => true, 'frontend_display:rss-2.0:per_entry' => true, 'frontend_header' => true, // 'frontend_display:rss-0.92:per_entry' => true, 'frontend_display:rss-1.0:per_entry' => true, // 'frontend_display:rss-0.91:per_entry' => true, 'frontend_display:atom-0.3:per_entry' => true, 'frontend_display:atom-1.0:per_entry' => true, 'frontend_entryproperties' => true, 'frontend_rss' => true, 'entry_display' => true, 'entries_header' => true, 'backend_publish' => true, 'backend_save' => true, 'backend_display' => true, 'backend_sidebar_entries' => true, 'backend_sidebar_entries_event_display_managetags' => true, 'backend_delete_entry' => true, 'external_plugin' => true, 'xmlrpc_updertEntry' => true, 'xmlrpc_fetchEntry' => true, 'xmlrpc_deleteEntry' => true, 'css' => true, )); $propbag->add('groups', array('BACKEND_EDITOR')); $this->supported_properties = array('freetag_name', 'freetag_tagList'); $this->dependencies = array('serendipity_plugin_freetag' => 'keep'); $propbag->add('configuration', array('cat2tag', 'keyword2tag', 'taglink', 'embed_footer', 'extended_smarty', 'show_tagcloud', 'min_percent', 'max_percent', 'max_tags', 'use_flash', 'flash_tag_color', 'flash_bg_trans', 'flash_bg_color', 'flash_width', 'flash_speed', 'meta_keywords', 'show_related', 'show_related_count', 'lowercase_tags', 'collation', 'send_http_header', 'admin_show_taglist', 'admin_ftayt', 'technorati_tag_link', 'technorati_tag_image')); } function introspect_config_item($name, &$propbag) { global $serendipity; switch($name) { case 'show_tagcloud': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_SHOW_TAGCLOUD); $propbag->add('description', ''); $propbag->add('default', true); break; case 'cat2tag': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_CAT2TAG); $propbag->add('description', PLUGIN_EVENT_FREETAG_CAT2TAG_DESC); $propbag->add('default', false); break; case 'keyword2tag': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_KEYWORD2TAG); $propbag->add('description', PLUGIN_EVENT_FREETAG_KEYWORD2TAG_DESC); $propbag->add('default', false); break; case 'embed_footer': $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_FREETAG_EMBED_FOOTER); $propbag->add('description', PLUGIN_EVENT_FREETAG_EMBED_FOOTER_DESC . ' ' . PLUGIN_EVENT_FREETAG_EMBED_FOOTER_DESC2); $propbag->add('select_values', array( 'yes' => YES, 'no' => NO, 'smarty' => 'Smarty' )); $propbag->add('default', 'true'); break; case 'extended_smarty': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_EXTENDED_SMARTY); $propbag->add('description', PLUGIN_EVENT_FREETAG_EXTENDED_SMARTY_DESC); $propbag->add('default', false); break; case 'taglink': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_TAGLINK); $propbag->add('description', ''); $propbag->add('default', $serendipity['baseURL'] . ($serendipity['rewrite'] == 'none' ? $serendipity['indexFile'] . '?/' : '') . 'plugin/tag/'); break; case 'min_percent': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_TAGCLOUD_MIN); $propbag->add('description', ''); $propbag->add('default', '100'); break; case 'max_percent': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_TAGCLOUD_MAX); $propbag->add('description', ''); $propbag->add('default', '300'); break; case 'collation': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_COLLATION); $propbag->add('description', ''); $propbag->add('default', ''); break; case 'max_tags': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_FREETAG_MAX_TAGS); $propbag->add('description', ''); $propbag->add('default', '45'); break; case 'meta_keywords': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_FREETAG_META_KEYWORDS); $propbag->add('description', ''); $propbag->add('default', '0'); break; case 'show_related': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_SHOW_RELATED); $propbag->add('description', ''); $propbag->add('default', true); break; case 'show_related_count': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_SHOW_RELATED_COUNT); $propbag->add('description', ''); $propbag->add('default', '5'); break; case 'lowercase_tags': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_LOWERCASE_TAGS); $propbag->add('description', ''); $propbag->add('default', true); break; case 'send_http_header': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_SEND_HTTP_HEADER); $propbag->add('description', ''); $propbag->add('default', true); break; case 'admin_show_taglist': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_ADMIN_TAGLIST); $propbag->add('description', ''); $propbag->add('default', true); break; case 'admin_ftayt': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_ADMIN_FTAYT); $propbag->add('description', ''); $propbag->add('default', false); break; case 'technorati_tag_link': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_TECHNORATI_TAGLINK); $propbag->add('description', PLUGIN_EVENT_FREETAG_TECHNORATI_TAGLINK_DESC); $propbag->add('default', false); break; case 'technorati_tag_image': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_TECHNORATI_TAGLINK_IMG); $propbag->add('description', ''); $propbag->add('default', 'http://static.technorati.com/static/img/pub/icon-utag-16x13.png'); break; case 'use_flash': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_USE_FLASH); $propbag->add('description', ''); $propbag->add('default', false); break; case 'flash_bg_trans': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_FREETAG_FLASH_TRANSPARENT); $propbag->add('description', ''); $propbag->add('default', false); break; case 'flash_tag_color': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_FLASH_TAG_COLOR); $propbag->add('description', ''); $propbag->add('default', 'ff6600'); break; case 'flash_bg_color': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_FLASH_BG_COLOR); $propbag->add('description', ''); $propbag->add('default', 'ffffff'); break; case 'flash_width': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_FLASH_WIDTH); $propbag->add('description', ''); $propbag->add('default', '500'); break; case 'flash_speed': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_FREETAG_FLASH_SPEED); $propbag->add('description', ''); $propbag->add('default', '100'); break; } return true; } function generate_content(&$title) { $title = $this->title; } static function tableCreated($table = 'entrytags') { global $serendipity; $q = "select count(tag) from {$serendipity['dbPrefix']}" . $table; $row = serendipity_db_query($q, true, 'num'); if (!is_numeric($row[0])) { // if the response we got back was an SQL error.. :P return false; } else { return true; } } static function upgradeFromVersion1() { global $serendipity; $q = "select count(*) from {$serendipity['dbPrefix']}entryproperties where property = 'ep_freetag_name'"; $result = serendipity_db_query($q); if ((int)$result[0] > 0) { return true; } else { return false; } } static function convertEntryPropertiesTags() { global $serendipity; $q = "select entryid, value from {$serendipity['dbPrefix']}entryproperties where property = 'ep_freetag_name'"; $result = serendipity_db_query($q); if (!is_array($result)) { return false; } foreach($result as $entry) { $tags = serendipity_event_freetag::makeTagsFromTaglist($entry['value']); serendipity_event_freetag::addTagsToEntry($entry['entryid'], $tags); printf(PLUGIN_FREETAG_UPGRADE1_2, count($tags), $entry['entryid']); echo '
'; } $q = "delete from {$serendipity['dbPrefix']}entryproperties where property = 'ep_freetag_name'"; $result = serendipity_db_query($q); } function cleanup() { global $serendipity; serendipity_event_freetag::static_install(); } function install() { serendipity_event_freetag::static_install(); } static function static_install() { global $serendipity; if (!serendipity_event_freetag::tableCreated('entrytags')) { $q = "create table {$serendipity['dbPrefix']}entrytags (" . "entryid int(10) not null, " . "tag varchar(50) not null, " . "primary key (entryid, tag)" . ")"; $result = serendipity_db_schema_import($q); if ($result !== true) { return; } serendipity_db_schema_import("CREATE INDEX tagsentryindex ON {$serendipity['dbPrefix']}entrytags (entryid)"); serendipity_db_schema_import("CREATE INDEX tagsTagIndex ON {$serendipity['dbPrefix']}entrytags (tag)"); } if (!serendipity_event_freetag::tableCreated('tagkeywords')) { $q = "create table {$serendipity['dbPrefix']}tagkeywords (" . "keywords text, " . "tag varchar(50) not null, " . "primary key (tag)" . ")"; $result = serendipity_db_schema_import($q); } if (serendipity_event_freetag::upgradeFromVersion1()) { serendipity_event_freetag::convertEntryPropertiesTags(); } else { echo "NOT UPGRADING!"; } } static function makeURLTag($tag) { return str_replace('.', '%FF', urlencode($tag)); } function getTagHtmlFromCSV($tagString) { global $serendipity; static $taglink = null; if ($taglink == null) { $taglink = $this->get_config('taglink'); } $links = array(); if (empty($tagString)) { return array(); } $tags = explode(',', $tagString); foreach($tags as $tag) { $tag = trim($tag); if (empty($tag)) { continue; } $links[] = ''; } return implode(', ', $links); } function getTagHtml($tags, $extended_smarty = false) { global $serendipity; static $taglink = null; $links = array(); if ($taglink == null) { $taglink = $this->get_config('taglink'); } if (!is_array($tags)) { return ''; } $technorati = $this->get_config('technorati_tag_link'); $technorati_img = $this->get_config('technorati_tag_image'); $img_url = $this->get_config('path_img',$serendipity['serendipityHTTPPath'] . 'plugins/serendipity_event_freetag/img/'); foreach($tags as $tag) { $tag = trim($tag); if (empty($tag)) { continue; } $links[] = '' . ($technorati?'':''); } if ($extended_smarty) { return $links; } else { return implode(', ', $links); } } function getRelatedEntries($tags, $postID) { global $serendipity; if (!is_array($tags)) { return false; } foreach($tags AS $idx => $tag) { $tags[$idx] = serendipity_db_escape_string($tag); } $q = "SELECT DISTINCT e1.entryid, e2.title, e2.timestamp FROM {$serendipity['dbPrefix']}entrytags AS e1 LEFT JOIN {$serendipity['dbPrefix']}entries AS e2 ON e1.entryid = e2.id WHERE e1.tag IN ('" . implode("', '", $tags) . "') AND e1.entryid != " . (int)$postID . " AND e2.isdraft = 'false' " . (!serendipity_db_bool($serendipity['showFutureEntries']) ? " AND e2.timestamp <= " . time() : '') . " ORDER BY e2.timestamp DESC LIMIT " . $this->get_config('show_related_count', 10); $result = serendipity_db_query($q, false, 'assoc', false, 'entryid', 'title'); if (!is_array($result)) { return false; } return $result; } function getRelatedEntriesHtml(&$entries, $extended_smarty = false) { global $serendipity; if (!is_array($entries)) { return false; } $entrylink = $serendipity['baseURL'] . ($serendipity['rewrite'] == 'none' ? $serendipity['indexFile'] . '?/' : '/'); if ($extended_smarty) { $return = array(); $return['description'] = PLUGIN_EVENT_FREETAG_RELATED_ENTRIES; foreach($entries AS $entryid => $title) { $return['entries'][] = '' . htmlspecialchars($title) . ''; } } else { $return = ''; } return $return; } /* This method can be called statically. Tags should be an array with the key being the tag name, and val being the number of occurances. */ static function displayTags($tags, $xml, $nl, $scaling, $maxSize = 200, $minSize = 100, $useFlash = false, $flashbgtrans = true, $flashtagcolor = 'ff6600', $flashbgcolor = 'ffffff', $flashwidth = 190, $flashspeed = 100, $cfg_taglink, $cfg_template, $xml_image = 'img/xml.gif') { global $serendipity; if (!is_array($tags)) { return false; } static $taglink = null; if ($taglink == null) { $taglink = $cfg_taglink; } $template = $cfg_template; if (!$template) { serendipity_event_freetag::renderTags($tags, $xml, $nl, $scaling, $maxSize, $minSize, $useFlash, $flashbgtrans, $flashtagcolor, $flashbgcolor, $flashwidth, $flashspeed, $taglink, $xml_image); } else { arsort($tags); $tagsWithLinks = array(); foreach ($tags as $tag => $count) { $tagsWithLinks[$tag] = array( 'count' => $count, 'href' => $taglink . serendipity_event_freetag::makeUrlTag($tag), ); } $serendipity['smarty']->assign('tags', $tagsWithLinks); $template = serendipity_getTemplateFile($template, 'serendipityPath'); $serendipity['smarty']->display($template); } return true; } static function renderTags($tags, $xml, $nl, $scaling, $maxSize, $minSize, $useFlash, $flashbgtrans, $flashtagcolor, $flashbgcolor, $flashwidth, $flashspeed, $taglink, $xml_image = 'img/xml.gif') { global $serendipity; $rsslink = $serendipity['serendipityHTTPPath'] . 'rss.php?serendipity%5Btag%5D='; $xmlImg = serendipity_getTemplateFile($xml_image); $first = true; $biggest = max($tags); $smallest= min($tags); $scale = $biggest - $smallest; if ($scale < 0) { $scale = 1; } $key = uniqid(rand()); if ($useFlash) { echo '
'. "\n"; echo "\n". ''. "\n"; echo ''. "\n"; echo ''. "\n"; echo ' '; } if ($scaling) { if ($scale==0) { $fontSize = $maxSize; } elseif ($scale==1) { if ($quantity==$biggest) { $fontSize = $maxSize; } else { $fontSize = $minSize; } } else { $fontSize = round(($quantity - $smallest)*(($maxSize - $minSize)/($scale))) + $minSize; } $html .= ''; } else { $fontSize = 100; } $html .= ''; if ($scaling) { $html .= ''; } if ($xml) { $html .= ""; } if ($nl) { $html .= '
' . "\n"; } $first = false; $tagparam .= "%3Ca href='" . $taglink . serendipity_event_freetag::makeURLTag($name) . "' style='" . round($fontSize/5) . "'%3E" . str_replace(' ',' ',htmlspecialchars($name)) . "%3C/a%3E"; } if ($useFlash) { echo $tagparam; echo '%3C/tags%3E" />' . "\n"; echo '' . "\n"; echo "\n" . ''. "\n"; echo '' . "\n"; echo ''. "\n"; echo ''. "\n"; } echo $html; if ($useFlash) { echo ''. "\n"; echo ''. "\n"; echo ''. "\n"; echo '
'. "\n"; echo '
'. "\n"; } } function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; $hooks = &$bag->get('event_hooks'); if (isset($hooks[$event])) { switch($event) { case 'backend_delete_entry': $this->deleteTagsForEntry((int)$eventData); return true; case 'frontend_header': if (serendipity_db_bool($this->get_config('use_flash'))) { echo ''. "\n"; echo ''. "\n"; } $this->displayMetaKeywords($serendipity['GET']['id'], $this->displayTag ); return true; case 'frontend_display:rss-2.0:per_entry': case 'frontend_display:rss-0.91:per_entry': $eventData['display_dat'] .= $this->getFeedXmlForTags('category', $eventData['properties']['freetag_tags']); return true; case 'frontend_display:rss-1.0:per_entry': case 'frontend_display:rss-0.91:per_entry': case 'frontend_display:atom-0.3:per_entry': case 'frontend_display:atom-1.0:per_entry': $eventData['display_dat'] .= $this->getFeedXmlForTags('dc:subject', $eventData['properties']['freetag_tags']); return true; case 'external_plugin': $uri_parts = explode('?', str_replace(array('&', '%FF'), array('&', '.'), $eventData)); $param = explode('/', $uri_parts[0]); $plugincode = array_shift($param); if (($plugincode == "tag") || ($plugincode == "tags") || ($plugincode == "freetag")) { /* Attempt to locate hidden variables within the URI */ foreach ($serendipity['uriArguments'] as $k => $v) { if ($v[0] == 'P') { /* Page */ $page = substr($v, 1); if (is_numeric($page)) { $serendipity['GET']['page'] = $page; unset($serendipity['uriArguments'][$k]); if ($param[count($param)-1] == "P{$page}.html") { array_pop($param); // knock it off of the param array as well } } } } if (count($param) == 0 || empty($param[0])) { $serendipity['head_subtitle'] = PLUGIN_EVENT_FREETAG_ALLTAGS; $this->displayTag = true; $param = null; } else if (count($param) == 1) { $param = urldecode($param[0]); $serendipity['head_subtitle'] = sprintf(PLUGIN_EVENT_FREETAG_USING, htmlspecialchars($param)); $emit_404 = true; } else { $serendipity['head_subtitle'] = sprintf(PLUGIN_EVENT_FREETAG_USING, implode(' + ', array_map('htmlspecialchars', $param))); $param = array_map('urldecode', $param); $emit_404 = true; } $this->tags['show'] = $param; $serendipity['plugin_vars']['tag'] = $param; if (is_array($param)) { @define('PLUGIN_VARS_TAG', implode(',', $param)); } else { @define('PLUGIN_VARS_TAG', $param); } $serendipity['GET']['subpage'] = $eventData; unset($serendipity['GET']['category']); // No restriction should be enforced here. include_once(S9Y_INCLUDE_PATH . 'include/genpage.inc.php'); if ($emit_404 && $this->TaggedEntries !== null && $this->TaggedEntries < 1) { @header('HTTP/1.0 404 Not found'); @header('Status: 404 Not found'); if (serendipity_db_bool($this->get_config('send_http_header', true))) { @header('X-FreeTag: not found'); } } else { if (serendipity_db_bool($this->get_config('send_http_header', true))) { @header('X-FreeTag: ' . $this->TaggedEntries); } } $raw_data = ob_get_contents(); ob_end_clean(); $serendipity['smarty']->assign('raw_data', $raw_data); serendipity_gzCompression(); $serendipity['smarty']->display(serendipity_getTemplateFile($serendipity['smarty_file'], 'serendipityPath')); @define('NO_EXIT', true); } break; case 'backend_sidebar_entries': ?> eventData = $eventData; $this->displayManageTags($event, $bag, $eventData, $addData); return true; break; case 'backend_publish': case 'backend_save': if (function_exists('mb_internal_encoding')) { mb_internal_encoding(LANG_CHARSET); } if (!isset($eventData['id'])) { return true; } $to_lower = serendipity_db_bool($this->get_config('lowercase_tags')); $keylist = serendipity_db_query("SELECT tag, keywords FROM {$serendipity['dbPrefix']}tagkeywords", false, 'assoc'); $automatted = array(array()); if (is_array($keylist)) { foreach($keylist AS $key) { $keywords = explode(',', $key['keywords']); foreach($keywords AS $keyword) { $automatted[trim($keyword)][$key['tag']] = true; } } } $tags = $this->makeTagsFromTagList($serendipity['POST']['properties']['freetag_tagList']); if (serendipity_db_bool($this->get_config('keyword2tag'))) { $searchtext = strip_tags($eventData['body'] . $eventData['extended']); foreach($automatted AS $keyword => $ktags) { $keyword = trim($keyword); if (empty($keyword)) continue; if (!is_array($ktags) || count($ktags) < 1) continue; $regex = sprintf("/((\s+|[\(\[-]+)%s([-\/,\.\?!'\";\)\]]*+|[\/-]+))/i", $keyword); if (preg_match($regex, $searchtext) > 0) { foreach($ktags AS $tag => $is_assigned) { if (!is_array($tags) || (!in_array(strtolower($tag), $tags) && !in_array($tag, $tags))) { if ($to_lower) { if (function_exists("mb_strtolower")) { $tag = mb_strtolower($tag); } else { $tag = strtolower($tag); } } $tags[] = $tag; printf(PLUGIN_EVENT_FREETAG_KEYWORDS_ADD, htmlspecialchars($keyword), htmlspecialchars($tag)); } } } } } if (empty($tags)) { $tags = array(); } if (serendipity_db_bool($this->get_config('cat2tag'))) { if (is_array($cats = serendipity_fetchCategories())) { $cats = serendipity_walkRecursive($cats, 'categoryid', 'parentid', VIEWMODE_THREADED); foreach ($cats as $cat) { if ($to_lower) { if (function_exists("mb_strtolower")) { $cat['category_name'] = mb_strtolower($cat['category_name']); } else { $cat['category_name'] = strtolower($cat['category_name']); } } $names = explode(',', $cat['category_name']); foreach($names AS $name) { $name = trim($name); if (in_array($cat['categoryid'], $eventData['categories']) && !in_array($name, $tags)) { $tags[] = $name; } } } } } $serendipity['POST']['properties']['freetag_tagList'] = implode(',', $tags); $this->deleteTagsForEntry($eventData['id']); $this->addTagsToEntry($eventData['id'], $tags); if ($serendipity['POST']['properties']['freetag_kill']) { $this->deleteTagsForEntry($eventData['id']); } return true; break; case 'backend_display': if (function_exists('mb_internal_encoding')) { mb_internal_encoding(LANG_CHARSET); } if (!empty($serendipity['POST']['properties']['freetag_tagList'])) { $tagList = $serendipity['POST']['properties']['freetag_tagList']; } else if (isset($eventData['id'])) { $tagList = implode(',', $this->getTagsForEntry($eventData['id'])); } else { $tagList = ''; } if (serendipity_db_bool($this->get_config('lowercase_tags', true))) { if (function_exists("mb_strtolower")) { $tagList = mb_strtolower($tagList); } else { $tagList = strtolower($tagList); } } $freetags = $this->makeTagsFromTagList($tagList); if (!empty($freetags)) { $tagList = implode(',', $freetags); } $taglist = (array)$this->getAllTags(); if ($this->get_config('admin_ftayt')) { foreach ($taglist as $k => $v) { $wicktags[] = '\'' . addslashes($k) . '\''; } echo ' '; } if ($this->get_config('admin_show_taglist')) { ?>
$count) { if (function_exists('mb_strtoupper')) { $upc = mb_strtoupper(mb_substr($tag, 0, 1, LANG_CHARSET), LANG_CHARSET); } else { $upc = strtoupper(substr($tag, 0, 1)); } if ($upc != $lastletter) echo " |".$upc.': '; echo "$tag, "; $lastletter = $upc; } ?>


importEntryTagsIntoProperties($eventData, $addData); return true; break; case 'frontend_fetchentries': case 'frontend_fetchentry': if (!empty($this->tags['show'])) { if (is_array($this->tags['show'])) { $showtag = array_map('serendipity_db_escape_string', $this->tags['show']); } else { $showtag = serendipity_db_escape_string($this->tags['show']); } } else if (!empty($serendipity['GET']['tag'])) { $showtag = serendipity_db_escape_string(urldecode($serendipity['GET']['tag'])); } $arr_showtag = explode(';', $showtag); $multimode = 'and'; if (count($arr_showtag) > 1) { $showtag = $arr_showtag; $multimode = 'or'; } if (!empty($show_tag) && is_string($show_tag) && serendipity_db_bool($this->get_config('lowercase_tags', true))) { if (function_exists("mb_strtolower")) { if (function_exists('mb_internal_encoding')) { mb_internal_encoding(LANG_CHARSET); } $showtag = mb_strtolower($showtag); } else { $showtag = strtolower($showtag); } } $coll_target = $this->get_config('collation', ''); if (empty($coll_target) && stristr($serendipity['dbType'], 'mysql') ) { $cd = serendipity_db_query("SHOW FULL COLUMNS FROM {$serendipity['dbPrefix']}entrytags LIKE 'tag'"); if (!empty($cd[0]['Collation'])) { $coll_target = $cd[0]['Collation']; $this->set_config('collation', $coll_target); } } if (!empty($showtag)) { if (LANG_CHARSET == 'UTF-8' && stristr($serendipity['dbType'], 'mysql') && !stristr($coll_target, 'utf8')) { $collate = "COLLATE utf8_general_ci"; $collateP = '_utf8 '; } else { $collate = $collateP = ""; } $cond = $join = ''; if (is_string($showtag)) { $join = "INNER JOIN {$serendipity['dbPrefix']}entrytags AS entrytags ON (e.id = entrytags.entryid) "; $cond = "entrytags.tag = $collateP '$showtag' $collate"; } else if (is_array($showtag)) { $_taglist = array(); $cond = '(1=2 '; foreach($showtag AS $_showtag) { $_taglist[] = serendipity_db_escape_string($_showtag); $cond .= " OR entrytags.tag = $collateP '" . serendipity_db_escape_string($_showtag) . "' $collate "; } $cond .= ' ) '; $total = count($showtag); $join = "INNER JOIN {$serendipity['dbPrefix']}entrytags AS entrytags ". "ON e.id = entrytags.entryid "; if ($multimode == 'and') { $eventData['having'] = " HAVING count(entrytags.tag) = $total"; } } if (empty($eventData['and'])) { $eventData['and'] = " WHERE $cond "; } else { $eventData['and'] .= " AND $cond "; } if (empty($eventData['joins'])) { $eventData['joins'] = $join; } else { $eventData['joins'] .= $join; } $this->displayTag = $showtag; $serendipity['plugin_vars']['displayTag'] = $showtag; @define('PLUGIN_VARS_DISPLAYTAG', $showtag); } return true; break; case 'frontend_rss': if (!empty($this->displayTag)) { $eventData['title'] .= serendipity_utf8_encode(htmlspecialchars(' (' . sprintf(PLUGIN_EVENT_FREETAG_USING, $this->displayTag) . ')')); } return true; break; case 'entries_header': if (isset($eventData['plugin_vars']['tag']) && serendipity_db_bool($this->get_config('show_tagcloud'))) { $this->displayTagCloud($eventData['plugin_vars']['tag']); } return true; break; case 'css': if (strpos($eventData, '.serendipity_freeTag')) { // class exists in CSS, so a user has customized it and we don't need default return true; } $this->addToCSS($eventData); return true; break; case 'entry_display': // Don't display entries if we are getting a full tag list if (is_array($eventData)) { $this->TaggedEntries = count($eventData); if (serendipity_db_bool($this->get_config('send_http_header', true))) { @header('X-FreeTag-Count: Array'); } } else { if (serendipity_db_bool($this->get_config('send_http_header', true))) { @header('X-FreeTag-Count: Empty'); } $this->TaggedEntries = 0; } if ($this->displayTag === true) { $eventData['clean_page'] = true; return true; } // This falls into the default case, which returns false... Is this supposed to happen? // Is it a bug? // Is it a feature? $this->displayEntry($eventData, $addData); return true; case 'xmlrpc_updertEntry': if (isset($eventData['id']) && isset($eventData['mt_keywords'])) { //XMLRPC call $tags = $this->makeTagsFromTagList($eventData['mt_keywords']); if (!empty($tags)) { $this->deleteTagsForEntry($eventData['id']); $this->addTagsToEntry($eventData['id'], $tags); } } return true; break; case 'xmlrpc_fetchEntry': $eventData['mt_keywords']=implode(',', $this->getTagsForEntry($eventData['id'])); return true; break; case 'xmlrpc_deleteEntry': if (isset($eventData["id"])) { $this->deleteTagsForEntry($eventData["id"]); } return true; break; default: return false; break; } } else { return false; } } function displayEntry(&$eventData, $addData) { global $serendipity; //echo real smarty-elements: $show_related = serendipity_db_bool($this->get_config('show_related', true)); $elements = count($eventData); //If not using extended-smarty, we want related entries only when //showing only one entry if ($elements > 1) { $manyEntries = true; } else { $manyEntries = false; } for ($entry = 0; $entry < $elements; $entry++) { $tags = $this->getTagsForEntry($eventData[$entry]['id']); //when in preview, maybe there are no tags stored yet if ($addData['preview'] && empty($tags)) { $tags = explode(',', $serendipity['POST']['properties']['freetag_tagList']); } $eventData = $this->addTags($entry, $tags, $eventData); if ($show_related) { $relatedEntries = $this->getRelatedEntries($tags, $eventData[$entry]['id']); $eventData = $this->addRelatedEntries($entry, $manyEntries, $relatedEntries, $eventData); } } } # # Add related entries to eventData[$entry] # # $entry: number of entry in $eventData # for use in displayEntry function addRelatedEntries($entry, $manyEntries, $relatedEntries, $eventData) { if (is_array($relatedEntries)) { if ($this->get_config('extended_smarty', false)) { $eventData[$entry]['freetag']['extended'] = true; $eventData[$entry]['freetag']['related'] = $this->getRelatedEntriesHtml($relatedEntries, true); } else if (! $manyEntries){ $field = $this->getField($eventData, $entry); //work with getFieldReference to prevent caching-issues $entryText =& $this->getFieldReference($field, $eventData[$entry]); $entryText .= $this->getRelatedEntriesHtml($relatedEntries); } } return $eventData; } # # $entry: number of entry in $eventData # for use in displayEntry function addTags($entry, $tags, $eventData) { if (!is_array($eventData)) $eventData = array(); if ($this->get_config('extended_smarty', false)) { $eventData[$entry]['freetag']['extended'] = true; $eventData[$entry]['freetag']['tags']['description'] = str_replace('%s', '', PLUGIN_EVENT_FREETAG_LIST); $eventData[$entry]['freetag']['tags']['tags'] = $this->getTagHtml($tags, true); } else { if (!empty($tags)) { $field = $this->getField($eventData, $entry); $msg = '
' . PLUGIN_EVENT_FREETAG_LIST . '
'; //in preview, $eventData maybe don't contain the field - till now if (!isset($eventData[$entry][$field])) { $eventData[$entry][$field] = ""; } $entryText =& $this->getFieldReference($field, $eventData[$entry]); $entryText .= sprintf($msg, $this->getTagHtml($tags)); } } return $eventData; } function getField($eventData, $entry) { $embed_footer = $this->get_config('embed_footer'); if ($embed_footer === 'yes' || ($embed_footer !== 'no' && serendipity_db_bool($embed_footer))) { $field = 'add_footer'; } else if ($embed_footer === 'smarty') { $field = 'freetag'; } else { //The option is set to add to the entry, but where? if (strlen($eventData[$entry]['extended']) > 0) { $field = 'extended'; } else { $field = 'body'; } } return $field; } /** * Returns a list of all tags * This performs a memoization operation, so that if we happen to be * getting all tags more then one time per request, we only perform * the SQL query once */ // static static function makeTagsFromTaglist($tagList) { $freetags = explode(',', $tagList); foreach($freetags AS $tag) { $tag = trim($tag); if (!empty($tag)) { $tags[] = $tag; } } return $tags; } static function getAllTags() { global $serendipity; static $memo = false; if (is_array($memo)) { return $memo; } $q = "SELECT tag, count(tag) as total FROM {$serendipity['dbPrefix']}entrytags GROUP BY tag ORDER BY tag"; $rows = serendipity_db_query($q); if (!is_array($rows)) { echo $rows; return false; } $memo = array(); foreach((array)$rows as $r) { $memo[$r['tag']] = $r['total']; } serendipity_plugin_api::hook_event('sort', $memo); return $memo; } function displayTagCloud($tag) { global $serendipity; $tags = $this->getTagCloudTags($tag); $serendipity['smarty']->assign('freetag_tagTitle', htmlspecialchars(is_array($this->displayTag) ? implode(' + ',$this->displayTag) : $this->displayTag)); if (!empty($tags)) { $serendipity['smarty']->assign('freetag_hasTags', true); $min = $this->get_config('min_percent', 100); $max = $this->get_config('max_percent', 300); ob_start(); serendipity_event_freetag::displayTags($tags, false, false, true, $max, $min, serendipity_db_bool($this->get_config('use_flash')), serendipity_db_bool($this->get_config('flash_bg_trans', true)), $this->get_config('flash_tag_color', 'ff6600'), $this->get_config('flash_bg_color', 'ffffff'), $this->get_config('flash_width', 600), $this->get_config('flash_speed', 100), $this->get_config('taglink'), $this->get_config('template'), $this->get_config('xml_image','img/xml.gif')); $tagout = ob_get_contents(); ob_end_clean(); $serendipity['smarty']->assign('freetag_displayTags', $tagout); } else { $serendipity['smarty']->assign('freetag_hasTags', false); } $filename = 'plugin_freetag.tpl'; $tfile = serendipity_getTemplateFile($filename, 'serendipityPath'); if (!$tfile || $tfile == $filename) { $tfile = dirname(__FILE__) . '/' . $filename; } $inclusion = $serendipity['smarty']->security_settings[INCLUDE_ANY]; $serendipity['smarty']->security_settings[INCLUDE_ANY] = true; $content = $serendipity['smarty']->fetch('file:'. $tfile); $serendipity['smarty']->security_settings[INCLUDE_ANY] = $inclusion; echo $content; } # # descend: if true, get the related tags of the related tags of given tag # function getTagCloudTags($tag, $descend = true) { $rows = serendipity_db_query($this->getTagCloudQuery('', $tag)); if (is_array($rows)) { foreach((array)$rows as $r) { $tags[$r['tag']] = $r['total']; #get also tags which are related only by other tags if($descend) { $descended_tags = $this->getTagCloudTags($r['tag'], false); foreach($descended_tags AS $dtag => $value) { $descended_tags[$dtag] = $value / 2; } #$tags = array_merge($tags, $descended_tags); $tags = $tags + $descended_tags; } } } unset($tags["$tag"]); return $tags; } function getTagCloudQuery($sort = '', $tag) { global $serendipity; if ($tag === true) { $title = PLUGIN_EVENT_FREETAG_ALLTAGS; $q = "SELECT tag, count(tag) as total FROM {$serendipity['dbPrefix']}entrytags GROUP BY tag ORDER BY tag"; } else { $title = PLUGIN_EVENT_FREETAG_SUBTAG; if (is_string($tag)) { $cond = "main.tag = '$tag'"; $ncond = "neg.tag != '$tag'"; $join = "LEFT JOIN {$serendipity['dbPrefix']}entrytags AS neg ". "ON main.entryid = neg.entryid "; $totalModifier = ''; } else if (is_array($tag)) { $join = "LEFT JOIN {$serendipity['dbPrefix']}entrytags AS neg ". "ON main.entryid = neg.entryid "; $ccond = ''; $ncond = ''; $first = true; $total = count($tag); $totalModifier = " - $total"; for ($i = 0; $i < $total; $i++) { if (!$first) { $ncond .= " AND "; $cond .= " AND "; } else { $first = false; } $join .= "LEFT JOIN {$serendipity['dbPrefix']}entrytags AS sub{$i} ". "ON main.entryid = sub{$i}.entryid "; $cond .= "sub{$i}.tag = '{$tag[$i]}' "; $ncond .= "neg.tag != '{$tag[$i]}' "; } } else { return; } $q = "SELECT neg.tag AS tag, count(neg.tag) {$totalModifier} AS total FROM {$serendipity['dbPrefix']}entrytags AS main {$join} WHERE ($cond) AND ($ncond) GROUP BY neg.tag"; } if (serendipity_db_bool($this->get_config('use_flash'))) { $mt = $this->get_config('max_tags', 45); } else { $mt = $this->get_config('max_tags', 0); } if ($mt > 0 && $sort == '') { $q = $q . " LIMIT " . $mt; } return $q; } function displayMetaKeywords($id = null, $tag) { global $serendipity; $id = (int)$id; $max_keywords = (int)$this->get_config('meta_keywords', 0); if ($max_keywords < 1) { return; } if ($tag !== false && $tag !== true) { //show related tags $query = $this->getTagCloudQuery(' ORDER BY total DESC LIMIT ' . $max_keywords, $tag); } else if ($id == null) { // show all tags // select most used tags in descending order $query = "SELECT tag, count(tag) AS total FROM {$serendipity['dbPrefix']}entrytags GROUP BY tag ORDER BY total DESC LIMIT " . $max_keywords; } else { // show tags for entry // select tags from entry $id ordered by most usage descending $query = "SELECT one.tag, two.entryid, count(two.tag) AS total FROM {$serendipity['dbPrefix']}entrytags AS one JOIN {$serendipity['dbPrefix']}entrytags AS two ON two.entryid = " . $id . " AND one.tag = two.tag GROUP BY one.tag, two.entryid ORDER BY total DESC LIMIT " . $max_keywords; } $rows = serendipity_db_query($query); if (!is_array($rows)) { return; } echo "tags['show'])) { if (is_array($this->tags['show'])) { $not_first = false; foreach($this->tags['show'] AS $r) { $not_first ? print(', ') : $not_first = true; echo $r; } } else { echo $this->tags['show']; $not_first = true; } } foreach($rows AS $r) { if (empty($r['tag'])) { continue; } $not_first ? print(', ') : $not_first = true; echo htmlspecialchars($r['tag']); } echo "\" />"; } function getRelatedTags($tag) { global $serendipity; $q = "SELECT sub.tag AS tag, count(sub.tag) AS total FROM {$serendipity['dbPrefix']}entrytags AS main LEFT JOIN {$serendipity['dbPrefix']}entrytags AS sub ON main.entryid = sub.entryid WHERE main.tag = '$tag' AND sub.tag != '$tag' GROUP BY sub.tag ORDER BY sub.tag"; $rows = serendipity_db_query($q); if (!is_array($rows)) { if ($rows !== true && $rows !== 1 && $rows !== 'true') { echo $rows; } return array(); } foreach($rows as $r) { $tags[$r['tag']] = $r['total']; } return $tags; } function getLeafTags($leafWeight=1) { global $serendipity; $q = "SELECT tag, count(tag) as total FROM {$serendipity['dbPrefix']}entrytags GROUP BY tag HAVING count(tag) <= $leafWeight ORDER BY tag"; $rows = serendipity_db_query($q); if (!is_array($rows)) { echo $rows; } $tags = array(); foreach((array)$rows as $r) { $tags[$r['tag']] = $r['total']; } return $tags; } static function getTagsForEntries($entries) { global $serendipity; if (!is_array($entries) || count($entries) < 1 || implode(',', $entries) == '') { return false; } $q = "SELECT entryid, tag from {$serendipity['dbPrefix']}entrytags WHERE entryid IN (".implode(',', $entries).") order by entryid, tag"; $result = serendipity_db_query($q); if (!is_array($result)) { return false; } $return = array(); foreach($result as $row) { if (isset($row['entryid'])) { $return[$row['entryid']][] = $row['tag']; } } return $return; } function getTagsForEntry($entryId) { $array = $this->getTagsForEntries(array($entryId)); return (is_array($array) ? array_pop($array) : array()); } function deleteTagsForEntry($entryId) { global $serendipity; $q = "DELETE FROM {$serendipity['dbPrefix']}entrytags WHERE entryid = ".(int)$entryId; serendipity_db_query($q); } // Static static function addTagsToEntry($entryId, $tags) { global $serendipity; if (!is_array($tags)) { return false; } foreach($tags as $tag) { $q = "INSERT INTO {$serendipity['dbPrefix']}entrytags (entryid, tag) VALUES (".(int)$entryId.", '".serendipity_db_escape_string($tag)."')"; serendipity_db_query($q); } } // This may not be the right way to do this... function importEntryTagsIntoProperties(&$eventData, $addData) { // we do a dual loop here, which is probably the worst thing to do. // A better thing might be some kind of array merge action, but I am not // entirely sure how do do that with the arrays we are given. // // RefactorMe Later. // Loop one in getTagsForEntries $tagGroups = $this->getTagsForEntries(array_keys($addData)); // Loop 2 if (is_array($tagGroups)) { foreach($tagGroups as $entryId => $tagList) { $eventData[$addData[$entryId]]['properties']['freetag_tags'] = $tagList; $eventData[$addData[$entryId]]['properties']['freetag_tagList'] = implode(",", $tagList); } } } function getFeedXmlForTags($element, $tagList) { $out = ''; if (!is_array($tagList)) { return $out; } foreach($tagList as $tag) { $out .= serendipity_utf8_encode("<$element>".htmlspecialchars($tag)."\n"); } return $out; } function displayManageTags($event, &$bag, &$eventData, $addData) { global $serendipity; if ($this->get_config('dbversion', 1) != 2) { $this->install(); $this->set_config('dbversion', 2); } ?>
eventData['GET']['tagaction'])) { $this->displayTagAction($this->eventData); } switch(@$this->eventData['GET']['tagview']) { case "entryuntagged": $this->displayUntaggedEntries(); break; case "entryleaf": $this->displayLeafTaggedEntries(); break; case "all": $tags = (array)$this->getAllTags(); $this->displayEditTags($this->eventData, $tags); break; case "leaf": $tags = $this->getLeafTags(); $this->displayEditTags($this->eventData, $tags); break; case 'keywords': $tags = (array)$this->getAllTags(); $this->displayKeywordAssignment($tags); break; case 'tagupdate': $per_fetch = 25; $page = (isset($serendipity['GET']['page']) ? $serendipity['GET']['page'] : 1); $from = ($page-1)*$per_fetch; $to = ($page)*$per_fetch; printf(PLUGIN_EVENT_FREETAG_REBUILD_FETCHNO, $from, $to); $entries = serendipity_fetchEntries( null, true, $per_fetch, false, false, 'timestamp DESC', '', true ); $total = serendipity_getTotalEntries(); printf(PLUGIN_EVENT_FREETAG_REBUILD_TOTAL . '
', $total); if (is_array($entries)) { foreach($entries AS $entry) { unset($entry['orderkey']); unset($entry['loginname']); unset($entry['email']); printf('%d - "%s"
', $entry['id'], htmlspecialchars($entry['title'])); $serendipity['POST']['properties']['fake'] = 'fake'; $up = serendipity_updertEntry($entry); if (is_string($up)) { echo "
$up
\n"; } echo DONE . "
\n"; } } echo '
'; if ($to < $total) { ?> ' . DONE . ''; } break; case 'cat2tag': $e = serendipity_db_query("SELECT e.id, e.title, c.category_name, et.tag FROM {$serendipity['dbPrefix']}entries AS e LEFT OUTER JOIN {$serendipity['dbPrefix']}entrycat AS ec ON e.id = ec.entryid LEFT OUTER JOIN {$serendipity['dbPrefix']}category AS c ON ec.categoryid = c.categoryid LEFT OUTER JOIN {$serendipity['dbPrefix']}entrytags AS et ON e.id = et.entryid", false, 'assoc'); // Get all categories and tags of all entries $entries = array(); foreach($e AS $row) { $entries[$row['id']]['title'] = $row['title']; $entries[$row['id']]['categories'][$row['category_name']] = $row['category_name']; $entries[$row['id']]['tags'][$row['tag']] = $row['tag']; } // Cycle all entries foreach($entries AS $id => $props) { $newtags = array(); // Fetch all tags that should be added foreach($props['categories'] AS $tag) { if (empty($tag)) continue; $newtags[$tag] = $tag; } // Subtract all tags that already exist foreach($props['tags'] AS $tag) { unset($newtags[$tag]); } if (count($newtags) < 1) { continue; } $this->addTagsToEntry($id, $newtags); printf(PLUGIN_EVENT_FREETAG_GLOBALCAT2TAG_ENTRY . '
', $id, htmlspecialchars($props['title']), htmlspecialchars(implode(', ', $newtags)) ); } echo PLUGIN_EVENT_FREETAG_GLOBALCAT2TAG . '
'; break; case 'cleanupmappings': $this->cleanupTagAssignments(); break; default: if (!empty($this->eventData['GET']['tagview'])) { echo "Can't execute tagview"; } break; } return true; } function displayUntaggedEntries() { global $serendipity; $q = "SELECT e.id as id, e.title as title FROM ${serendipity['dbPrefix']}entries AS e LEFT OUTER JOIN ${serendipity['dbPrefix']}entrytags AS t ON e.id = t.entryid WHERE entryid IS NULL GROUP BY e.id, e.title"; $this->displayEditEntries($q); } function displayLeafTaggedEntries() { global $serendipity; $q = "SELECT e.id as id, e.title as title, count(t.tag) as total FROM ${serendipity['dbPrefix']}entries AS e LEFT JOIN ${serendipity['dbPrefix']}entrytags AS t ON e.id = t.entryid GROUP BY e.id, e.title HAVING total = 1"; $this->displayEditEntries($q); } function displayEditEntries($q) { global $serendipity; $r = serendipity_db_query($q); if ($r === true) { echo PLUGIN_EVENT_FREETAG_MANAGE_UNTAGGED_NONE; } else if (!is_array($r)) { echo $r; } else { foreach ($r as $row) { echo '

' . $row['title'] . '

'; } } } function displayKeywordAssignment($taglist) { global $serendipity; if ($serendipity['POST']['keywordsubmit']) { serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}tagkeywords WHERE tag = '" . serendipity_db_escape_string(urldecode($serendipity['POST']['tag'])) . "'"); serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}tagkeywords (tag, keywords) VALUES ('" . serendipity_db_escape_string(urldecode($serendipity['POST']['tag'])) . "', '" . serendipity_db_escape_string($serendipity['POST']['keywords']) . "')"); } $keys = array(); $keylist = serendipity_db_query("SELECT tag, keywords FROM {$serendipity['dbPrefix']}tagkeywords ORDER BY tag"); if (is_array($keylist)) { foreach($keylist AS $key) { $keys[$key['tag']] = $key['keywords']; } } $url = FREETAG_MANAGE_URL . "&serendipity[tagview]=".htmlspecialchars($this->eventData['GET']['tagview']); echo '
' . PLUGIN_EVENT_FREETAG_KEYWORDS_DESC . '

'; ?>
$weight) { ?>
eventData['GET']['tagview']); ?> $weight) { ?>
eventData['GET']['tag']); $action = urldecode($this->eventData['GET']['tagaction']); if (!in_array($this->eventData['GET']['tagaction'], $validActions)) exit ("DON'T HACK!"); if ($this->eventData['GET']['commit'] == 'true') { $method = 'get'.$this->eventData['GET']['tagaction'].'TagQuery'; $q = $this->$method($tag, $this->eventData); echo $this->eventData['GET']['tagaction'] . " Completed"; } else { $method = 'display'.$this->eventData['GET']['tagaction']."Tag"; $this->$method($tag, $this->eventData); } } function getManageUrlAsHidden(&$eventData) { return ' '; } function displayRenameTag($tag, &$eventData) { ?>
getManageUrlAsHidden($this->eventData) ?> =>
eventData['GET']['tagview']); $yes = FREETAG_MANAGE_URL . "&serendipity[tagview]=".htmlspecialchars($this->eventData['GET']['tagview']). "&serendipity[tagaction]=delete". "&serendipity[tag]=".urlencode($tag)."&serendipity[commit]=true"; ?>

   

getManageUrlAsHidden($this->eventData) ?>


foobarbaz => foo,bar,baz

=>
makeTagsFromTaglist(urldecode($this->eventData['GET']['newtags'])); $tag = serendipity_db_escape_string($tag); $q = "SELECT entryid from ${serendipity['dbPrefix']}entrytags where tag = '$tag'"; $entries = serendipity_db_query($q); if (!is_array($entries)) { echo $entries; return false; } $q = "DELETE FROM ${serendipity['dbPrefix']}entrytags where tag = '$tag'"; $r = serendipity_db_query($q); if ($r !== true) { echo $r; return false; } foreach ($entries as $entryid) { foreach ($newtags as $tag) { $q = "INSERT INTO ${serendipity['dbPrefix']}entrytags (entryid, tag) VALUES ('${entryid['entryid']}', '$tag')"; $r = serendipity_db_query($q); } } } function cleanupTagAssignments() { global $serendipity; echo "
"; // Search for inconsistencies $q_search = "SELECT et.tag AS tag, et.entryid AS entryid, e.id ". "FROM {$serendipity['dbPrefix']}entrytags AS et LEFT JOIN {$serendipity['dbPrefix']}entries AS e ". "ON et.entryid = e.id ". "WHERE e.id IS NULL ". "ORDER BY et.tag ASC"; $mappings = serendipity_db_query($q_search, FALSE, 'assoc', TRUE); if (is_array($mappings) && count($mappings) > 0) { // Inconsistencies found if ($this->eventData['GET']['perform'] == 'true') { // Perform cleanup $entryIDs = array(); foreach ($mappings as $mapping) { if (!in_array($mapping['entryid'], array_values($entryIDs))) { $entryIDs[] = $mapping['entryid']; } } $q_cleanup = "DELETE FROM {$serendipity['dbPrefix']}entrytags " . "WHERE entryid IN (".implode(", ", $entryIDs).")"; $cleanup = serendipity_db_query($q_cleanup); if ($cleanup === TRUE) { echo "".PLUGIN_EVENT_FREETAG_MANAGE_CLEANUP_SUCCESSFUL.""; } else { echo "".PLUGIN_EVENT_FREETAG_MANAGE_CLEANUP_FAILED."

DB-Error:".$cleanup; } } else { // Show inconsistencies foreach ($mappings as $mapping) { $cleanup_tags[$mapping['tag']][] = $mapping['entryid']; } echo PLUGIN_EVENT_FREETAG_MANAGE_CLEANUP_INFO."

"; // Display list of found inconsistencies echo ""; echo ""; foreach ($cleanup_tags as $tag => $entries) { echo ""; } echo "
".PLUGIN_EVENT_FREETAG_MANAGE_LIST_TAG."".PLUGIN_EVENT_FREETAG_MANAGE_CLEANUP_ENTRIES."
$tag".implode(', ', $entries)."
"; // Display submit form to start cleanup process echo '
'; echo $this->getManageUrlAsHidden($this->eventData); echo ''; echo ''; echo ''; echo '
'; } } elseif ($mappings === TRUE) { // No inconsistencies found echo "".PLUGIN_EVENT_FREETAG_MANAGE_CLEANUP_NOTHING.""; } else { // An error occures while searching for inconsistencies echo "".PLUGIN_EVENT_FREETAG_MANAGE_CLEANUP_LOOKUP_ERROR."

DB-Error:".$mappings; } } function addToCSS(&$eventData) { $eventData .= ' .serendipity_freeTag { margin-left: auto; margin-right: 0px; text-align: right; font-size: 7pt; display: block; margin-top: 5px; margin-bottom: 0px; } .serendipity_freeTag_related { margin-left: 50px; margin-right: 0px; text-align: left; font-size: small; display: block; margin-top: 20px; margin-bottom: 0px; } ' . (serendipity_db_bool($this->get_config('use_flash')) ? ' .serendipity_freetag_taglist { margin: 10px; border: 1px solid #' . $this->get_config('flash_tag_color', 'ffffff') . '; padding: 5px; background-color: #' . $this->get_config('flash_bg_color', 'ffffff') . '; text-align: justify; } ' : '') . ' .serendipity_freeTag a { font-size: 7pt; text-decoration: none; } .serendipity_freeTag a:hover { color: green; text-decoration: underline; } .serendipity_freeTag_xmlTagEntry { white-space: pre; } img.serendipity_freeTag_xmlButton { vertical-align: bottom; display: inline; border: 0px; } '; } function debugMsg($msg) { global $serendipity; $this->debug_fp = @fopen ( $serendipity ['serendipityPath'] . 'templates_c/freetag.log', 'a' ); if (! $this->debug_fp) { return false; } if (empty ( $msg )) { fwrite ( $this->debug_fp, "failure \n" ); } else { fwrite ( $this->debug_fp, print_r ( $msg, true ) ); } fclose ( $this->debug_fp ); } } /* vim: set sts=4 ts=4 expandtab : */