Example #1
0
/**
 * @version $Id$
 * @author Matthew McNaney <mcnaney at gmail dot com>
 */
function core_update(&$content, $version)
{
    $content[] = '';
    // Versions previous to 1.9.8 removed 2 May, 2013.
    switch (1) {
        case version_compare($version, '1.9.8', '<'):
            $content[] = '<h2>Sorry</h2>
<p>Your version of phpWebSite is too old to update using 1.8.0. Please update to
1.7.3 and return.</p>';
        case version_compare($version, '2.0.0', '<'):
            if (PHPWS_Core::isBranch()) {
                $content[] = 'This update can only be performed on the hub.';
                return false;
            }
            if (!PHPWS_Boost::inBranch()) {
                $config_dir = PHPWS_SOURCE_DIR . 'config/core/';
                if (!is_writable($config_dir)) {
                    $content[] = '<p>Core update can not continue until your hub installation\'s <strong>config/core/</strong> directory is writable.</p>';
                    return false;
                }
                $source_http = sprintf("<?php\ndefine('PHPWS_SOURCE_HTTP', '%s');\n?>", PHPWS_CORE::getHomeHttp());
                if (!file_put_contents($config_dir . 'source.php', $source_http)) {
                    $content[] = '<p>Could not create config/core/source.php file.</p>';
                    return false;
                }
                $content[] = <<<EOT
                <pre>2.0.0 changes
-----------------
+ Hub/Branch overhaul. Branches pull config, templates, javascript,
  and theme files from hub instead of locally.
+ Added Icon class. Standardizes icons and prevents overlap.
+ Added Tag class: extendable class used with Image and Form2.
+ Added tag_implode function.
+ Created Form2 class.
+ Added CKeditor.
+ Added Lightbox.
+ getConfigFile does not throw error now.
+ Dutch translation updated.
+ Added autoload function for core classes.
+ Source dir derived from file path and not simply "./"
+ Added Image class.
+ Critical functions changed to throw exceptions.
+ Setup steamlined.</pre>

<p><strong>Note:</strong> this update creates a backup of your config/core/config.php file named<br />
config-prior170.php.<br />
If your installation is working, this file may be safely deleted.</p>
<p>IMPORTANT! Many settings in the old config.php have been moved to core/conf/defines.php in the hub.
You can delete all settings <strong>except</strong> the following:</p>
<ul><li>PHPWS_SOURCE_DIR</li>
<li>PHPWS_HOME_DIR</li>
<li>PHPWS_SOURCE_HTTP</li>
<li>SITE_HASH</li>
<li>PHPWS_DSN</li>
<li>PHPWS_TABLE_PREFIX</li></ul>
</pre>
EOT;
            }
            if ($branch = PHPWS_Boost::inBranch(true)) {
                if (!PHPWS_File::copy_directory(PHPWS_SOURCE_DIR . 'javascript/editors/fckeditor/', $branch->directory . 'javascript/editors/fckeditor', true)) {
                    mkdir($branch->directory . 'images/ckeditor/');
                    $this->content[] = dgettext('branch', 'Failed to copy FCKeditor to branch.');
                } else {
                    $content[] = 'FCKeditor not copied to branch. Check directory permissions.';
                }
            } else {
                mkdir(PHPWS_SOURCE_DIR . 'images/ckeditor/');
            }
        case version_compare($version, '2.0.1', '<'):
            $content[] = <<<UPDATES
            <pre>2.0.1 changes
----------------------
+ Fixed captcha trying to pull from branch directory.
+ Fixed templates ignoring use_hub_themes setting.
+ Image class will accept tilde in source directory.
+ Database fix for insert and update on multiple tables.
+ Powerpoint types added to file check.
+ Background mode added to index (allows for selective loading on Ajax calls)
+ Freecap ereg_replace updated to preg_replace
+ Fix for js_calendar
+ Fix for javascript alert script
+ Fixes for Fckeditor and Tinymce
+ Inclusion of ngBackup
</pre>
UPDATES;
        case version_compare($version, '2.0.2', '<'):
            $content[] = <<<UPDATES
<pre>2.0.2 changes
----------------------
+ Added To top icon
+ Fixed table bug where names used in foreign key constrains (in CREATE TABLE statements) were not prefixed correctly
+ Removed HTML from some translations.
+ Fixed bug causing a table name to be repeated in a JOIN statement
+ Fixed some PHP notice errors.
+ Fixed some hub icon directory problems (Thanks Eloi).
+ Image resizing reworked to correct problems with irregular images.
+ ngBackup updates.
+ Fixed some templating issues (Thanks Tommy, Eloi).
+ URL validity checking in Text was made more robust.
+ Fixed some label id issues in form.
+ Fixed a loadDimensions error in Image (Thanks Eloi)
+ Fixed DBPager duplicating table insertions (Thanks Eloi)
+ Fixed some PEAR PHP 5 warnings.
+ Changed URL forwarding - if first value after the module is numeric, it is cast as an id.
+ Removed deny-all .htaccess file from file directory.
</pre>
UPDATES;
        case version_compare($version, '2.1.0', '<'):
            $content[] = <<<UPDATES
<pre>2.1.0 changes
----------------------
 + Another Powerpoint file mimetype added to file_types.php
 + Turned off collapse_urls as a default condition.
 + Added cosign configuration example in defines.dist.php
 + More static warnings silenced.

Classes
----------------
 + Form.php
    - Fixed bug with addCheckAssoc
    - Added onbeforeclose protection to forms
    - Fixed array handling in PHPWS_Form::grab(). If the array of elements isn't
      indexed by integers, it will return the entire array instead of trying to
      return element 0.
 + Error.php
    - Pear method call was called all lowercase. Probably a hold over
      from when function name case was irrelevant.
 + Cookie.php
    - Cookie assumes a cookie is set before deletion. Changed function
      call to check prior to operation.
 + File.php
    - Fix to file extension checking.
 + Core.php
    - Moved some logic for finding the site Base URL out of Layout and
      into Core, as the getBaseURL() function
 + Text.php
    - Missing variable added to parameter list.
    - Faulty parse_url is being silenced on failure and getGetValues returns null.
    - Filtering out high ascii using parseOutput
 + Init.php
    - Fixed overwrite problem with defines.php on updating.
 + Database.php
    - Removed restrictive join check
    - Database substitutes table "as" if it exists on column call and/or set order
    - Allow parenthesis and commas in addOrder, so we can order by function,
      like "order by coalesce(...)"
    - Fixed splat usage with count in addColumn and getColumn
+ DBPager.php
    - Rewrote CSV parser to use fputcsv
    - Fixed bug with csv reporting

Javascript
------------------
+ captcha/recaptcha - added recycle instructions
+ required_input - file inputs can now be required fields
+ protect_form - new javascript to prevent user leaving fields blank
+ jquery - updated
+ flowplayer - updated version
+ editors
    + ckeditor - added File Cabinet functionality
    + cleditor - added Cleditor by Hilmar
</pre>
UPDATES;
        case version_compare($version, '2.1.1', '<'):
            $content[] = <<<UPDATES
<pre>
2.1.1 changes
-----------------

Core Classes
-----------------
+ Fixed bugs with Key and Database. Registered users (not deities) were having problems
  with editing and view restricted items. PHPWS_DB::groupIn rewritten.
+ Core now has better error messages for Branches problems.
+ Image - removed px from width and height for xhtml compatibility.
+ Static notice fixes
+ Removed clone function call in Icon.

Javascript
----------------
+ jquery_ui and jquery updated
</pre>
UPDATES;
        case version_compare($version, '2.2.0', '<'):
            $changes = file_get_contents(PHPWS_SOURCE_DIR . 'core/boost/changes/2_2_0.txt');
            $content[] = "<pre>{$changes}</pre>";
        case version_compare($version, '2.3.0', '<'):
            try {
                include_once PHPWS_SOURCE_DIR . 'core/boost/updates/2_3_0.php';
                update_core_2_3_0();
            } catch (\Exception $e) {
                $content[] = 'Error: ' . $e->getMessage();
                return false;
            }
            $changes = file_get_contents(PHPWS_SOURCE_DIR . 'core/boost/changes/2_3_0.txt');
            $content[] = "<pre>{$changes}</pre>";
        case version_compare($version, '2.3.1', '<'):
            $db = \Database::newDB();
            $db->setConditional($db->addTable('modules')->getFieldConditional('title', 'comments'));
            $db->delete();
            $db = \Database::newDB();
            $db->setConditional($db->addTable('controlpanel_link')->getFieldConditional('itemname', 'comments'));
            $db->delete();
            $db = \Database::newDB();
            if ($db->tableExists('comments_items')) {
                $db->buildTable('comments_items')->drop();
            }
            if ($db->tableExists('comments_items_seq')) {
                $db->buildTable('comments_items_seq')->drop();
            }
            if ($db->tableExists('comments_monitors')) {
                $db->buildTable('comments_monitors')->drop();
            }
            if ($db->tableExists('comments_permissions')) {
                $db->buildTable('comments_permissions')->drop();
            }
            if ($db->tableExists('comments_ranks')) {
                $db->buildTable('comments_ranks')->drop();
            }
            if ($db->tableExists('comments_ranks_seq')) {
                $db->buildTable('comments_ranks_seq')->drop();
            }
            if ($db->tableExists('comments_threads')) {
                $db->buildTable('comments_threads')->drop();
            }
            if ($db->tableExists('comments_threads_seq')) {
                $db->buildTable('comments_threads_seq')->drop();
            }
            if ($db->tableExists('comments_users')) {
                $db->buildTable('comments_users')->drop();
            }
            if ($db->tableExists('comments_user_ranks')) {
                $db->buildTable('comments_user_ranks')->drop();
            }
            if ($db->tableExists('comments_user_ranks_seq')) {
                $db->buildTable('comments_user_ranks_seq')->drop();
            }
            $db = \Database::newDB();
            if ($db->tableExists('categories')) {
                $db->buildTable('categories')->drop();
            }
            if ($db->tableExists('categories_seq')) {
                $db->buildTable('categories_seq')->drop();
            }
            if ($db->tableExists('categories_permissions')) {
                $db->buildTable('categories_permissions')->drop();
            }
            if ($db->tableExists('category_items')) {
                $db->buildTable('category_items')->drop();
            }
            if ($db->tableExists('category_items_seq')) {
                $db->buildTable('category_items_seq')->drop();
            }
            $db = \Database::newDB();
            $db->setConditional($db->addTable('modules')->getFieldConditional('title', 'categories'));
            $db->delete();
            $db = \Database::newDB();
            $db->setConditional($db->addTable('controlpanel_link')->getFieldConditional('itemname', 'categories'));
            $db->delete();
            $content[] = '<pre>Core 2.3.1 Changes
-------------------
+ Removed Comments module
+ Removed Categories module
</pre>';
        case version_compare($version, '2.3.2', '<'):
            $content[] = '<pre>Core 2.3.2 Changes
-------------------
+ Bootstrap
    - Updated Bootstrap theme to Bootstrap 3.0.1
    - Added Bootstrap table styles to several modules.
    - Removed class name "label" from several templates as it is a reserved class name
        in Bootstrap. Leaving it caused white text.
+ Font Awesome
    - Font Awesome replaced several module icons.
    - Updated Icon class to use Font Awesome 4
+ Changed phpDSNLoader to accept the table prefix as a parameter instead of relying on a define.
+ added loadPDO to exec method should it get unset.
+ Removed remnants of category calls.
+ xml2php changed to catch an exception.
+ Added Dutch translation from Han Velthuis.
+ Rewrote some Global error messages to be more descriptive.
+ Removed "simple" theme.
+ Fixed define bug casuing setup errors.
+ Pear deprecated when possible.
+ Filter code (BB and pear) removed from Text parsing.
+ Removed firebug code, ngboost and ngcom.
+ A theme can now define default classes for inputs, labels, and element groups.
+ date_default_timezone_set added to index.php to conform with new PHP standards.
+ Error check on PHPWS_Form class added.
+ Removed setup/manager.php
+ Fixed GD version detection. Was causing resampled images to be downgraded.
+ Swiftmail library added. Not in use yet but will replace other mail functions.
+ Added abbr tag to allowed_tags.
+ Global\\Server
    - fixed getCurrentUrl adding extra slashes
+ Global\\Variable
    - setRange and setIncrement return $this to allow method chaining.
    - setText will change a bool to a 0 or 1 for display.
    - Integer creates a ranged select if setInputType is set to select.
    - Unlimited String will create a text column in the database and no longer a varchar.
    - Text input is no longer the default type for a Variable object
    - Fixed: String validity check would fail on empty or null values.
    - String-type variable limits raised to reflect higher varchar limits
    - Added unlink method to File class.
    - Boolean now shows up in a Debug call
+ Global\\Form
    - Form can now define groupings for use with Bootstrap
    - Form Labels are now a class instead of a string.
    - addInputClass will plug a css class to every input in the Global\\Form.
    - Placeholders can now be added to input objects.
    - Required check works with onblur instead of change allowing blanks to be detected.
    - Submit button will be disabled if form set to use required inputs.
    - Choice\\Select now allows first choice to be blank
    - Input\\Text now allow apostrophes.
    - Added to ability to theme buttons
    - Added return to Text to allow method chaining.
    - Removed code that automatically copied the options of integer keyed arrays
        over the key. Instead added a copyOptionToValue method.
+ Global\\Database
    - Added addFieldConditional method to Table class.
    - Text added as datatype.
    - Added joinResources method to replace join method
    - Large update to allow multiple conditionals to join statements
    - Update to subselects and tables to work properly with fields.
    - Added Exists class which is an extension of Conditional. Works with subselects.
    - DB quote changed to static method.
    - Conditionals were missing proper quoting methods.
    - Added stringAsField method to Expression.
    - Conditional checks for alias on getLeft
+ Global\\Resource returns the id of the resource as a hidden input.
    - createTable returns a table object
+ Global\\Request added methods for returning FILES information
    - Added new functions to Request to assist with command branching.
    - Added lastCommand method
+ Global\\ResourceFactory selectInto fixed as private and protected variables would not work
+ Global\\Pager
    - Added addJsonData and json_data variable. Allows entering a key=>value pair
        that will be included in the JSON return.
    - Fixed search box display
    - Fixed search clear
    - Added page count to JSON result. Not in UI yet.
    - Added method to set the data url to the pager template.
    - Added undefined check to prevent javascript error.
+ Global\\DatabasePager
    - added showQuery function and show_query variable. If variable is true, the
        select query will be inserted into the JSON return for evaluation
    - Total row calculation moved up in process so current page count is correct.
</pre>';
        case version_compare($version, '2.4.0', '<'):
            $db = \Database::newDB();
            $tbl = $db->addTable('modules');
            $tbl->addFieldConditional('title', 'clipboard');
            $db->delete();
            $db->clearConditional();
            $tbl->addFieldConditional('title', 'demographics');
            $db->delete();
            $db->clearTables();
            if ($db->tableExists('demographics')) {
                $tbl = $db->addTable('demographics');
                $tbl->drop();
            }
            $content[] = <<<EOF
<pre>Core 2.4.0 Changes
--------------------------------
+ Dropping clipboard module.
+ Dropping demographics module.
</pre>
EOF;
        case version_compare($version, '2.4.1', '<'):
            $db = \Database::newDB();
            $db->addTable('modules')->addFieldConditional('title', 'version');
            $db->delete();
            $content[] = <<<EOF
<pre>Core 2.4.1 Changes
--------------------------------
+ Removed Version module from Core modules
+ Pear DB changed to MDB2.
+ MDB2 using mysqli class instead of mysql class to prevent MySQL deprecation warnings.
+ Fixed GD library identification.
+ DTTIME format now includes hour, minute, and seconds set to zero as "all day" is interpreted differently by ical.
+ ResourceFactory returns True on successful load and false otherwise. Previously returned void.
+ Added aspell plugin for CKEditor. Written by Christian Boisjoli.
+ CKeditor
    - altered to have smoother button transitions when width is changed.
    - removed Style button
    - default width is 100% instead of hard coded pixel
    - imports images with img-responsive class added
+ Javascript added to avoid image loading on small screens
+ Fixed createConfig function in setup script
EOF;
        case version_compare($version, '2.4.2', '<'):
            $db = \Database::newDB();
            $t1 = $db->addTable('settings');
            $indexes = $t1->getIndexes();
            if (empty($indexes)) {
                $t1->createPrimaryIndexId();
            }
            $content[] = <<<EOF
<pre>
Core 2.4.2 Changes
--------------------
+ Index added to the Settings table
+ dropIndex and createPrimaryIndexId methods added to Database Table
+ Update autoloader to allow modules classes to be in their own top-level namespace
+ Global/Module: Unnecessary ampersand removed from afterRun
+ Global/Form: setAction missing https check.
+ Global/Form/Input/Date: Added min, max, and step parameters to conform with HTML5
+ Global/Form/Input/Date: setValue parses integer values
+ Global/Form/Label: required parameter made private. It was breaking the required tag.
+ Global/Modal: new class that allows for easier insertion of a bootstrap modal window.
+ Global/Variable/Integer: fixed typo with class name Exception
+ Global/Form: Added removeInput method
+ core/class/PHPWS_DB: Previously, Pear's DB class would return two column results
  as an array with the key as the first column and the value as the second. This
  behavior was inconsistent with the expected functionality. We had code programmed
  expecting this behavior. MDB2 did not replicate it, so two column results were
  broken. New code brings the result back to the expected action.
+ core/class/Link: addClass method added. setClass accepts an array
+ CKeditor: Allows i tags for use with Font Awesome and to not strip spans.
+ CKeditor: Shortened max height on autogrow. Previously, 600px frequently pushed
            it outside the monitor bounds.
</pre>
EOF;
        case version_compare($version, '2.5.0', '<'):
            $content[] = <<<EOF
<pre>
Core 2.5.0 Changes
------------------
+ Added selectAsCSV to Global Database class.
</pre>
EOF;
        case version_compare($version, '2.6.0', '<'):
            $content[] = <<<EOF
<pre>
Core 2.6.0 Changes
------------------
+ Improved DBPager Search bar and pagination
+ Updated CKEditor from 3 to 4.
+ Removed Editor class.
+ Added PHPWS_File stub file to work with autoload.
+ Added method to set width and height on Modal.
+ Added method to pull hidden variables.
+ Removed Simple and Tinymce editors
+ Updated datetimepicker script
</pre>
EOF;
        case version_compare($version, '2.7.0', '<'):
            $content[] = <<<EOF
<pre>
+ Bug Fix: CKEditor images folder returned.
+ Bug Fix: Database - Blank schema error check added to mysql Table class.
+ Bug Fix: Database - Mislabeled return on getDateType.
+ Change: datepicker - script tags put into head.js
+ Update: Bootstrap and Font Awesome version
+ Feature: Database - added "using" ability. Helps with multi-table deletions.
+ Update: Flowplayer version upped. Captioning ability added.
+ Removed: javascript/editor/ directory and all wysiwyg editors outside of ckeditor
+ Removed: Unsupported modules: phpwsbb, podcaster, and profiler
+ Bug Fix: core/class/DBPager - setDefaultOrder was ignored
+ Bug Fix: Removed @ error suppressors throughout code. Should be fun right?
+ Feature: Added exception messages to JsonErrorView.
           Previously info had to be dug out of an html encoded exception object.
+ Bug Fix: Global/Pager Search icon with bad class name
+ Feature: Global/Pager Search columns can now be set manually instead of depending on the headers.
+ Feature: Global/Tag - removeClass method - removes a class previously added to the class variable stack
+ Feature: Added authkey javascript for insertion of the authkey value for use in other js scripts.
+ Added:  &lt;s&gt; as allowed tag.
+ Feature: CKEditor Save button added for use with some modules.
</pre>
EOF;
        case version_compare($version, '2.8.0', '<'):
            $db = \Database::newDB();
            $t = $db->addTable('settings');
            $dt_old = $t->getDataType('setting');
            $dt_update = new \Database\Datatype\Text($t, 'setting');
            $dt_update->setIsNull(true);
            $t->alter($dt_old, $dt_update);
            $content[] = <<<EOF
<pre>2.8.0 changes
--------------------
+ Settings table setting column is now TEXT not VARCHAR.
</pre>               
EOF;
        case version_compare($version, '2.8.1', '<'):
            $db = \Database::newDB();
            $t = $db->addTable('settings');
            $dt_old = $t->getDataType('setting');
            $t->buildDatatype('mediumtext', 'setting');
            $dt_update = new \Database\Datatype\Text($t, 'setting');
            $dt_update->setIsNull(true);
            $t->alter($dt_old, $dt_update);
            $content[] = <<<EOF
<pre>2.8.1 changes
--------------------
+ Settings table setting column is now MEDIUMTEXT not TEXT.
</pre>               
EOF;
    }
    return true;
}
Example #2
0
 /**
  * Uses the Pear log class to write a log file to the logs directory
  */
 public static function log($message, $filename, $type = NULL)
 {
     if (!is_writable(LOG_DIRECTORY)) {
         exit(_('Unable to write to log directory.'));
     }
     if (is_file(LOG_DIRECTORY . $filename) && !is_writable(LOG_DIRECTORY . $filename)) {
         exit(sprintf(_('Unable to write %s file.'), $filename));
     }
     $conf = array('mode' => LOG_PERMISSION, 'timeFormat' => LOG_TIME_FORMAT);
     if (PHPWS_Core::isBranch()) {
         $branch_name = Branch::getCurrentBranchName();
         $message = '{' . $branch_name . '} ' . $message;
     } else {
         $message = '{HUB} ' . $message;
     }
     logMessage($message, $filename);
 }
