SMF 2.0 on PHP 7.2

I recently changed my server from CentOS 6 to CentOS 7 and in the process decided that to avoid having to upgrade everything later, installing PHP 7.2 before migrating the sites would be a better option than staying with the default PHP 5.4.

This was a good idea – mostly. It forced me to upgrade a couple of mediawiki installs that hadn’t been touched in a while and those were migrated ok. When it came to migrating the Shartak Forum I was starting to think I should have gone for a slightly older version of PHP because SMF 1.1 (Simple Machines Forum) doesn’t work on such a recent version of PHP. It wasn’t just a minor issue, functions such as mysql_* that had been removed in PHP 7 were all over the place!

Time to take the plunge and upgrade to SMF 2.0 which had been stable for several years but there had never been a reason to upgrade before now. Looking at the large amount of spam user accounts and the upgrade process documentation, I decided it would be easier to start from scratch instead of trying to upgrade SMF 1.1 (with some custom tweaks) to 2.0.

I installed the SMF 2.0 code, configured the theme, found that only one of the old tweaks was really still needed and put it live. Then I checked the error logs in the SMF admin panel and found there were thousands of errors after just a few hours of it being live!

Function create_function() is deprecated

It turned out that SMF 2.0.15 only supports up to PHP 7.1 as PHP 7.2 is deprecating create_function() and this is used by the BBCode parser.

After some searching, I came across a message on the SMF forum that suggested adding an exception to the error handler to prevent it logging the deprecation warnings. The suggestion of comparing the version using the builtin PHP method version_compare() was taken into account and here is my version of the solution.

