File/program/lib/updatelib.php

Description

/program/lib/updatelib.php - update wizard

This file handles all system updates. The basic idea is as follows.

We assume that a previous version of Website@School is/was already correctly installed using the code in /program/install.php. Using this version the school has added many, many hours of work in entering data.

Now a new version is installed, i.e. the new files (or just the updated files) are copied/uploaded to the webserver, including the file version.php and perhaps also updated versions of modules, themes, etc. This yields an error message for visitors (the infamous 'error 050') because the database version and the file version no longer match. The user logging in into admin.php is forced to attend to the job 'update', arriving here in job_update().

There an overview is presented of the core version and versions of all subsystems, with the option to upgrade those that qualify. The actual work for the core version is done in update_core() in this file. The actual work for modules and themes are done via the code in those subsystems. However, these are called from here.

The user is more or less _forced_ to perform the upgrade: all ways lead to job_upgrade() while the internal (database) version does not match the file version.

The upgrade should perform all necessary steps to upgrade, ending with updating the internal version number to match the file version. After that the error message '050' for visitors is gone, and admin.php no longer forces the user to come here. It is possible, however, to manually arrive here to check the updates of modules, themes, etc. but I consider that less importent. That is: an upgrade of a module or theme will NOT be forced upon the user. It is wise, though to upgrade, but that is up to the user.

Constants
TASK_INSTALL_LANGUAGE = install_language (line 66)
TASK_INSTALL_MODULE = install_module (line 69)
TASK_INSTALL_THEME = install_theme (line 72)
TASK_UPDATE_CORE = core (line 64)
TASK_UPDATE_LANGUAGE = update_language (line 67)
TASK_UPDATE_MODULE = update_module (line 70)
TASK_UPDATE_OVERVIEW = overview (line 63)
TASK_UPDATE_THEME = update_theme (line 73)
Functions
get_manifests (line 1042)

retrieve an array of manifests for modules, themes or languages

this examines the file system starting in the directory $path, looking for manifest files. These manifest files are named after the subdirectory they are in as follows. Example: If $path is /program/modules, this routine steps through that directory and may find subdirectories 'htmlpage', 'guestbook' and 'forum'. Eventually these manfest files are include()'d: /program/modules/htmlpage/htmlpage_manifest.php, /program/modules/guestbook/guestbook_manifest.php and /program/modules/forum/forum_manifest.php.

Every manifest file must describe the module (or language or theme) via the following construct:

    $manifests['htmlpage'] = array('name' => 'htmlpage', ...., 'cron_interval' => 0);

After processing all the subdirectories of $path, the resulting array $manifests is returned. Note that pseudo-directories like '.' and '..' are not considered. Also, subdirectories 'foo' without the file 'foo_manifest.php' are also ignored.

Note that the name of the manifest file itself is also stored in the array, but excluding the subdirectory name.

Note: a similar routine is used in the installation script install.php.

  • return: zero or more arrays comprising manifests
array get_manifests (string $path)
  • string $path: top directory for the search for manifest files
install_language (line 347)

install an additional language pack

this routine attempts to insert the information from the manifest of language $language_key into the database. The routine displays the result (error or success) in a message in $output. Details can be found in the logs.

The language_key is validated by reading all existing manifests. This is quite expensive, but that is not important because we do not use this routine very often anyway.

Note that we assume that the actual translations of the language pack are already unpacked into the correct directories. The corresponding manifest should exist in the directory /program/languages/$language_key.

  • return: results are returned as output in $output
void install_language (object &$output,  $language_key, string $lanuage_key)
  • object &$output: collects the html output
  • string $lanuage_key: primary key for language record in database AND name of the /program/languages subdirectory
  • $language_key
install_module (line 479)

install an additional module

this routine attempts to insert the information from the manifest of module $module_key into the database. The routine displays the result (error or success) in a message in $output. Details can be found in the logs.

The module_key is validated by reading all existing module manifests. This is quite expensive, but that is not important because we do not use this routine very often anyway.

Note that we assume that the actual modules are already unpacked into the correct directories. The corresponding manifest should exist in the directory /program/modules/$module_key.

  • return: results are returned as output in $output
  • todo: we should refactor and combine install_theme() and install_module()
  • uses: $CFG
