# HG changeset patch # User Dan # Date 1185989967 14400 # Node ID cb7dde69c30145700e707b1627ea4b8079f064c3 # Parent 5faff33a658066691f80a105fac225dd1c523d27 Improved and enabled HTML optimization algorithm; enabled gzip compression; added but did not test at all the tag cloud class in includes/tagcloud.php, this is still very preliminary and not ready for any type of production use diff -r 5faff33a6580 -r cb7dde69c301 ajax.php --- a/ajax.php Mon Jul 30 10:46:17 2007 -0400 +++ b/ajax.php Wed Aug 01 13:39:27 2007 -0400 @@ -224,7 +224,7 @@ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); $ret = array('tags' => array(), 'user_level' => $session->user_level, 'can_add' => $session->get_permissions('tag_create')); - $q = $db->sql_query('SELECT t.tag_id, t.tag_name, pg.pg_target IS NULL AS used_in_acl, t.user FROM '.table_prefix.'tags AS t + $q = $db->sql_query('SELECT t.tag_id, t.tag_name, pg.pg_target IS NOT NULL AS used_in_acl, t.user FROM '.table_prefix.'tags AS t LEFT JOIN '.table_prefix.'page_groups AS pg ON ( ( pg.pg_type = ' . PAGE_GRP_TAGGED . ' AND pg.pg_target=t.tag_name ) OR ( pg.pg_type IS NULL AND pg.pg_target IS NULL ) ) WHERE t.page_id=\'' . $db->escape($paths->cpage['urlname_nons']) . '\' AND t.namespace=\'' . $db->escape($paths->namespace) . '\';'); @@ -233,21 +233,141 @@ while ( $row = $db->fetchrow() ) { - $can_del = ( - ( $session->get_permissions('tag_delete_own') && $row['user'] == $session->user_id && $session->user_logged_in ) || // User created the tag and can remove own tags - ( $session->get_permissions('tag_delete_other') && $row['used_in_acl'] != 1 ) || // User can remove tags and the tag isn't used in an ACL (page group) - ( $row['used_in_acl'] == 1 && $session->get_permissions('tag_delete_own') && $session->get_permissions('tag_delete_other') && ( $session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN ) ) - ); + $can_del = true; + + $perm = ( $row['user'] != $session->user_id ) ? + 'tag_delete_other' : + 'tag_delete_own'; + + if ( $row['user'] == 1 && !$session->user_logged_in ) + // anonymous user trying to delete tag (hardcode blacklisted) + $can_del = false; + + if ( !$session->get_permissions($perm) ) + $can_del = false; + + if ( $row['used_in_acl'] == 1 && !$session->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN ) + $can_del = false; + $ret['tags'][] = array( 'id' => $row['tag_id'], 'name' => $row['tag_name'], - 'can_del' => $can_del + 'can_del' => $can_del, + 'acl' => ( $row['used_in_acl'] == 1 ) ); } echo $json->encode($ret); break; + case 'addtag': + $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); + $resp = array( + 'success' => false, + 'error' => 'No error', + 'can_del' => ( $session->get_permissions('tag_delete_own') && $session->user_logged_in ), + 'in_acl' => false + ); + + // first of course, are we allowed to tag pages? + if ( !$session->get_permissions('tag_create') ) + { + $resp['error'] = 'You are not permitted to tag pages.'; + die($json->encode($resp)); + } + + // sanitize the tag name + $tag = sanitize_tag($_POST['tag']); + $tag = $db->escape($tag); + + if ( strlen($tag) < 2 ) + { + $resp['error'] = 'Tags must consist of at least 2 alphanumeric characters.'; + die($json->encode($resp)); + } + + // check if tag is already on page + $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'tags WHERE page_id=\'' . $db->escape($paths->cpage['urlname_nons']) . '\' AND namespace=\'' . $db->escape($paths->namespace) . '\' AND tag_name=\'' . $tag . '\';'); + if ( !$q ) + $db->_die(); + if ( $db->numrows() > 0 ) + { + $resp['error'] = 'This page already has this tag.'; + die($json->encode($resp)); + } + $db->free_result(); + + // tricky: make sure this tag isn't being used in some page group, and thus adding it could affect page access + $can_edit_acl = ( $session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN ); + $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'page_groups WHERE pg_type=' . PAGE_GRP_TAGGED . ' AND pg_target=\'' . $tag . '\';'); + if ( !$q ) + $db->_die(); + if ( $db->numrows() > 0 && !$can_edit_acl ) + { + $resp['error'] = 'This tag is used in an ACL page group, and thus can\'t be added to a page by people without administrator privileges.'; + die($json->encode($resp)); + } + $resp['in_acl'] = ( $db->numrows() > 0 ); + $db->free_result(); + + // we're good + $q = $db->sql_query('INSERT INTO '.table_prefix.'tags(tag_name,page_id,namespace,user) VALUES(\'' . $tag . '\', \'' . $db->escape($paths->cpage['urlname_nons']) . '\', \'' . $db->escape($paths->namespace) . '\', ' . $session->user_id . ');'); + if ( !$q ) + $db->_die(); + + $resp['success'] = true; + $resp['tag'] = $tag; + $resp['tag_id'] = $db->insert_id(); + + echo $json->encode($resp); + break; + case 'deltag': + + $tag_id = intval($_POST['tag_id']); + if ( empty($tag_id) ) + die('Invalid tag ID'); + + $q = $db->sql_query('SELECT t.tag_id, t.user, t.page_id, t.namespace, pg.pg_target IS NOT NULL AS used_in_acl FROM '.table_prefix.'tags AS t + LEFT JOIN '.table_prefix.'page_groups AS pg + ON ( pg.pg_id IS NULL OR ( pg.pg_target = t.tag_name AND pg.pg_type = ' . PAGE_GRP_TAGGED . ' ) ) + WHERE t.tag_id=' . $tag_id . ';'); + + if ( !$q ) + $db->_die(); + + if ( $db->numrows() < 1 ) + die('Could not find a tag with that ID'); + + $row = $db->fetchrow(); + $db->free_result(); + + if ( $row['page_id'] == $paths->cpage['urlname_nons'] && $row['namespace'] == $paths->namespace ) + $perms =& $session; + else + $perms = $session->fetch_page_acl($row['page_id'], $row['namespace']); + + $perm = ( $row['user'] != $session->user_id ) ? + 'tag_delete_other' : + 'tag_delete_own'; + + if ( $row['user'] == 1 && !$session->user_logged_in ) + // anonymous user trying to delete tag (hardcode blacklisted) + die('You are not authorized to delete this tag.'); + + if ( !$perms->get_permissions($perm) ) + die('You are not authorized to delete this tag.'); + + if ( $row['used_in_acl'] == 1 && !$perms->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN ) + die('You are not authorized to delete this tag.'); + + // We're good + $q = $db->sql_query('DELETE FROM '.table_prefix.'tags WHERE tag_id = ' . $tag_id . ';'); + if ( !$q ) + $db->_die(); + + echo 'success'; + + break; default: die('Hacking attempt'); break; diff -r 5faff33a6580 -r cb7dde69c301 includes/clientside/sbedit.js --- a/includes/clientside/sbedit.js Mon Jul 30 10:46:17 2007 -0400 +++ b/includes/clientside/sbedit.js Wed Aug 01 13:39:27 2007 -0400 @@ -60,10 +60,10 @@ var thediv = document.createElement('div'); //if(!oElm.id) oElm.id = 'autoEditButton_'+Math.floor(Math.random() * 100000); oElm = oElm.parentNode; - o = fetch_offset(oElm); - d = fetch_dimensions(oElm); - top = o['top'] + d['h'] + 'px'; - left = o['left'] + 'px'; + var magic = $(oElm).Top() + $(oElm).Height(); + var top = String(magic); + top = top + 'px'; + left = $(oElm).Left() + 'px'; thediv.style.top = top; thediv.style.left = left; thediv.style.position = 'absolute'; @@ -107,10 +107,13 @@ eval(ajax.responseText); if(status == 'GOOD') { - parent = document.getElementById('disabled_'+id).parentNode.parentNode; + var _id = 'disabled_' + String(id); + var parent = document.getElementById(_id).parentNode.parentNode; oElm.parentNode.parentNode.removeChild(oElm.parentNode); content = content.replace('%a', unescape('%0A')); - parent.firstChild.nextSibling.nextSibling.nextSibling.innerHTML = content; // $content is set in ajax.responseText + var obj = ( IE ) ? parent.firstChild.nextSibling.nextSibling : parent.firstChild.nextSibling.nextSibling.nextSibling; + if ( obj ) + obj.innerHTML = content; // $content is set in ajax.responseText } else { diff -r 5faff33a6580 -r cb7dde69c301 includes/clientside/static/ajax.js --- a/includes/clientside/static/ajax.js Mon Jul 30 10:46:17 2007 -0400 +++ b/includes/clientside/static/ajax.js Wed Aug 01 13:39:27 2007 -0400 @@ -893,7 +893,8 @@ var a = document.createElement('a'); a.appendChild(document.createTextNode('[X]')); a.href = '#'; - a.onclick = function() { return false; } + a._js_tag_id = json.tags[i].id; + a.onclick = function() { ajaxDeleteTag(this, this._js_tag_id); return false; } catbox.appendChild(a); } if ( ( i + 1 ) < json.tags.length ) @@ -912,17 +913,28 @@ }); } +var addtag_open = false; + function ajaxAddTagStage1() { + if ( addtag_open ) + return false; var catbox = document.getElementById('mdgCatBox'); var adddiv = document.createElement('div'); var text = document.createElement('input'); var addlink = document.createElement('a'); addlink.href = '#'; - addlink.onclick = function() { return false; }; + addlink.onclick = function() { ajaxAddTagStage2(this.parentNode.firstChild.nextSibling.value, this.parentNode); return false; }; addlink.appendChild(document.createTextNode('+ Add')); text.type = 'text'; text.size = '15'; + text.onkeyup = function(e) + { + if ( e.keyCode == 13 ) + { + ajaxAddTagStage2(this.value, this.parentNode); + } + } adddiv.style.margin = '5px 0 0 0'; adddiv.appendChild(document.createTextNode('Add a tag: ')); @@ -930,6 +942,119 @@ adddiv.appendChild(document.createTextNode(' ')); adddiv.appendChild(addlink); catbox.appendChild(adddiv); + addtag_open = true; +} + +var addtag_nukeme = false; + +function ajaxAddTagStage2(tag, nukeme) +{ + if ( !addtag_open ) + return false; + if ( addtag_nukeme ) + return false; + addtag_nukeme = nukeme; + tag = ajaxEscape(tag); + setAjaxLoading(); + ajaxPost(stdAjaxPrefix + '&_mode=addtag', 'tag=' + tag, function() + { + if ( ajax.readyState == 4 ) + { + unsetAjaxLoading(); + var nukeme = addtag_nukeme; + addtag_nukeme = false; + var resptext = String(ajax.responseText + ' '); + resptext = resptext.substr(0, resptext.length-1); + if ( resptext.substr(0, 1) != '{' ) + { + alert('Invalid JSON response from server:\n' + resptext); + return false; + } + var json = parseJSON(resptext); + var parent = nukeme.parentNode; + parent.removeChild(nukeme); + addtag_open = false; + if ( json.success ) + { + var node = parent.childNodes[1]; + var insertafter = false; + var nukeafter = false; + if ( node.nodeValue == 'No tags on this page' ) + { + nukeafter = true; + } + insertafter = parent.childNodes[ parent.childNodes.length - 3 ]; + // these need to be inserted in reverse order + if ( json.can_del ) + { + var a = document.createElement('a'); + a.appendChild(document.createTextNode('[X]')); + a.href = '#'; + a._js_tag_id = json.tag_id; + a.onclick = function() { ajaxDeleteTag(this, this._js_tag_id); return false; } + insertAfter(parent, a, insertafter); + insertAfter(parent, document.createTextNode(' '), insertafter); + } + insertAfter(parent, document.createTextNode(json.tag), insertafter); + if ( !nukeafter ) + { + insertAfter(parent, document.createTextNode(', '), insertafter); + } + if ( nukeafter ) + { + parent.removeChild(insertafter); + } + } + else + { + alert(json.error); + } + } + }); +} + +function ajaxDeleteTag(parentobj, tag_id) +{ + var arrDelete = [ parentobj, parentobj.previousSibling, parentobj.previousSibling.previousSibling ]; + var parent = parentobj.parentNode; + var writeNoTags = false; + if ( parentobj.previousSibling.previousSibling.previousSibling.nodeValue == ', ' ) + arrDelete.push(parentobj.previousSibling.previousSibling.previousSibling); + else if ( parentobj.previousSibling.previousSibling.previousSibling.nodeValue == 'Page tags: ' ) + arrDelete.push(parentobj.nextSibling); + + if ( parentobj.previousSibling.previousSibling.previousSibling.nodeValue == 'Page tags: ' && + parentobj.nextSibling.nextSibling.firstChild ) + if ( parentobj.nextSibling.nextSibling.firstChild.nodeValue == '(add a tag)') + writeNoTags = true; + + ajaxPost(stdAjaxPrefix + '&_mode=deltag', 'tag_id=' + String(tag_id), function() + { + if ( ajax.readyState == 4 ) + { + if ( ajax.responseText == 'success' ) + { + for ( var i = 0; i < arrDelete.length; i++ ) + { + try + { + parent.removeChild(arrDelete[i]); + } catch(e) {} + } + if ( writeNoTags ) + { + var node1 = document.createTextNode('No tags on this page'); + var node2 = document.createTextNode(' '); + insertAfter(parent, node1, parent.firstChild); + insertAfter(parent, node2, node1); + } + } + else + { + alert(ajax.responseText); + } + } + }); } function ajaxTagToCat() diff -r 5faff33a6580 -r cb7dde69c301 includes/clientside/static/dropdown.js --- a/includes/clientside/static/dropdown.js Mon Jul 30 10:46:17 2007 -0400 +++ b/includes/clientside/static/dropdown.js Wed Aug 01 13:39:27 2007 -0400 @@ -486,9 +486,12 @@ event = window.event; } clX = event.clientX; - sL = document.body.scrollLeft; + if ( document.body ) + sL = document.body.scrollLeft; + else + sL = 0; mouseX = clX + sL; - mouseY = event.clientY + document.body.scrollTop; + mouseY = event.clientY + ( document.body ? document.body.scrollTop : 0 ); return; } if( typeof(event.clientX) == 'number' ) diff -r 5faff33a6580 -r cb7dde69c301 includes/common.php --- a/includes/common.php Mon Jul 30 10:46:17 2007 -0400 +++ b/includes/common.php Wed Aug 01 13:39:27 2007 -0400 @@ -91,6 +91,7 @@ require_once(ENANO_ROOT.'/includes/json.php'); require_once(ENANO_ROOT.'/includes/wikiengine/Tables.php'); require_once(ENANO_ROOT.'/includes/pageprocess.php'); +require_once(ENANO_ROOT.'/includes/tagcloud.php'); strip_magic_quotes_gpc(); @@ -172,7 +173,8 @@ table_prefix.'acl', table_prefix.'search_cache', table_prefix.'page_groups', - table_prefix.'page_group_members' + table_prefix.'page_group_members', + table_prefix.'tags' ); dc_here('common: initializing base classes'); diff -r 5faff33a6580 -r cb7dde69c301 includes/functions.php --- a/includes/functions.php Mon Jul 30 10:46:17 2007 -0400 +++ b/includes/functions.php Wed Aug 01 13:39:27 2007 -0400 @@ -732,12 +732,9 @@ if ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' ) { echo '
'; - if ( $session->user_level >= USER_LEVEL_ADMIN ) - { - echo '
'; - echo '(show page tags)'; - echo '
'; - } + echo '
'; + echo '(show page tags)'; + echo '
'; echo '
Categories: '; $where = '( c.page_id=\'' . $db->escape($paths->cpage['urlname_nons']) . '\' AND c.namespace=\'' . $db->escape($paths->namespace) . '\' )'; @@ -2656,6 +2653,158 @@ return $array; } +/** + * Sanitizes a page tag. + * @param string + * @return string + */ + +function sanitize_tag($tag) +{ + $tag = strtolower($tag); + $tag = preg_replace('/[^\w _-]+/', '', $tag); + $tag = trim($tag); + return $tag; +} + +/** + * Gzips the output buffer. + */ + +function gzip_output() +{ + global $do_gzip; + + // + // Compress buffered output if required and send to browser + // + if ( $do_gzip && function_exists('ob_gzhandler') ) + { + // + // Copied from phpBB, which was in turn borrowed from php.net + // + $gzip_contents = ob_get_contents(); + ob_end_clean(); + + header('Content-encoding: gzip'); + $gzip_contents = ob_gzhandler($gzip_contents); + echo $gzip_contents; + } +} + +/** + * Aggressively and hopefully non-destructively optimizes a blob of HTML. + * @param string HTML to process + * @return string much snaller HTML + */ + +function aggressive_optimize_html($html) +{ + $size_before = strlen($html); + + // kill carriage returns + $html = str_replace("\r", "", $html); + + // Optimize (but don't obfuscate) Javascript + preg_match_all('/(.+?)<\/script>/is', $html, $jscript); + + // list of Javascript reserved words - from about.com + $reserved_words = array('abstract', 'as', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'continue', 'const', 'debugger', 'default', 'delete', 'do', + 'double', 'else', 'enum', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', + 'in', 'instanceof', 'int', 'interface', 'is', 'long', 'namespace', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', + 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'use', 'var', + 'void', 'volatile', 'while', 'with'); + + $reserved_words = '(' . implode('|', $reserved_words) . ')'; + + for ( $i = 0; $i < count($jscript[0]); $i++ ) + { + $js =& $jscript[2][$i]; + + // for line optimization, explode it + $particles = explode("\n", $js); + + foreach ( $particles as $j => $atom ) + { + // Remove comments + $atom = preg_replace('#\/\/(.+)#i', '', $atom); + + $atom = trim($atom); + if ( empty($atom) ) + unset($particles[$j]); + else + $particles[$j] = $atom; + } + + $js = implode("\n", $particles); + + $js = preg_replace('#/\*(.*?)\*/#s', '', $js); + + // find all semicolons and then linebreaks, and replace with a single semicolon + $js = str_replace(";\n", ';', $js); + + // starting braces + $js = preg_replace('/\{([\s]+)/m', '{', $js); + $js = str_replace(")\n{", '){', $js); + + // ending braces (tricky) + $js = preg_replace('/\}([^;])/m', '};\\1', $js); + + // other rules + $js = str_replace("};\n", "};", $js); + $js = str_replace(",\n", ',', $js); + $js = str_replace("[\n", '[', $js); + $js = str_replace("]\n", ']', $js); + $js = str_replace("\n}", '}', $js); + + // newlines immediately before reserved words + $js = preg_replace("/(\)|;)\n$reserved_words/is", '\\1\\2', $js); + + // fix for firefox issue + $js = preg_replace('/\};([\s]*)(else|\))/i', '}\\2', $js); + + // apply changes + $html = str_replace($jscript[0][$i], "$js", $html); + } + + // Which tags to strip - you can change this if needed + $strip_tags = Array('pre', 'script', 'style', 'enano:no-opt'); + $strip_tags = implode('|', $strip_tags); + + // Strip out the tags and replace with placeholders + preg_match_all("#<($strip_tags)(.*?)>(.*?)#is", $html, $matches); + $seed = md5(microtime() . mt_rand()); // Random value used for placeholders + for ($i = 0;$i < sizeof($matches[1]); $i++) + { + $html = str_replace($matches[0][$i], "{DONT_STRIP_ME_NAKED:$seed:$i}", $html); + } + + // Finally, process the HTML + $html = preg_replace("#\n([ ]*)#", " ", $html); + + // Remove annoying spaces between tags + $html = preg_replace("#>([ ][ ]+)<#", "> <", $html); + + // Re-insert untouchable tags + for ($i = 0;$i < sizeof($matches[1]); $i++) + { + $html = str_replace("{DONT_STRIP_ME_NAKED:$seed:$i}", "<{$matches[1][$i]}{$matches[2][$i]}>{$matches[3][$i]}", $html); + } + + // Remove blocks (can be used by themes that don't want their HTML optimized) + $html = preg_replace('#<(\/|)enano:no-opt(.*?)>#', '', $html); + + $size_after = strlen($html); + + // Tell snoopish users what's going on + $html = str_replace('', "\n".'\n", $html); + return $html; +} + //die('
Original:  01010101010100101010100101010101011010'."\nProcessed: ".uncompress_bitfield(compress_bitfield('01010101010100101010100101010101011010')).'
'); ?> diff -r 5faff33a6580 -r cb7dde69c301 includes/paths.php --- a/includes/paths.php Mon Jul 30 10:46:17 2007 -0400 +++ b/includes/paths.php Wed Aug 01 13:39:27 2007 -0400 @@ -845,9 +845,16 @@ // What linked categories have this page? $q = $db->sql_query('SELECT g.pg_id FROM '.table_prefix.'page_groups AS g - LEFT JOIN '.table_prefix.'categories AS c - ON ( c.category_id = g.pg_target AND g.pg_type = ' . PAGE_GRP_CATLINK . ' ) - WHERE c.page_id=\'' . $page_id . '\' AND c.namespace=\'' . $namespace . '\';'); + LEFT JOIN '.table_prefix.'categories AS c + ON ( ( c.category_id = g.pg_target AND g.pg_type = ' . PAGE_GRP_CATLINK . ' ) OR c.category_id IS NULL ) + LEFT JOIN '.table_prefix.'page_group_members AS m + ON ( ( g.pg_id = m.pg_id AND g.pg_type = ' . PAGE_GRP_NORMAL . ' ) OR ( m.pg_id IS NULL ) ) + LEFT JOIN '.table_prefix.'tags AS t + ON ( ( t.tag_name = g.pg_target AND pg_type = ' . PAGE_GRP_TAGGED . ' ) OR t.tag_name IS NULL ) + WHERE + ( c.page_id=\'' . $page_id . '\' AND c.namespace=\'' . $namespace . '\' ) OR + ( t.page_id=\'' . $page_id . '\' AND t.namespace=\'' . $namespace . '\' ) OR + ( m.page_id=\'' . $page_id . '\' AND m.namespace=\'' . $namespace . '\' );'); if ( !$q ) $db->_die(); @@ -858,6 +865,7 @@ $db->free_result(); + /* // Static-page groups $q = $db->sql_query('SELECT g.pg_id FROM '.table_prefix.'page_groups AS g LEFT JOIN '.table_prefix.'page_group_members AS m @@ -873,7 +881,20 @@ $group_list[] = $row['pg_id']; } - // Tagging ain't implemented yet ;-) + // Tag groups + + $q = $db->sql_query('SELECT g.pg_id FROM '.table_prefix.'page_groups AS g + LEFT JOIN '.table_prefix.'tags AS t + ON ( t.tag_name = g.pg_target AND pg_type = ' . PAGE_GRP_TAGGED . ' ) + WHERE t.page_id = \'' . $page_id . '\' AND t.namespace = \'' . $namespace . '\';'); + if ( !$q ) + $db->_die(); + + while ( $row = $db->fetchrow() ) + { + $group_list[] = $row['pg_id']; + } + */ return $group_list; diff -r 5faff33a6580 -r cb7dde69c301 includes/tagcloud.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/tagcloud.php Wed Aug 01 13:39:27 2007 -0400 @@ -0,0 +1,153 @@ +. + * @package Enano + * @subpackage Presentation/UI + * @copyright (C) 2007 Dan Fuhry + * @license GNU General Public License, version 2 or at your option any later versionc + */ + +class TagCloud +{ + + /** + * The list of words in the cloud. + * @var array + */ + + var $words = array(); + + /** + * Constructor. + * @param array Optional. An initial list of words, just a plain old array. + */ + + function __construct($words) + { + if ( count($words) > 0 ) + { + foreach ( $words as $word ) + $this->add_word($word); + } + } + + /** + * Adds a word into the word list. + * @param string The word to add + */ + + function add_word($word) + { + $word = strtolower($word); + + if ( isset($this->words[$word]) ) + $this->words[$word] += 1; + else + $this->words[$word] = 1; + } + + /** + * Returns the total size of the cloud. + * @return int + */ + + function get_cloud_size() + { + return array_sum($this->words); + } + + /** + * Shuffles the cloud. + */ + + function shuffle_cloud() + { + $keys = array_keys($this->words); + if ( !$keys || empty($keys) || !is_array($keys) ) + return null; + + shuffle($keys); + if ( !$keys || empty($keys) || !is_array($keys) ) + return null; + + $temp = $this->words; + $this->words = array(); + foreach ( $keys as $word ) + { + $this->words[$word] = $temp[$word]; + } + + unset($temp); + } + + /** + * Returns the popularity index (scale class) for a 1-100 number. + * @param int + * @return int + */ + + function get_scale_class($val) + { + $ret = 0; + if ( $val >= 99 ) + $ret = 1; + else if ( $val >= 70 ) + $ret = 2; + else if ( $val >= 60 ) + $ret = 3; + else if ( $val >= 50 ) + $ret = 4; + else if ( $val >= 40 ) + $ret = 5; + else if ( $val >= 30 ) + $ret = 6; + else if ( $val >= 20 ) + $ret = 7; + else if ( $val >= 10 ) + $ret = 8; + else if ( $val >= 5 ) + $ret = 9; + return $ret; + } + + /** + * Generates and returns HTML for the cloud. + * @return string + */ + + function make_html() + { + $html = array(); + $max = max($this->words); + $size = $this->get_cloud_size(); + if ( count($this->words) > 0 ) + { + foreach ( $this->words as $word => $popularity ) + { + $word = htmlspecialchars($word); + $percent = ( $popularity / $max ) * 100; + $index = $this->get_scale_class($percent); + $html[] = "$word"; + } + } + $html = implode("\n", $html); + return $html; + } + + +} + +?> diff -r 5faff33a6580 -r cb7dde69c301 index.php --- a/index.php Mon Jul 30 10:46:17 2007 -0400 +++ b/index.php Wed Aug 01 13:39:27 2007 -0400 @@ -13,17 +13,20 @@ * */ - // Set up gzip encoding before any output is sent + // Se t up gzip encoding before any output is sent - $aggressive_optimize_html = false; + $aggressive_optimize_html = true; global $do_gzip; - $do_gzip = false; + $do_gzip = true; if(isset($_SERVER['PATH_INFO'])) $v = $_SERVER['PATH_INFO']; elseif(isset($_GET['title'])) $v = $_GET['title']; else $v = ''; + if ( isset($_GET['nocompress']) ) + $aggressive_optimize_html = false; + error_reporting(E_ALL); // if(!strstr($v, 'CSS') && !strstr($v, 'UploadFile') && !strstr($v, 'DownloadFile')) // These pages are blacklisted because we can't have debugConsole's HTML output disrupting the flow of header() calls and whatnot @@ -371,35 +374,7 @@ $html = ob_get_contents(); ob_end_clean(); - // Which tags to strip - you can change this if needed - $strip_tags = Array('pre', 'script', 'style', 'enano:no-opt'); - $strip_tags = implode('|', $strip_tags); - - // Strip out the tags and replace with placeholders - preg_match_all("#<($strip_tags)(.*?)>(.*?)#is", $html, $matches); - $seed = md5(microtime() . mt_rand()); // Random value used for placeholders - for ($i = 0;$i < sizeof($matches[1]); $i++) - { - $html = str_replace("<{$matches[1][$i]}{$matches[2][$i]}>{$matches[3][$i]}", "{DONT_STRIP_ME_NAKED:$seed:$i}", $html); - } - - // Finally, process the HTML - $html = preg_replace("#\n([ ]*)#", " ", $html); - - // Remove annoying spaces between tags - $html = preg_replace("#>([ ]*?){2,}<#", "> <", $html); - - // Re-insert untouchable tags - for ($i = 0;$i < sizeof($matches[1]); $i++) - { - $html = str_replace("{DONT_STRIP_ME_NAKED:$seed:$i}", "<{$matches[1][$i]}{$matches[2][$i]}>{$matches[3][$i]}", $html); - } - - // Remove blocks (can be used by themes that don't want their HTML optimized) - $html = preg_replace('#<(\/|)enano:no-opt(.*?)>#', '', $html); - - // Tell snoopish users what's going on - $html = str_replace('', "\n\n", $html); + $html = aggressive_optimize_html($html); // Re-enable output buffering to allow the Gzip function (below) to work ob_start(); @@ -407,31 +382,8 @@ // Done, send it to the user echo( $html ); } - - // - // Compress buffered output if required and send to browser - // - if ( $do_gzip ) - { - // - // Copied from phpBB, which was in turn borrowed from php.net - // - $gzip_contents = ob_get_contents(); - ob_end_clean(); + + $db->close(); + gzip_output(); - $gzip_size = strlen($gzip_contents); - $gzip_crc = crc32($gzip_contents); - - $gzip_contents = gzcompress($gzip_contents, 9); - $gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4); - - header('Content-encoding: gzip'); - echo "\x1f\x8b\x08\x00\x00\x00\x00\x00"; - echo $gzip_contents; - echo pack('V', $gzip_crc); - echo pack('V', $gzip_size); - } - - $db->close(); - ?> diff -r 5faff33a6580 -r cb7dde69c301 install.php --- a/install.php Mon Jul 30 10:46:17 2007 -0400 +++ b/install.php Wed Aug 01 13:39:27 2007 -0400 @@ -812,7 +812,7 @@ Your e-mail address:Good/bad icon - Allow administrative embedding of PHP:
+ Allow administrators to embed PHP code into pages:
Do not under any circumstances enable this option without reading these sql_query($q); if(!$s) die('Error getting theme count: '.mysql_error().'
SQL:
'.$q); $n = $db->numrows($s); @@ -1896,10 +1896,42 @@ $theme_id = $_POST['theme_id']; $theme = Array(); include('./themes/'.$theme_id.'/theme.cfg'); - $q = 'INSERT INTO '.table_prefix.'themes(theme_id,theme_name,theme_order,enabled) VALUES(\''.$theme['theme_id'].'\', \''.$theme['theme_name'].'\', '.$n.', 1)'; - $s = $db->sql_query($q); - if(!$s) die('Error inserting theme data: '.mysql_error().'
SQL:
'.$q); - else echo('
Theme "'.$theme['theme_name'].'" installed.
'); + if ( !isset($theme['theme_id']) ) + { + echo '
Could not load theme.cfg (theme metadata file)
'; + } + else + { + $default_style = false; + if ( $dh = opendir('./themes/' . $theme_id . '/css') ) + { + while ( $file = readdir($dh) ) + { + if ( $file != '_printable.css' && preg_match('/\.css$/i', $file) ) + { + $default_style = $file; + break; + } + } + closedir($dh); + } + else + { + die('The /css subdirectory could not be located in the theme\'s directory'); + } + + if ( $default_style ) + { + $q = 'INSERT INTO '.table_prefix.'themes(theme_id,theme_name,theme_order,enabled,default_style) VALUES(\''.$db->escape($theme['theme_id']).'\', \''.$db->escape($theme['theme_name']).'\', '.$n.', 1, \'' . $db->escape($default_style) . '\')'; + $s = $db->sql_query($q); + if(!$s) die('Error inserting theme data: '.mysql_error().'
SQL:
'.$q); + else echo('
Theme "'.$theme['theme_name'].'" installed.
'); + } + else + { + echo '
Could not determine the default style for the theme.
'; + } + } } echo('

Currently installed themes

diff -r 5faff33a6580 -r cb7dde69c301 plugins/SpecialUpdownload.php --- a/plugins/SpecialUpdownload.php Mon Jul 30 10:46:17 2007 -0400 +++ b/plugins/SpecialUpdownload.php Wed Aug 01 13:39:27 2007 -0400 @@ -269,29 +269,7 @@ header('Last-Modified: '.date('r', $row['time_id'])); echo($data); - // - // Compress buffered output if required and send to browser - // - if ( $do_gzip ) - { - // - // Copied from phpBB, which was in turn borrowed from php.net - // - $gzip_contents = ob_get_contents(); - ob_end_clean(); - - $gzip_size = strlen($gzip_contents); - $gzip_crc = crc32($gzip_contents); - - $gzip_contents = gzcompress($gzip_contents, 9); - $gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4); - - header('Content-encoding: gzip'); - echo "\x1f\x8b\x08\x00\x00\x00\x00\x00"; - echo $gzip_contents; - echo pack('V', $gzip_crc); - echo pack('V', $gzip_size); - } + gzip_output(); exit; diff -r 5faff33a6580 -r cb7dde69c301 plugins/admin/PageGroups.php --- a/plugins/admin/PageGroups.php Mon Jul 30 10:46:17 2007 -0400 +++ b/plugins/admin/PageGroups.php Wed Aug 01 13:39:27 2007 -0400 @@ -504,7 +504,7 @@ if ( strval(intval($id)) == $id ) $good[] = $id; } - $subquery = 'pg_member_id=' . implode(' OR pg_member_id=', $good); + $subquery = ( count($good) > 0 ) ? 'pg_member_id=' . implode(' OR pg_member_id=', $good) : "'foo'='foo'"; $sql = 'DELETE FROM '.table_prefix."page_group_members WHERE ( $subquery ) AND pg_id=$edit_id;"; if ( !$db->sql_query($sql) ) { @@ -598,7 +598,7 @@ // More javascript magic! ?>