reCaptcha plugin for Movable Type 7

I’ve installed the reCaptcha plugin for Movable Type for spam control.

Unfortunately, when using dynamic publishing, I got a helpful error:

An error occurs.

I enabled debug logging, and got something a little more helpful:

Error: Class 'BaseCaptchaProvider' not found
#0 /var/www/spd.ltd/mt/php/mt.php(228): require_once()
#1 /var/www/spd.ltd/mt/php/mt.php(213): MT->load_plugin('/var/www/spd.lt...')
#2 /var/www/spd.ltd/mt/addons/DynamicMTML.pack/php/dynamicmtml.run.php(237): MT->init_plugins()
#3 /var/www/spd.ltd/mt/addons/DynamicMTML.pack/php/init.dynamicmtml.php(132): require_once('/var/www/spd.lt...')
#4 /var/www/spd.ltd/mt/php/mt.php(228): require_once('/var/www/spd.lt...')
#5 /var/www/spd.ltd/mt/php/mt.php(213): MT->load_plugin('/var/www/spd.lt...')
#6 /var/www/spd.ltd/mt/php/mt.php(511): MT->init_plugins()
#7 /var/www/spd.ltd/arme-test/mtview.php(5): MT->view()
#8 {main}

But, I could find nothing in the Movable Type source to suggest there was ever a BaseCaptchaProvider class.

I scoured the web and the best I could find was this page. Two problems: (a) it’s in Japanese, and (b) it’s no longer available. It’s not even in the Wayback Machine.

Google had a cached copy though, which provided the following insight:

However, when MT-5 became MT-5, the BaseCaptchaProvider of virtual class was discontinued, and captchaProvider was defined as a method instead. Therefore, in an MT-5 environment, when using DynamicHTML.pack and reCaptcha, the init.reCaptcha.php function needs to be modified as follows.

- class reCaptcha extends BaseCaptchaProvider {
+ class reCaptcha implements CaptchaProvider {

This is only a problem when used in a DynamicHTML.pack environment, and if you are only using static HTML, the PHP module will not be called, so this problem will not become apparent. In short, it might be such a thing that there is no person who uses it by such a combination.

Once I made that change, dynamic rendering started working. Until I had to render a reCaptcha. On comment pages, I got another error:

Error: Undefined captcha provider. (sixapart_rc)
#0 /var/www/spd.ltd/mt/php/lib/function.mtcaptchafields.php(18): CaptchaFactory::get_provider('sixapart_rc')
#1 /var/www/spd.ltd/mt/php/lib/MTViewer.php(1036): smarty_function_mtcaptchafields(Array, Object(MTViewer))
#2 /var/www/spd.ltd/mt/php/extlib/smarty/libs/sysplugins/smarty_resource_recompiled.php(52) : eval()'d code(213): MTViewer->function_wrapper(Array, Object(Smarty_Internal_Template))

This was resolved by calling the CaptchaFactory instantiation of $_captcha_providers:

- $_captcha_providers[$provider->get_key()] = $provider;
+ CaptchaFactory::$_captcha_providers[$provider->get_key()] = $provider;

Update 15 May 2021: No need to change this as of Movable Type 7.7 / r.4901.

That gave me a further error:

Error: Cannot access protected property MT::$db
#0 /var/www/spd.ltd/mt/php/lib/function.mtcaptchafields.php(20): reCaptcha->form_fields(1)
#1 /var/www/spd.ltd/mt/php/lib/MTViewer.php(1036): smarty_function_mtcaptchafields(Array, Object(MTViewer))
#2 /var/www/spd.ltd/mt/php/extlib/smarty/libs/sysplugins/smarty_resource_recompiled.php(52) : eval()'d code(213): MTViewer->function_wrapper(Array, Object(Smarty_Internal_Template))
#3 /var/www/spd.ltd/mt/php/extlib/smarty/libs/sysplugins/smarty_template_resource_base.php(128): content_605887c6b1dde8_14729443(Object(Smarty_Internal_Template))

I resolved this in form_fields():

- $config = $mt->db->fetch_plugin_config('reCaptcha', 'blog:' . $blog_id);
+ $config = $mt->db()->fetch_plugin_config('reCaptcha', 'blog:' . $blog_id);

And now the reCaptcha widget renders correctly.