Dealing with Mods in TNG 10.1
TNG V10.1 introduced two important changes to the "inner workings" of TNG. Neither has significant impact on the features or appearance of TNG. They are:
- The underlying database was changed from MySQL to MySQLi (essentially just a new version of MySQL). All PHP code that references the databases had to be changed, though the changes were limited to new function names. That is, database structure and the logic of code didn't have to be changed. Still this meant that small changes were required throughout the released code - and throughout many TNG Mods.
- The Mod Manager was completely rewritten, with a few new features, and closer attention to existing Mod Manager syntax rules. As a result, many mods had to be changed in small ways to work with TNGv10.1.
This article is one of two TNG Wiki articles that describes how TNG mods had to be changed to deal with these two changes in TNG. This article focuses primarily on the changes to use SQLi. See Mod Manager gotchas for details on changes necessary to address the tighter syntax rules in the TNGv10.1 Mod Manager.
MySQLi Functions in TNGv10.1
The PHP language contains several built-in functions to invoke MySQL and/or MySQLi. In order to implement MySQLi with minimum impact on TNG code, TNG contains new PHP functions that are very similar to the MySQL calls, but that invoke MySQLi. The SQL statements themselves ("SELECT x FROM y...", "UPDATE Y SET X=1...", etc.) do not need to be changed; only the PHP functions that send SQL statements to the database and that deal with result sets need to be changed.
In particular,
- The built-in functions mysql_query, mysql_num_rows, mysql_fetch_assoc, mysql_free_result, mysql_affected_rows, mysql_insert_id, mysql_error, and mysql_errno that invoke MySQL have all been replaced by new user-defined functions that begin with tng_ rather than mysql_ and that invoke MySQLi.
- The TNG function dbExecuteQuery has been replaced by tng_query,
- The tng_db_connect function, which opens and connects to a specified database, has been replaced with a new function, tng_db_connect, that is called from code that is automatically included in TNG programs, and
- The error-handling (well, really, the failure message) associated with the built_in function mysql_query has been changed.
The new functions are all defined in the PHP module tngconnect.php, which is included in TNG applications automatically.
Updating TNG Mods for MySQLi
Mods that contain SQL function calls must be updated to use the new functions. You should execute the follow steps on mods that you know (or suspect) contain SQL functions
Scan and Replace mysql_
Mods that contain MySQL calls will need to be rewritten before they can work with the TNGv10.1. Some SQL queries will continue to work in TNGv10.1, even with the old SQL_ function calls, but some will generate error messages such as
Cannot execute query: SELECT count(living) FROM tng_people WHERE `living` = '1'
So even if you don't get these errors, you should scan your TNG mods with a text editor, and and replace mysql_ with tng_. Note that this process is not reversable. That is, several other TNG function names begin with tng_, so you cannot simply replace tng_ with mysql_ to return to MySQL.
The above approach is required for TNG programs that use the standard begin.php or tng_begin.php include files, and thus automatically call tng_connect to connect to the TNG database, since your connection is now through MySQLi.
Scan and Replace dbExecuteQuery
If a mod was using TNG queries that included
return dbExecuteQuery($query);
you should replace dbExecuteQuery with tng_query, like this:
return tng_query($query);
Remove tng_db_connect
If your mod or TNG addon previous called the function tng_db_connect - typically, like this:
tng_db_connect($database_host,$database_name,$database_username,$database_password) or exit;
you need to remove or comment out that instruction, since
- That function connects to a MySQL database, not MySQLi, and
- TNGv10.1 has moved the statement that connects to the database into a PHP file (begin.php) that is included in all TNG programs.
Few TNG mods are likely to contain calls to tng_db_connect, but some may, so you should look for it in your mods.
Remove "or die"
NOTE that the "or die" clause of a mysql_query call is NOT required with the new tng_query call, as the error condition is checked inside the new tng_query function. Leaving it will not have any adverse effect, but code will be tidier without it. So
$result6 = tng_query($query6) or die ("$text[cannotexecutequery]: $query6");
would become
$result6 = tng_query($query6);
Compatibility with earlier versions of TNG
Once you have made all the mysql_ to tng_ changes to use the new database functions in TNG 10.1, your mod will no longer work with earlier versions of TNG. If you want to make sure that your mod can be run in older versions of TNG as well as the new one, you use one of the following techniques:
Two Mods
Many mod developers provide two version of their mods - one for TNGv10.1 and beyond, and one for earlier versions. The newer version of the file will need to show 10.1.0 as the minimum TNG version number in the mod's Wiki page. Generally speaking, the two mods might be identical except for the tng_ vs mysql_ database calls.
If you want to implement changes to a mod that has two versions, you would need either to
- Let the older version lag behind, without the new features, or
- Make all changes to both versions of the mod.
One Mod With Conditional Functions
Your mod could add conditional function definitions that would come into play in older TNG environments where the new tng_ database functions have not been defined. For instance, for tng_query, you could add this code:
// Does function tng_query() exist? (i.e are we running TNGv10.1 or above)
if (!function_exists('tng_query')) {
// No, it doesn't, so create a new function that calls the old mysql_query function
function tng_query($x) {
return mysql_query($x);
} //End of function definition
} //End if
With this conditional function definition in place,
- If you are in a pre-TNGv10.1 environment, tng_query will not be defined when the above if statement is executed. Thus a function that simply calls mysql_query will be defined, and that function will be called when the program subsequently encounters a call to tng_query.
- If you are in TNGv10.1 or later, tng_query WILL be defined when the above if statement is executed. Thus, the new function will not be defined, and subsequent calls to tng_query will invoke the function defined in TNGv10.1.
You could add this PHP code (which lacks the explanatory comments and multiple lines of the code above) to conditionally defined most of the tng_ database functions you might ever need.
// For Backwards compatibility with pre TNG 10.1 installations
if (!function_exists('tng_query' )){ function tng_query($x) {return mysql_query($x); } }
if (!function_exists('tng_num_rows' )){ function tng_num_rows($x) {return mysql_num_rows($x); } }
if (!function_exists('tng_fetch_assoc' )){ function tng_fetch_assoc($x) {return mysql_fetch_assoc($x); } }
if (!function_exists('tng_free_result' )){ function tng_free_result($x) {return mysql_free_result($x); } }
if (!function_exists('tng_affected_rows')){ function tng_affected_rows() {return mysql_affected_rows(); } } // No parameters
if (!function_exists('tng_insert_id' )){ function tng_insert_id() {return mysql_insert_id(); } } // No parameters
if (!function_exists('tng_error' )){ function tng_error() {return mysql_error(); } } // No parameters
if (!function_exists('tng_errno' )){ function tng_errno() {return mysql_errno(); } } // No parameters
NOTE: This may not be a complete set of functions. You need to do this for each and every tng_ / mysql_ database your code uses.
Note that, if more than one mod uses this same technique within one program, this block of code would be duplicated, but that's ok, since, once the first set of definitions are executed, the functions will exist, and all of the if statements in the second block will fail.
Since PHP function statements are global in scope, even if these statements are executed deep inside an Include file, or even another function, the new tng_ definitions will be available across the entire program. You just need to make sure they are in a spot that gets executed before any of your tng_ functions are called.
See the Event Map Add Children mod for an example of this technique: File:Event map add children v10.0.0.1.zip
Update User Pages
With the TNG 10.1 upgrade to use MySQLi
tng_db_connect($database_host,$database_name,$database_username,$database_password)
in user created files that were created using the historytemplate.php from prior versions.
At a minimum, you will need to update your user created pages to comment out that statement. If you also use MySQL queries in those pages then you also need to take the actions to replace mysql_ with tng_ in those files.
The new %wikipage% Mod Manager directive
An updated Mod Manager will also be provided in TNG 10.1.0 which adds a new %wikipage: keyword that links to the TNG Wiki page for your mod. The argument for the %wikipage:% directive is the Wiki article name. So as you update mods for TNG 10.1 (or create new ones), you should add the following mod statement after the %description:% statement
%wikipage:Census_Plus_International%
In the new Mod Manager, in the list of your mods, all mods with %wikipage% values will show this icon: . If you click on the icon for the %wikipage:% definition just above, you will be taken to
http://tng.lythgoes.net/wiki/index.php?title=Census_Plus_International