Thanks to Helene for the amazing job she did on this new WassUp version. Yes we have a new major release number, because there are a lot of changes on the core code.
Here is the main changelog for this version 1.7:
21 feature improvements
15 bug fixes
New features and improvements:
1) Modified Wassup to include the following design/interface changes
- -Added a top horizontal menu in the contextual menu area of WordPress 2.7+ for each page of WassUp. This improves page navigation because in WordPress 2.7 submenus are located at the bottom of the page and may be off-screen.
- -Added the word “WassUp” to the page heading on each submenu page and included the standard plugin icon in the heading for WordPress 2.7+.
- -Added a mouse-over effect using jQuery that causes the “delete” and “table” icons to be swapped with a slightly larger image.
- -Added a background color to the jQuery delete effect so the colorchanges just before the div disappears.
2) To make WassUp run in WordPress 2.6+ secure configurations that have “/wp-content/” in a directory different from WordPress itself, added a new constant, WASSUPURL, to point to WassUp’s plugin page url. Also added GET parameter, “wpabspath=ABSPATH” for “action.php” so it will also run. “wpabspath” is mime64 encoded to mask ABSPATH value before being passed on the URL.
3) Added more security and sanitizing of table data to protect against sql injection attacks:
- -Wrote a new function, “wSanitizeData”, to clean the wassup record of potentially harmful code prior to insert into mySQL.
- -Used “clean_url” WordPress function to sanitize referrer urls. This replaces the previous “htmlentities/urlencode” functions.
- -Cleaned the output of “Stringshortener()” and “AddSiteURL()” functions, inside these functions, before the output is sent. Removed sanitizing done after output, as it is no longer needed.
- -Wrote code to block hackers from using WassUp to hack WordPress by checking page requests for certain words found in malicious code and denying access when found.
- -Added a security test for logged-in user in “action.php” that aborts the program if no login is detected. This was needed because AJAX requests bypass normal WordPress login checks.
4) Updated MySQL code in “MainItems” class to improve performance and security:
- -Changed MySQL “select” statement to “SELECT SQL_BUFFER_RESULT” to reduce incidents of timeouts and memory errors on large data sets. Available for ISAM and MyISAM engines only, ignored by other engines.
- -Increased MySQL “wait_timeout” to 120 seconds.
- -Used ‘sprintf’ PHP function to build MySQL query strings in a cleaner and safer manner (similar to wpdb::prepare in WP2.3.3+).
- -Wrote a new method “MainItem::buildSearch” to generate the search portion of MySQL queries and protect against SQL injection in user-input.
- -Changed “mainItems” class constructor to accept up to 5 arguments, 3 required (table_name,to_date,from_date) and 2 optional (whereis, limit) that are used to set class variables. This replaces the requirement to set object variables separately and outside the object definition and reduces the chances of coding bugs.
- -Modified “mainItem::theChart” method to return chart URL only (no html code) for more flexibility in chart display. Removed “$chart_pos” argument as it is no longer needed.
- -Changed the code to generate charts from “if-elseif” to “switch-case” so more charts can be generated for more date ranges.
5) Added three new settings in WassupOptions:
- -“wassup_admin” for separate recording of logged-in administrators.
- -“wassup_exclude_user” to exclude recording by username.
- -“wassup_version” for use in updating Wassup tables on activation.
6) In Wassup Options page, made the following changes:
- -Added input fields for Administrator recording and username exclusion in “Statistics Recording” section.
- -Disabled “wassup_geoip_map” input field when ‘curl_init’ does not exist.
- -Internationalized messages about Curl errors.
- -Expanded the list of MySQL server and PHP settings in “Manage Database” section.
- -Moved page heading out of “settings.php” into “wassup.php” to keep page headings in one location for easier editing.
7) Added new key, “wassup_time_range”, in WassupOptions::getKeyOptions (formerly “getItemOptions”) method as the name for time range filters.
It is used to display a list of time range options for the select form on WassUp’s main/detail page.
8) Modified WassUp main/detail page to include the following:
- -Increased the number of time range filter choices to include “6 hours”, “3 months”, “6 months”, and “all time”.
- -Extended search filter to include “username” and “comment author” in the search range (in mainItems::buildSearch).
- -Moved chart code to the bottom of page and wrote a jQuery script to insert the chart at the top of page…to minimize browser timeouts due to slow up page load.
- -Administrators are listed as “Administrators” instead of “Logged-In User” to distinguish them from regular visitors.
9) Modified “createTable()” function to include the following:
- -Created a new index on “username”.
- -Changed “CREATE TABLE” to “CREATE TABLE IF NOT EXISTS” so tables are created only if needed.
- -Changed “wp_wassup_tmp” table creation to use “CREATE TABLE LIKE” syntax instead of making a second call to “createTable()”. For MySQL 4.0 or less, the 2nd call to “createTable()” is still used.
10) Modified “updateTable()” function to include the following:
- -Included a test for “wassup_version” to limit updates to only those needed for the current WassUp upgrade
- -All of ‘wp_wassup’ indices except ‘id’ are dropped and rebuilt with every upgrade. This should improve WassUp performance because indices get inefficient and corrupt over time.
11) Modified “insert_into_wp()” function to include:
- -Changed number of parameters to 2, table name and table record (an associative array). This replaces the over 20 parameters previously required and simplifies the function.
- -Changed “INSERT” syntax to “INSERT DELAYED” to queue the insert request in the background when wassup table is locked or busy.
- -Used PHP’s “sprintf” to build the MySQL insert statement and used new sanitizing function, “wSanitizeData()”, to clean up data. This is like “wpdb::prepare” for pre 2.3.3 versions of WordPress.
12) Changed “wassupAppend()/wassupaPrepend()” code to include:
- -Added IP and Hostname to wassup cookie contents to reuse hostname for multi-page visits from the same IP and avoid multiple ‘gethostbyaddr’ lookups on one IP.
- -Added “user-agent”, “browser”, “spider”, and “os” fields to the query for “duplicate check”. If results show same visitor within 3 minutes (but not duplicate) these values are reused, avoiding additional tests.
- -Added new exclusion controls by “username” and for administrators.
- -Moved search engine detection and language detection to after all exclusion control are done to avoid unnecessary tests on excluded records.
- -For detected hack attempts, URLrequested field is prepended with “” to distinguish it from valid page requests. WassUp detail reports do not create a link for these requests as the link would not exist.
- -Used PHP’s “ignore_user_abort(1)” to prevent premature aborts and window close from affecting recording. “wassupAppend” finishes recording in the background whenever a user interruption occurs.
- -Increased script execution time to 0.5 hour when wassup table is optimized as this can be slow on large tables.
- -Changed automatic purge of “wp_wassup_tmp” table to be less frequent (3 minutes interval) to avoid slowdowns due to table locks or busy server.
14) Wrote a new class, “uadetector”, that compares user-agent to the 10 most popular user-agents, then builds on the “detector” class to identify more obscure user-agents. It can detect IE8, Win7, Win2008, Windows 64-bit os versions, and mobile devices.
15) Wrote a new function, “wMajorVersion()”, to return the major number from a version string. This function is used to make sure that browser information stored in wassup table is limited to browser name and major version number only. Common browsers will now be counted more accurately in WassUp statistics.
16) Wrote a new function, “validIP()”, to identify and return a valid IP address from a list of IPs. This is used find a visitor’s IP when IP forwarding or a proxy server is used.
17) Updated “wGetSpider()” function to include the following:
- -Added tests to identify MSN and Yahoo robots by their hostname or IP as these crawlers don’t always use a unique user-agent string to distinguish themselves from regular visitors.
- -Added a “break” to exit foreach loop immediately after user agent match is found.
- -Added tests for obvious script injection bots.
- -Added a new return parameter, crawlertype, to distinguish Robots, feed readers, link checkers, etc. For script injection bots crawlertype=”H” is returned which then causes spam=”3″ (hack attempt) to be set in wassup record.
- -Removed wildcards and version#’s from spider array because wildcards are not matched and version number can change.
- -Added new agents and removed obsolete agents from spider array.
18) Wrote a new function, “wGetStats()” to compile and output statistics in an ordered array for “top ten” and widget stats. Currently this is only implemented for “top ten” referrers.
19) Modified “spyview()” function to add an optional 5th parameter, “spy_datasource”. This parameter is the name of the wassup table used as the source of spy data. The default is “wp_wassup_tmp”. However, when “spy” page is first opened, “wp_wassup” is used to populate the screen and chart with 10 initial data points.
20) Wrote a new function, “backup_wassup()” to output wassup SQL data to a file. Intended as an alternative to “export_wassup” which times out
on large tables. Currently not implemented.
21) Added a Debug mode to print out some useful information about the page you are surfing (blog and admin pages). “$debug_mode” is assigned only once in the beginning of “wassup.php”, then declared global in all functions where it is used in “wassup.php”, “main.php”, and “uadetector.php”. In “action.php” it is passed as a GET parameter. you have to manually activate it by set it to TRUE in wassup.php ($debug_mode=true;)
Bug fixes and code cleanup:
1) Fixed the problem with WassUp widget that caused the widget options to be inaccessible after being set once. Also changed widget so that
there is no data displayed when WassUp is inactive (not recording).
2) Updated main/detail page and “action.php” to send a keep-alive “heartbeat” output to the browser (<!–heartbeat–>) and increased PHP script timeout length to help prevent browser timeouts when MySQL is slow to respond.
3) Removed redundant sanitizing functions such as “htmlentities(attribute_escape())” and “urlencode(attribute_escape())” on $_POST, $_GET, or database variables and replaced them with either a single “attribute_escape()” function or a test for a valid numeric value.
4) Removed the redundant “attribute_escape” from the prepare statement in “insert_into_db()” function because “prepare()” does it’s own sanitizing of data.
5) In “createTables()” function, removed the test for $wpdb->supports_collation() because that method is only available in wordpress 2.5+ and does the same thing as the existing version check for mySQL 4.1 (redundant).
6) Commented out “wp_cache_flush() because it clears the database cache and could cause WordPress to run sluggishly on slow servers.
7) Replaced “wp_get_current_user” with “get_currentuserinfo()” which sets the $current_user global in “WassupAppend/WassupPrepend” functions. Plugins can override “wp_set_current_user” and this could affect logged-in user detection. It is unknown whether this change fixes the reported problem with WassUp not tracking logged-in users when a login management plugin is installed.
8) Removed “is_admin()” test before calling “wassupPrepend()” because it caused all “hack attempts” to be omitted from recordings.
9) Created variables “$URLQuery” and “$stickyfilters” to replace $_SERVER[‘QUERY_STRING’] in link creation for user selectable filters on Wassup Detail page…to prevent parameters from being reset whenever a new filter is selected.
10) In WassupOptions class, changed user role names to match WordPress user role/level numbers (fixes bug reported in wpwp forums). Role names are now standard WordPress names (no pluralization) and is translatable by WordPress itself, not just Wassup.
11) Set “wassup_active” option to inactive in “wassup_uninstall()” and for “Options ==>Uninstall” to stop recordings before “wp_wassup” table is deleted…to avoid any problems with Wassup’s delayed inserts and background operations (see new features above).
12) Fixed several problems with the “spyview()” function in “main.php”:
- -Replaced MySQL query with a simple select statement with no “group by” clause. “group by id” was unneeded because `id` is a unique field and any groups on it would have exactly one member.
- -Inserted missing quotation marks in $_SERVER[HTTP_USER_AGENT] on lines #660 and 779.
- -Added a test for ‘curl_init’ so “spy” will run even when a user don’t have ‘Curl’ on their server. Line #654.
- -Fixed a bug that caused the list of visitor records to occasionally display without any color-coding. Reset $unclass to “sum-box” after each “foreach” iteration and changed PHP code that sets the <div> class.
- -Reduced the frequency of “No Activity” messages” by increasing the modulo number to “99” in line#763.
- -Added a test for existence of $data on line #695 to prevent PHP warnings.
- -Removed a redundancy check on “username” in elseif statement on line#642.
13) In the “top ten” report, added the condition “spider=”” to “top browsers” and “top os” to prevent spiders from skewing statistics.
14) In “action.php”, replaced “$wassup_options” with “$wassup_settings” because “$wassup_options” is not defined in the “action.php” module.
15) In “wGetLocale()” function, added code to swap japanese language code “ja” to Japan country code “jp”, for consistency and flag display. Country code swaps (or a flag) is still needed for the languages: ko, he, ur, and da.