Example #3
0
 /**
  * Copy of the setup function of the same name
  * This one also checks the write and read capabilities of
  * the log files.
  */
 public static function checkDirectories(&$content, $home_dir = null, $check_branch = true)
 {
     $errorDir = true;
     if (empty($home_dir)) {
         $home_dir = PHPWS_Boost::getHomeDir();
     }
     $directory[] = $home_dir . 'images/';
     $directory[] = $home_dir . 'files/';
     $directory[] = LOG_DIRECTORY;
     foreach ($directory as $id => $check) {
         if (!is_dir($check)) {
             $dirExist[] = $check;
         } elseif (!is_writable($check)) {
             $writableDir[] = $check;
         }
     }
     if (isset($dirExist)) {
         $content[] = dgettext('boost', 'The following directories need to be created:');
         $content[] = implode("\n", $dirExist);
         $errorDir = false;
     }
     if (isset($writableDir)) {
         $content[] = dgettext('boost', 'The following directories are not writable:');
         $content[] = implode(chr(10), $writableDir);
         $errorDir = false;
     }
     $files = array('boost.log', 'error.log');
     foreach ($files as $log_name) {
         if (is_file('logs/' . $log_name) && (!is_readable('logs/' . $log_name) || !is_writable('logs/' . $log_name))) {
             $content[] = sprintf(dgettext('boost', 'Your logs/%s file must be readable and writable.'), $log_name);
             $errorDir = false;
         }
     }
     if (!isset($GLOBALS['Boost_Ready'])) {
         $GLOBALS['Boost_Ready'] = $errorDir;
     }
     if (!$errorDir) {
         $GLOBALS['Boost_Current_Directory'] = false;
     }
     if ($check_branch && !PHPWS_Core::isBranch() && PHPWS_Core::moduleExists('branch')) {
         $db = new PHPWS_DB('branch_sites');
         $db->addColumn('branch_name');
         $db->addColumn('directory');
         $result = $db->select();
         if (!empty($result)) {
             if (PHPWS_Error::logIfError($result)) {
                 $content[] = dgettext('boost', 'An error occurred when tryingt to access your branch site listing.');
                 $content[] = dgettext('boost', 'Branches could not be checked.');
                 return $errorDir;
             }
             foreach ($result as $branch) {
                 $contentTmp = array();
                 if (!PHPWS_Boost::checkDirectories($contentTmp, $branch['directory'], false)) {
                     $content[] = sprintf(dgettext('boost', 'Checking branch "%s"'), $branch['branch_name']);
                     foreach ($contentTmp as $tmp) {
                         $content[] = $tmp;
                     }
                     $content[] = '';
                     $errorDir = false;
                 }
             }
         }
     }
     return $errorDir;
 }