void install_module (object &$output, string $module_key)
  • object &$output: collects the html output
  • string $module_key: primary key for module record in database AND name of the /program/modules subdirectory
install_theme (line 699)

install an additional theme

this routine attempts to insert the information from the manifest of theme $theme_key into the database. The routine displays the result (error or success) in a message in $output. Details can be found in the logs.

The theme_key is validated by reading all existing module manifests. This is quite expensive, but that is not important because we do not use this routine very often anyway.

Note that we assume that the actual thenes are already unpacked into the correct directories. The corresponding manifest should exist in the directory /program/themes/$theme_key.

  • return: results are returned as output in $output
  • todo: we should refactor and combine install_theme() and install_module()
  • uses: $CFG
void install_theme (object &$output, string $theme_key)
  • object &$output: collects the html output
  • string $theme_key: primary key for theme record in database AND name of the /program/themes subdirectory
job_update (line 103)

main entry point for update wizard (called from /program/main_admin.php)

This routine takes care of executing update routines for both the core program and modules, themes, etc. It is called automagically whenever the core program version in the database is different from the version in the file {@lnk version.php} (see also main_admin()).

It can also be called manually via 'job=update'. When no specific task is specified, this routine shows the overview of versions for core, modules, themes, etc. Whenever a component is NOT up to date, an [Update] button is displayed. If a component IS up to date, we simply display the word 'OK'. This implies that when everything is up to date, the overview simply displays a list of OK's and the user is 'free to go'.

The actual updates for modules, themes, etc. is done via the various subsystems themselves, e.g. by calling htmlpage_upgrade() in the file /program/modules/htmlpage/htmlpage_install.php. The updates for the core program are actually performed from this file right here, see below for an example.

Note that we give a core update high priority: if the core is not up to date, nothing will work, except updating the core.

  • return: results are returned as output in $output
void job_update (object &$output)
  • object &$output: collects the html output
update_core (line 894)

update the core version in the database to the version in the version.php file (the 'manifest' version)

  • return: results are returned as output in $output
void update_core (object &$output)
  • object &$output: collects the html output
update_core_2010120800 (line 1100)

perform actual update to version 2010120800

  • return: TRUE on success, FALSE otherwise
bool update_core_2010120800 (object &$output)
  • object &$output: collects the html output
update_core_2010122100 (line 1118)

perform actual update to version 2010122100

  • return: TRUE on success, FALSE otherwise
bool update_core_2010122100 (object &$output)
  • object &$output: collects the html output
update_core_2011020100 (line 1136)

perform actual update to version 2011020100

  • return: TRUE on success, FALSE otherwise
bool update_core_2011020100 (object &$output)
  • object &$output: collects the html output
update_core_2011051100 (line 1199)

perform actual update to version 2011051100

this is a substantial change in the database: we (finally) standardise on UTF-8 including the database. Up until now we still only have a choice of exactly one database driver: MySQL. Therefore the upgrade we do here can be more or less MySQL-specific. (So much for database-independency).

What needs to be done here?

The most important task (in fact: the only task) is to change the collation (and implicitly the default charset) to utf8_unicode_ci (4.1.x <= MySQL < 5.5.2) or utf8mb4_unicode_ci (MySQL 5.5.3+). See mysql.class.php for more information on these UTF-8 & MySQL issues.