--- Sources/Errors.orig.php 2018-05-23 14:21:57.933367060 +0100
+++ Sources/Errors.php 2018-05-23 13:47:45.711567251 +0100
@@ -203,6 +203,10 @@
 {
 global $settings, $modSettings, $db_show_debug;

+ // Disable PHP 7.2 "Function create_function() is deprecated" errors from filling the forum error logs
+ if (defined('E_DEPRECATED') && $error_level == E_DEPRECATED && (version_compare(phpversion(), '7.2') >= 0) && strpos($error_string, 'Function create_function() is deprecated') !== false)
+ return;
+
 // Ignore errors if we're ignoring them or they are strict notices from PHP 5 (which cannot be solved without breaking PHP 4.)
 if (error_reporting() == 0 || (defined('E_STRICT') && $error_level == E_STRICT && (empty($modSettings['enableErrorLogging']) || $modSettings['enableErrorLogging'] != 2)))
 return;

It’s not a perfect fix but it’ll do until SMF 2.1 is released. I hope this helps someone else searching for the same issue.

Installing DBD::mysql on Mavericks

3 years ago, I posted about getting DBD::mysql to build on OSX 10.6 – it seems the same thing works on Mavericks (10.9) as well!

#   Failed test 'use DBD::mysql;'
#   at t/00base.t line 18.
#     Tried to use 'DBD::mysql'.
#     Error:  Can't load '/Users/simon/.cpan/build/DBD-mysql-4.027-wbgMWL/blib/arch/auto/DBD/mysql/mysql.bundle' for module DBD::mysql: dlopen(/Users/simon/.cpan/build/DBD-mysql-4.027-wbgMWL/blib/arch/auto/DBD/mysql/mysql.bundle, 2): Library not loaded: libmysqlclient.18.dylib
#   Referenced from: /Users/simon/.cpan/build/DBD-mysql-4.027-wbgMWL/blib/arch/auto/DBD/mysql/mysql.bundle
#   Reason: image not found at /System/Library/Perl/5.16/darwin-thread-multi-2level/DynaLoader.pm line 194.
#  at (eval 7) line 2.

The version of MySQL has changed slightly (and hence the path used) but everything else is the same.

$ sudo install_name_tool -id /usr/local/mysql-5.5.30-osx10.6-x86_64/lib/libmysqlclient.18.dylib /usr/local/mysql-5.5.30-osx10.6-x86_64/lib/libmysqlclient.18.dylib

$ otool -D `mdfind libmysqlclient.18.dylib`

cpan2rpm for CentOS 6.5

I’ve been attempting to build all the dependencies for Dancer on CentOS 6.5 and things just kept going wrong. Several of the modules complained about needing perl >= 5.006 even though CentOS 6.5 comes with Perl 5.10.

[mockbuild@build6 ~]$ cpan2rpm Test::Simple

-- cpan2rpm - Ver: 2.028 --
Upgrade check
Fetch: HTTP

-- module: Test::Simple --
Found: Test-Simple-1.001002.tar.gz
At: http://search.cpan.org//CPAN/authors/id/R/RJ/RJBS
Retrieving URL
Metadata retrieval
Tarball extraction: [/home/mockbuild/rpmbuild/SOURCES/Test-Simple-1.001002.tar.gz]
Unable to build module, the following dependencies have failed:
  perl >= 5.006
Stopped at /usr/local/bin/cpan2rpm line 491.

Despite there not being a newer version of cpan2rpm than 2.028 obviously available, there is a development version 2.028_02 which makes it compatible with Perl 5.10.  You have to download it directly from CPAN at http://search.cpan.org/CPAN/authors/id/B/BB/BBB/cpan2rpm-2.028_02.tar.gz and then use cpan2rpm to build it!

[mockbuild@build6 ~]$ cpan2rpm --no-prfx --no-sign ./cpan2rpm-2.028_02.tar.gz

Once it’s built the new cpan2rpm rpm, install it using yum localinstall which will remove the old version at the same time. This new version is able to build the packages for more up to date versions of Test::Simple and URI.

Update: Test::Simple builds but doesn’t pass all the tests, URI is ok.

DBIx::Class default column value

Having read the docs for DBIx::Class::Row new() and DBIx::Class::ResultSource add_columns() it’s hard to know whether it’s better to (a) override new() for the Result module and set a default value in the method params, or (b) use default_value in the add_columns method and set the default within the database itself.

After some investigation, (b) requires fetching the row after creating it just in case there’s a default value being added by the database. Since I already had a custom new() method to validate one of the parameters anyway, I decided to go for option (a) and add a simple check to new()

$args->{ column_name } = $default unless exists $args->{ column_name };

DBD::mysql, MySQL and OS X Lion

I downloaded and installed MySQL Community Server 5.5.15 from http://dev.mysql.com/downloads/mysql/5.5.html

Using CPAN, I then tried to install DBD::mysql on a fresh install of OS X Lion and was presented with an error saying it was unable to load the library.

#     Error:  Can’t load ‘/private/var/root/.cpan/build/DBD-mysql-4.019-H1RD6j/blib/arch/auto/DBD/mysql/mysql.bundle’ for module DBD::mysql: dlopen(/private/var/root/.cpan/build/DBD-mysql-4.019-H1RD6j/blib/arch/auto/DBD/mysql/mysql.bundle, 2): Library not loaded: libmysqlclient.18.dylib
#   Referenced from: /private/var/root/.cpan/build/DBD-mysql-4.019-H1RD6j/blib/arch/auto/DBD/mysql/mysql.bundle

Continue reading

Shartak internals – speech and translation

Within Shartak there are two main factions – natives and outsiders. To make things somewhat realistic (and interesting), when they first start off there is quite a hefty language barrier in that a native can’t really understand an outsider and vice-versa. This situation can be improved by gaining the various language skills that help with reading/hearing the other language, and then for writing or speaking the other language.

There are three levels of comprehension – basic, advanced and expert language – followed by foreign writing and foreign speech. As far as the translation of language goes, we’re only interested in the first three skills. The foreign writing/speech skills simply allow things to work in reverse.

One of the players posted the results of a fairly detailed examination of the translation system on the Shartak forum and he was quite accurate with a some of the information. It’s not possible to accurately translate the garbled text back into the original text – this is intentional because otherwise it would only be a matter of time before someone wrote a Greasemonkey script to translate it and thus render 5 skills completely useless.

Both native and outsider speech work in the same way, all that changes are the character sequences associated with each letter. The sequences were deliberately chosen (with assistance from someone who knows about such things) such that the outsiders have a less harsh sound than the natives.

Natives have sounds like kam, rak, hok and uck where outsiders have kar, rar, hum and uh.

Trivia: the name of the cannibals home camp Rakmogak is actually a slight variation of the native translation of “Raw meat”!

Shartak internals – Maps and movement

The map for Shartak is held in a database table with over 140,000 rows in it. Each row corresponds to a single location on the map, also called a tile. The initial island map was generated automatically based on a simple bitmap image with varying colours for the different terrain types. Since 2005 there have been many changes to it, most of which are done by manually editing the table one row at a time. Bear in mind that this system is probably not the best way to do it, but it works for Shartak and allows for some interesting map layouts if I ever need them.

Continue reading

IPv6 and Shartak

Over the last couple of weeks I’ve been trying to figure out IPv6. Having worked through some of the IPv6 certification at http://ipv6.he.net/ I now have an IPv6 enabled web server and mail server as well as IPv6 connectivity at home via tunnelbroker.net

I thought I’d update Shartak to allow access via IPv6 as well as IPv4 – mostly nothing needed to be changed, however…

Continue reading

Merging two hashrefs in Perl

I came across an interesting and very simple way to merge the contents of two hashrefs today. A hash is made up of pairs – a key and a corresponding value. As an example, the following can be pasted into a shell session on most machines that have perl installed.
perl -MData::Dumper -le ‘
$x = { a => 1, b => 2 };
$y = { c => 3, d => 4 };
$x = { %$x, %$y };
print Dumper($x);

Continue reading