Example #4
0
/**
 * @author Matthew McNaney <mcnaney at gmail dot com>
 * @version $Id$
 */
function users_update(&$content, $currentVersion)
{
    $home_dir = PHPWS_Boost::getHomeDir();
    switch ($currentVersion) {
        case version_compare($currentVersion, '2.2.0', '<'):
            $content[] = 'This package does not update versions under 2.2.0';
            return false;
        case version_compare($currentVersion, '2.2.1', '<'):
            $content[] = '+ Fixed a bug causing conflicts between user and group permissions.';
        case version_compare($currentVersion, '2.2.2', '<'):
            $content[] = '+ Set username to the same character size in both users table and user_authorization.';
            $content[] = '+ Fixed typo causing branch installation failure on Postgresql.';
        case version_compare($currentVersion, '2.3.0', '<'):
            $content[] = '<pre>
2.3.0 changes
------------------------
+ Added translate function calls in classes and my_page.php
+ my_page hides translation option if language defines disable selection
+ Added a unrestricted only parameter to Current_User\'s allow and
  authorize functions
+ Dropped references from some constructors
+ Added error check to setPermissions function: won\'t accept empty
  group id
+ Changed id default to zero.
+ Removed unneeded function parameter on getGroups
</pre>
';
        case version_compare($currentVersion, '2.3.1', '<'):
            $content[] = '<pre>';
            $files = array('templates/my_page/user_setting.tpl');
            userUpdateFiles($files, $content);
            $content[] = '
2.3.1 changes
------------------------
+ Added ability for user to set editor preferences
</pre>
';
        case version_compare($currentVersion, '2.3.2', '<'):
            $content[] = '<pre>2.3.2 changes';
            $files = array('img/users.png', 'templates/user_main.tpl');
            userUpdateFiles($files, $content);
            $content[] = '+ Added error check to login.
+ Changed user control panel icon.
+ Fixed template typo that broke IE login.
+ Removed fake French translation (delete mod/users/locale/fr_FR/ directory
+ Permissions are now ordered alphabetically.
+ isUser will now always return false if passed a zero id.
+ Added new function requireLogin that forwards a user to the login
  screen
</pre>';
        case version_compare($currentVersion, '2.4.0', '<'):
            if (!PHPWS_DB::isTable('users_pw_reset')) {
                $new_table = 'CREATE TABLE users_pw_reset (
user_id INT NOT NULL default 0,
authhash CHAR( 32 ) NOT NULL default 0,
timeout INT NOT NULL default 0,
);';
                if (!PHPWS_DB::import($new_table)) {
                    $content[] = 'Unable to create users_pw_reset table.';
                    return false;
                } else {
                    $content[] = 'Created new table: users_pw_reset';
                }
            }
            $files = array('templates/forms/reset_password.tpl', 'templates/forms/forgot.tpl', 'conf/config.php', 'templates/usermenus/top.tpl', 'templates/forms/settings.tpl', 'templates/my_page/user_setting.tpl');
            $content[] = '<pre>';
            userUpdatefiles($files, $content);
            if (!PHPWS_Boost::inBranch()) {
                $content[] = file_get_contents(PHPWS_SOURCE_DIR . 'mod/users/boost/changes/2_4_0.txt');
            }
            $content[] = '</pre>';
        case version_compare($currentVersion, '2.4.1', '<'):
            $content[] = '<pre>';
            $files = array('conf/languages.php');
            userUpdateFiles($files, $content);
            $content[] = '
2.4.1 changes
------------------------
+ Default item id on permission check functions is now zero instead of
  null. This will make checking permissions a little easier on new items.
+ Bug #1690657 - Changed group select js property to onclick instead
  of onchange. Thanks singletrack.
+ Changed the language abbreviation for Danish
</pre>
';
        case version_compare($currentVersion, '2.4.2', '<'):
            $content[] = '<pre>';
            $files = array('templates/usermenus/Default.tpl');
            userUpdateFiles($files, $content);
            if (!PHPWS_Boost::inBranch()) {
                $content[] = file_get_contents(PHPWS_SOURCE_DIR . 'mod/users/boost/changes/2_4_2.txt');
            }
            $content[] = '</pre>';
        case version_compare($currentVersion, '2.4.3', '<'):
            $content[] = '<pre>';
            if (!PHPWS_Boost::inBranch()) {
                $content[] = file_get_contents(PHPWS_SOURCE_DIR . 'mod/users/boost/changes/2_4_3.txt');
            }
            $content[] = '</pre>';
        case version_compare($currentVersion, '2.4.4', '<'):
            $content[] = '<pre>';
            $source_dir = PHPWS_SOURCE_DIR . 'mod/users/javascript/';
            $dest_dir = $home_dir . 'javascript/modules/users/';
            if (PHPWS_File::copy_directory($source_dir, $dest_dir, true)) {
                $content[] = "--- Successfully copied {$source_dir} to {$dest_dir}";
            } else {
                $content[] = "--- Could not copy {$source_dir} to {$dest_dir}";
            }
            $files = array('conf/error.php', 'templates/forms/permissions.tpl', 'templates/forms/permission_pop.tpl');
            userUpdateFiles($files, $content);
            if (!PHPWS_Boost::inBranch()) {
                $content[] = file_get_contents(PHPWS_SOURCE_DIR . 'mod/users/boost/changes/2_4_4.txt');
            }
            $content[] = '</pre>';
        case version_compare($currentVersion, '2.4.5', '<'):
            $content[] = '<pre>';
            $files = array('conf/error.php', 'conf/languages.php', 'templates/forms/settings.tpl', 'templates/manager/groups.tpl');
            userUpdateFiles($files, $content);
            if (!PHPWS_Boost::inBranch()) {
                $content[] = file_get_contents(PHPWS_SOURCE_DIR . 'mod/users/boost/changes/2_4_5.txt');
            }
            $content[] = '</pre>';
        case version_compare($currentVersion, '2.4.6', '<'):
            $content[] = '<pre>';
            $files = array('templates/forms/forgot.tpl');
            userUpdateFiles($files, $content);
            if (!PHPWS_Boost::inBranch()) {
                $content[] = '
2.4.6 changes
-------------------
+ Added error check to permission menu.
+ Error for missing user groups now reports user id.
+ Forgot password will work if CAPTCHA is disabled.
+ Using new savePermissions function instead of save.
+ Current_User was calling giveItemPermissions incorrectly.';
            }
            $content[] = '</pre>';
        case version_compare($currentVersion, '2.4.7', '<'):
            $content[] = '<pre>
2.4.7 changes
-------------------
+ Removed global authorization from change password check since it is not
  written yet.
</pre>';
        case version_compare($currentVersion, '2.4.9', '<'):
            $content[] = '<pre>';
            if (PHPWS_Core::isBranch() || PHPWS_Boost::inBranch()) {
                $user_db = new PHPWS_DB('users');
                $user_db->addWhere('deity', 1);
                $user_db->addColumn('id');
                $user_db->addColumn('username');
                $user_db->setIndexBy('id');
                $user_ids = $user_db->select('col');
                if (!empty($user_ids) && !PHPWS_Error::logIfError($user_ids)) {
                    $group_db = new PHPWS_DB('users_groups');
                    foreach ($user_ids as $id => $username) {
                        $group_db->addWhere('user_id', $id);
                        $result = $group_db->select('row');
                        if (!$result) {
                            $group_db->reset();
                            $group_db->addValue('active', 1);
                            $group_db->addValue('name', $username);
                            $group_db->addValue('user_id', $id);
                            if (!PHPWS_Error::logIfError($group_db->insert())) {
                                $content[] = '--- Created missing group for user: '******'2.4.9 changes
-----------------
+ Raised sql character limit in default username, display_name, and
  group name installs.
+ Fixed bug with forbidden usernames
+ Added a function to group to remove its permissions upon deletion.
+ Bookmark won\'t return a user to a authkey page if their session dies.
+ Fixed bug #1850815 : unknown function itemIsAllowed in Permission.php
+ My Pages are unregistered on module removal.
+ My Page tab stays fixed.
</pre>';
        case version_compare($currentVersion, '2.5.0', '<'):
            $content[] = '<pre>';
            $files = array('templates/forms/memberlist.tpl', 'templates/forms/userForm.tpl', 'javascript/generate/head.js', 'templates/manager/groups.tpl', 'templates/manager/users.tpl');
            userUpdateFiles($files, $content);
            $content[] = '2.5.0 changes
-------------------
+ Members\' names alphabetized
+ New user email notification added.
+ Fixed member listing  dropping names past 10.
+ Added random password generator on user edit form.
+ Removed reference from Action.php causing php notice.
+ Changed redundant static method call in Permission.
+ Added dash to allowed display name characters.
+ Added \\pL to display name characters.
+ Users will now query modules should a user get deleted.
+ Added an error check to Permissions.
+ Users will now look for remove_user.php in all modules\' inc/
  directory in order to run the remove_user function.
+ Using pager\'s addSortHeaders in user and group listing
+ Added display name to pager search.
</pre>';
        case version_compare($currentVersion, '2.6.0', '<'):
            $content[] = '<pre>';
            Users_Permission::registerPermissions('users', $content);
            $db = new PHPWS_DB('users_auth_scripts');
            $db->addWhere('filename', 'local.php');
            $db->addColumn('id');
            $auth_id = $db->select('one');
            PHPWS_Settings::set('users', 'local_script', $auth_id);
            PHPWS_Settings::save('users');
            $files = array('conf/languages.php', 'templates/my_page/user_setting.tpl', 'templates/usermenus/css.tpl', 'img/permission.png', 'templates/forms/userForm.tpl');
            userUpdateFiles($files, $content);
            if (!PHPWS_Boost::inBranch()) {
                $content[] = file_get_contents(PHPWS_SOURCE_DIR . 'mod/users/boost/changes/2_6_0.txt');
            }
            $content[] = '</pre>';
        case version_compare($currentVersion, '2.6.1', '<'):
            $content[] = '<pre>2.6.1 changes
------------------
+ requireLogin now reroutes dependant on the user authorization
+ If the user\'s group is missing when they are updated, a new one is
  properly created. Prior to the fix, a new group was created without an
  assigned user id.
+ Added error message to my page if update goes bad.
</pre>';
        case version_compare($currentVersion, '2.6.2', '<'):
            $content[] = '<pre>';
            $files = array('templates/forms/settings.tpl');
            userUpdateFiles($files, $content);
            $content[] = '2.6.2 changes
------------------
+ Moved error file to inc/
+ Blank passwords forbidden.
+ Error check added to cosign authorization.
+ php fiveasized the classes.
+ Added some needed error logging to user creation problems
+ Added ability for default user groups to be set for admin created
  and newly joined users.
+ Fixed testing on addMembers. Previous code was nonsensical.
+ _user_group id gets set upon a user object save.
</pre>';
        case version_compare($currentVersion, '2.6.3', '<'):
            $content[] = '<pre>';
            $files = array('img/deity.gif', 'img/delete.png', 'img/edit.png', 'img/man.gif', 'img/key.png', 'img/members.png', 'templates/forms/authorization.tpl', 'templates/forms/settings.tpl', 'templates/manager/users.tpl');
            userUpdateFiles($files, $content);
            $db = new PHPWS_DB('users_auth_scripts');
            PHPWS_Error::logIfError($db->addTableColumn('default_group', 'int not null default 0'));
            $content[] = '2.6.3 changes
------------------
+ Added icons for admin options under manage users and groups
+ Disabled active link in groups listing
+ Authorization scripts now have default group assignments. New
  members will assigned to a group based on their authorization
  method.
+ Removed default group by user or admin from settings.
+ Added ability to view users by whether or not they are in a
  particular group.
+ Added pager caching to group listing
+ Display name may now not be the same as another user\'s username
+ Extended user name error to include display name
+ Added empty password check to ldap script
</pre>';
        case version_compare($currentVersion, '2.6.4', '<'):
            $db = new PHPWS_DB('users_auth_scripts');
            PHPWS_Error::logIfError($db->addTableColumn('default_group', 'int not null default 0'));
            $content[] = '<pre>2.6.4 changes
-------------------------
+ Added missing column to install.sql</pre>';
        case version_compare($currentVersion, '2.6.5', '<'):
            $content[] = '<pre>';
            userUpdateFiles(array('conf/languages.php'), $content);
            $content[] = '2.6.5 changes
-------------------------
+ Added missing column to install.sql</pre>';
        case version_compare($currentVersion, '2.6.6', '<'):
            $content[] = '<pre>';
            userUpdateFiles(array('templates/forms/userForm.tpl'), $content);
            $content[] = '2.6.6 changes
        -----------------------
+ Graceful recovery from broken authentication scripts.
+ Authorization script made deity only
+ Fixed default groups on external authentication
+ Deleted auth scripts will update users under it to use local instead.
+ The user constructor was trying to load the authorization script on
  failed users. Thanks Verdon.</pre>';
        case version_compare($currentVersion, '2.7.0', '<'):
            $content[] = '<pre>2.7.0 changes
-------------------------
+ Usernames and passwords can not be changed on non local users
+ Added switch to settings to prevent admins from making new users
+ Site admin can be set by non-deities again
+ Fixed bug with users able to change password on alternate auth.
+ Fixed some bugs with user creation and editing with alternate authentication.
+ Hiding permissions and members in create group form
+ Icon class implemented.
+ Strict PHP 5 changes made.
</pre>';
        case version_compare($currentVersion, '2.7.1', '<'):
            $content[] = '<pre>2.7.1 changes
-------------------------
+ Improved cosign script
+ Fixed errors getting dropped without logging.
</pre>';
        case version_compare($currentVersion, '2.7.2', '<'):
            $content[] = '<pre>2.7.2 changes
-------------------------
+ Fixed multiple group member bug.
+ Cleaned up cosign authentication.
+ Current_User requireLogin to use login_link instead of login_url
+ New User form now properly respects the "settings" permission for showing
  user authentication script option.
+ User constuction allow username parameter.
+ Trim whitespace from user email addresses. Don\'t modify the member variable
  unless all the sanity checks passed.
</pre>';
        case version_compare($currentVersion, '2.7.3', '<'):
            PHPWS_Core::initModClass('users', 'Action.php');
            User_Action::checkPermissionTables();
            $content[] = '<pre>2.7.3 changes
------------------------
+ Update permissions
</pre>';
        case version_compare($currentVersion, '2.7.4', '<'):
            $content[] = '<pre>2.7.4 changes
------------------------
+ Fixed 500 error on My Page
</pre>';
        case version_compare($currentVersion, '2.7.5', '<'):
            $content[] = '<pre>2.7.5 changes
------------------------
+ Loosened group name restrictions
+ User edit page shows group membership
</pre>';
        case version_compare($currentVersion, '2.7.6', '<'):
            $content[] = '<pre>2.7.6 changes
------------------------
+ Updated icons to Font Awesome
+ Email addresses may now be used as user names.
+ Static method call fixed.
+ Added exception error for missing authorization file.
+ My Page no longer is using tabs as other modules use of My Page have been removed.
+ css.tpl template rewritten. Login now works closer with authentication script.
    - drop down no longer contains Home or Control Panel. Account link added - takes
        user to their account page to change their password.
</pre>';
        case version_compare($currentVersion, '2.8.0', '<'):
            $content[] = <<<EOF
<pre>2.8.0 changes
-----------------
+ Added suggested bootstrap classes from TRF
+ Removed call to nonexistent method.
+ Moved icons to left and set admin-icons class to column.
+ Added FA icon here for mini admin
+ Changed to ensure users_auth_scripts table was created properly
+ Session timeouts are now tracked. Warning to user given before failure.
</pre>
EOF;
        case version_compare($currentVersion, '2.8.1', '<'):
            \PHPWS_Settings::set('users', 'session_warning', 0);
            \PHPWS_Settings::save('users');
            $content[] = <<<EOF
<pre>2.8.1 changes
-----------------
+ Changing default on user session to false. If you want it enabled, do so in settings.
</pre>
EOF;
        case version_compare($currentVersion, '2.8.2', '<'):
            $content[] = <<<EOF
<pre>2.8.2 changes
-----------------
+ Bug Fix: Unstyled permission pop up.
</pre>
EOF;
    }
    // End of switch statement
    return TRUE;
}