Strategy here is as follows.

    for all 'our' tables (ie. "LIKE '{$prefix}%'" do    if table default charset is already utf8 (or utf8mb4)        continue;    for appropriate columns in this table        change column type to binary        change column type back to non-binary with correct charset and collation    if no trouble sofar        change default charset/collation of the table too    else        return failure return success

This way we _might_ be able to work our way through huge tables: if the PHP max processing time kicks in, we can rerun the upgrade and start (again) with the table we had in our hands the previous time. I don't expect this to happen, but it still the way to do it IMHO.

Note that I assume that I cannot change the default charset of the DATABASE for the same reason the Installation Wizard expects the database to be ready before installation commences. (I cannot be sure that I have the privilege to execute 'ALTER DATABASE $db_name DEFAULT CHARSET utf8 COLLATE utf8_unicode_ci').

A useful reference for solving this problem of converting to utf8 can be found here: http://codex.wordpress.org/Converting_Database_Character_Sets.

In the case of W@S we do not have to deal with enum-fields because those are not used at this time. In fact it boils down to changing char, varchar, text and longtext.

Let goforit...

  • return: TRUE on success, FALSE otherwise
bool update_core_2011051100 (object &$output)
  • object &$output: collects the html output
update_core_version (line 949)

record the specified version number in the config table AND in $CFG->version

This utility routine records the new version number in the config table and also adjusts the version number already in core (in $CFG->version).

  • return: TRUE on success, FALSE otherwise
bool update_core_version (object &$output, int $version)
  • object &$output: collects the html output
  • int $version: the new version number to store in config table
update_create_tables (line 1067)

create tables in database via include()'ing a file with tabledefs

  • return: TRUE on success, FALSE otherwise + messages written to logger
  • uses: $DB
bool update_create_tables (string $filename)
  • string $filename: contains the table definitions
update_language (line 410)

update a language in the database

this routine tries to update the information in the database with the information in the language manifest of the selected language $language_key. The event is logged via logger().

Note that an upgrade of a language is not at all interesting because there is nothing to do except to update the data in the databse with that from the manifest. However, we still do it this way in order for the user to grow accustomed to it so we can complexicate this routine in the future without the user having to learn new tricks.

  • return: results are returned as output in $output
void update_language (object &$output,  $language_key, string $lanuage_key)
  • object &$output: collects the html output
  • string $lanuage_key: primary key for language record in database AND name of the /program/languages subdirectory
  • $language_key
update_module (line 590)

call the module-specific upgrade routine

this routine tries to execute the correct upgrade script/function for module $module_key. If all goes well, a success message is written to $output (and the update is performed), otherwise an error message is written to $output Either way the event is logged via logger().

Note that we take care not to load spurious files and execute non-existing functions. However, at some point we do have to have some trust in the file system...

  • return: results are returned as output in $output
void update_module (object &$output, string $module_key)
  • object &$output: collects the html output
  • string $module_key: unique secondary key for module record in modules table in database
update_show_overview (line 170)

display an introductory text for update + status overview

  • return: results are returned as output in $output
void update_show_overview (object &$output)
  • object &$output: collects the html output
update_status_anchor (line 924)

return an anchor tag with link to the specific update function

This utility routine returns a ready to user HTML anchor tag.

  • return: ready to use HTML-code
array update_status_anchor ([string $task = NULL], [string||null $key = NULL], [string $anchor = NULL])
  • string $task: which update task do we need to do?
  • string||null $key: which module/theme/etc. (NULL for core)
  • string $anchor: text to show in link
update_status_table_close (line 1006)

close the status overview HTML-table we opened before

this is the companion routine for update_status_table_open(); it closes the open HTML-table

  • return: results are returned as output in $output
void update_status_table_close (object &$output)
  • object &$output: collects the html output
update_status_table_open (line 980)

open a status overview HTML-table including column headers

this routine opens an HTML-table in prepration for a status overview of the system or a subsystem (languages, modules, themes). The optional title is used as the header of the first column.

The width of the first column is 25% and the remaining 5 columns area 15% each which creates an orderly display of name, internal version, external version, releasedate, release and status.

  • return: results are returned as output in $output
void update_status_table_open (object &$output, [string $title = ''])
  • object &$output: collects the html output
  • string $title: is the header of the first column
update_theme (line 805)

call the theme-specific upgrade routine

this routine tries to execute the correct upgrade script/function for theme $theme_id. If all goes well, a success message is written to $output (and the update is performed), otherwise an error message is written to $output Either way the event is logged via logger().

Note that we take care not to load spurious files and execute non-existing functions. However, at some point we do have to have some trust in the file system...

  • return: results are returned as output in $output
void update_theme (object &$output, string $theme_key)
  • object &$output: collects the html output
  • string $theme_key: unique secondary key for theme record in themes table in database

Documentation generated on Wed, 11 May 2011 23:45:41 +0200 by phpDocumentor 1.4.0