1. Spend time reading the coding guidelines here: http://area51.phpbb.com/docs/coding-guidelines.html . Those guidelines not only have a few tips (some of which I'll repeat here) but also tell you the proper code layout (things like the number of spaces per tab, indentation of sql statements, etc.).
2. Spend time reading this wiki entry here: http://olympuswiki.naderman.de/Main_Page . That's pretty undeveloped so far but I suspect over time it will grow.
3. Try to keep the changes you make to core phpbb3 files to a minimum. For example, instead of editing phpbb3's language files, consider adding a new file in language/en/mods that would look like this:
Code: Select all
<?php
/**
* DO NOT CHANGE
*/
if (empty($lang) || !is_array($lang))
{
$lang = array();
}
$lang = array_merge($lang, array(
'SAMPLE_MOD_PHRASE' => 'This is a sample of text in a modlanguage file',
'ANOTHER_SAMPLE' => 'Here's another sample of some text in a mod language file',
));
?>
Code: Select all
$user->add_lang('mods/[name_of_mod]').
Code: Select all
$user->add_lang(array('mods/mod1', 'mods/mod2', 'mods/mod3'));
Code: Select all
include($phpbb_root_path . 'includes/functions_[name_of_mod].' . $phpEx);
include($phpbb_root_path . 'includes/constants_[name_of_mod].' . $phpEx);
5. Be very careful not to use formulations like if ($variable) if you are not sure that $variable has been set, because phpbb3 will run at a higher error reporting level than phpbb2. Instead, use if (isset($variable)) or if (!empty($variable)).
6. To find out if a variable has been passed in the address or in a hidden field in a template, use this formulation rather than the old $http_post_vars and $http_get_vars formulation:
Code: Select all
$submit = (isset($_POST['submit']) || isset($_GET['submit'])) ? true : false;
7. To actually use a variable (rather than simply finding out if it is passed), use the new function request_var. The function request_var takes three main arguments; the first argument is the name of the variable you are checking for, the second argument gives the default if nothing is there (and also by example tells request_var the 'type' of variable, e.g. integer, string, array of integers, array of strings, etc.) and the third argument specifies whether the input characters are multibyte. Here's how to use request_var in some simple situations (most of which are borrowed from the coding guidelines referred to above):
Code: Select all
// if start is an integer (defaults to 0):
$start = request_var('start', 0);
// if name is a string (defaults to ''):
$name = request_var('name', '', true);
// if mark is an array where the keys are integers (each element defaults to 0)
$mark_array = request_var('mark', array(0));
// if action is an array where the keys are strings (each element defaults to 0)
$action_ary = request_var('action', array('' => 0));
8. If you use request_var to get text that will be stored in the database, run the result through a function called utf8_normalize_nfc. For example, you will find this in posting.php:
Code: Select all
$message = utf8_normalize_nfc(request_var('message', '', true));
9. Although request_var forces user input that is supposed to be an integer to be an integer and forces any user input that is supposed to be a string to be run through htmlspecialchars(), it does not deal with the injection risk posed by single quotes. To deal with those, any strings inputed from user forms that will be used in any database query should be escaped like this:
Code: Select all
$db->sql_escape(utf8_normalize_nfc(request_var('message', '', true)));
Code: Select all
$sql = 'SELECT *
FROM ' . SOME_TABLE . "
WHERE username = '" . $db->sql_escape($username) . "'";
Code: Select all
$sql = 'SELECT *
FROM ' . SOME_TABLE . "
WHERE username = '" . $db->sql_escape(utf8_normalize_nfc(request_var('username', '', true))) . "'";
Code: Select all
$sql_ary = array(
'message' => utf8_normalize_nfc(request_var('message', '', true)),
'subject' => utf8_normalize_nfc(request_var('subject', '', true)),
);
$sql = 'INSERT INTO ' . YOUR_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_escape():
$db->sql_query_limit():
$db->sql_build_array():
$db->sql_in_set():
$db->sql_build_query():
A word about $db->sql_in_set(): the coding guidelnes say: "The $db->sql_in_set() function should be used for building IN () and NOT IN () constructs" and gives as an example:
Code: Select all
$sql = 'SELECT *
FROM ' . FORUMS_TABLE . '
WHERE ' . $db->sql_in_set('forum_id', $forum_ids);
$db->sql_query($sql);
- Even though mysql actually needs a comma separated list for its IN feature, the second parameter of sql_in_set ($forum_ids in the above example) needs to be an array (the function then changes the array to a comma separated list usable by mysql program). That is actually pretty useful, but if you are converting old code that uses IN you will need to keep in mind that you should now use an array that you feed into that function.
- The way to build NOT IN is to add a third parameter 'true'. If you look at the comments for the function in dbal.php you will see that they have it backwards (the way the function is written you should use 'true' if you want NOT IN but the function comment says the opposite).
10. Instead of message_die, use trigger_error. Here are three examples borrowed from the coding guidlines:
Code: Select all
trigger_error('NO_FORUM');
trigger_error($user->lang['NO_FORUM']);
trigger_error('NO_APPROPRIATE_MODE', E_USER_ERROR);
11. The templates now have an .html extension rather than a .tpl extension. They use conditional statements like 'if' (fabulous!). And you no longer need to assign any language file entries to the templates via the relevant php page; instead, if you have an entry like {L_XYZ} in a template, the parser will automatically look at the language files that were called in the relevant php page and if there is an 'XYZ' entry then that entry gets automatically picked up in the template (very cool). You can also include files within templates (which can be other templates or even php files). Take a look at the coding guidelines for more details on these subjects and for other noteworthy things about the new template system.
That's all for now...but please feel free to correct anything I have said that is wrong and to supplement it so that we can start to create a real resource for modding authors.