Blog

Cryptocurrency payments

Recently I accepted a cryptocurrency payment. I did it mostly to learn the process, advantages and pitfalls first hand. The process was straightforward, although it did require getting a digital wallet and setting up an only crypto account. I chose Exodus for my wallet and BlockFi as my broker.

I’m still evaluating the extent to which I want to accept crypto payments. Cryptocurrencies have certain advantages. For example, for certain international customers, it’s a relatively easy way to pay me or perhaps the only way to pay me, although certain countries like China restrict cryptocurrencies. Assuming the value of the cryptocurrency rises, it can also be something of an investment. I got a 25% return on the bitcoin I was paid in over one month. Of course cryptocurrency prices can vary widely over short time periods, so it’s just as easy to lose 25% in one of these currencies over a given month too.

They also have certain downsides. You can’t buy much with cryptocurrencies, so to spend the “money”, you have to sell it in your local currency and move it into a traditional bank account. Also, the price of cryptocurrencies can fluctuate wildly over time. A currency of value doesn’t fluctuate that much over time, which is why I’ve only accepted U.S. dollars until recently. So to my mind these cryptocurrencies that exist outside of regulation and are subject to supply and demand really aren’t currencies.

The client paid me in bitcoin. bitcoin is a “dirty” currency in that it requires a lot of electricity to create new bitcoins. It’s estimated the electricity used just in creating bitcoin is equal to the electricity consumed by the Netherlands. Most of this electricity comes from carbon-burning power sources, contributing to climate change and global warming.

Consequently, if I accept payment in cryptocurrencies in the future, it’s going to be in more environmentally benign and relatively stable cryptocurrencies. Right now, ethereum qualifies.

My services will still be priced in U.S. dollars. You would have to pay me the equivalent in ethereum. But I do want to be clear that I don’t want to be paid in ethereum or any digital currency. If you can pay me in U.S. dollars, that’s what I prefer. In some cases though not accepting ethereum would be unprofitable, so I will make exceptions.

Assuming I accept cryptocurrencies for work I do for you, I will provide an address you can use to pay me at the appropriate time.

July 2021 work summary

I kept plenty busy in July. Like most months for the last year or so, much of my work was focused around one commercial client.

Our main accomplishment this month was finally finishing up a custom OAuth interface to phpBB. The interface ties into many aspects of the business including a shop and accounting system with many points of entry all of which had to work consistently and reliably.

You may be familiar with OAuth if you go to sites where you can login with Google, Yahoo or other major web sites. OAuth allow for an external service to authorize your access on a different site through a complex exchange of codes and tokens. phpBB supports only three OAuth services natively: Google, Facebook and Bitly.

The client’s backend OAuth system is definitely a “roll your own” service so it required lots of low level integration challenges. I’ve learned plenty about OAuth in the process, enough to realize that it’s challenging, very low level and not for the faint of heart.

Toward the end of July we buttoned up we hope the last of the code changes needed but discovered a new area: mobile device display, that had been overlooked. So I am now deep into more styling work, which is where I started the project back in March 2020. Once this is done we should finally be at a code complete event, and the work will go into formal testing.

At this point I’m probably 80% of the way through the project, which has been challenging but very profitable. Working with one of their lead developers has been a great and at times humbling experience.

Here’s a summary of work I did for other clients in July:

  • Additional effort for a client I did work for in June. The main issue seems to be slow to nonexistent serving of ads on the view topics page, likely because more than two ads are served on the page. Doubleclick seems to be blocking the serving these ads. I suggested he needs to contact them to find out why this is happening. I also reviewed all enabled extensions for the database changes they made. With the exception of the YouTube videos extension, all appeared in order. I had to add auto increment to the primary keys of three tables created by extensions in use.
  • I updated a board from phpBB 3.3.3 to phpBB 3.3.4, principally to address the reCaptcha V3 bug fixed in version 3.3.4. I reapplied the logo.
  • I upgraded a board from phpBB 3.0.14 to phpBB 3.3.4. I installed the Milk style and placed the old logo. I added the American English language pack and disabled the contact form. I set up reCaptcha V3 spambot countermeasure. I also changed PHP to version 7.4. Client will need to play with Milk style control panel to fine tune its theme and look. Smooth upgrade, no issues. Later, the client had additional work. He had retired a number of users. When this happens and you retain the posts, the old username becomes a guest username but the original account goes away. Reassigned a guest’s posts whose account was deleted to a new account with their name. Also since guests can’t see any forums, I opened the forum in the visitors category to read-only access, so the “this board has no forums” message no longer came up for guests.
  • Did a system check as user was having spam and other issues. I recommended upgrade to phpBB 3.3.4 to be able to use reCaptcha V3. I had a number of other recommendations summarized in an email. I was authorized to update phpBB to 3.3.4 so I did that, along with addressing all the other issues including setting up automatic https, reCaptcha V3, disabling the contact form, creating a custom style, deleted orphaned attachments and inactive users. Later, I did additional work to fix a number of outstanding issues related to having the code originally in yaBB (a Perl-based forum solution popular in the late 1990s). I fixed an avatar issue where the URL was bad and pointed to the old domain. I then had to write a throw away program to make posts with [img] tags in the post text store properly in the database post_text column, which has a different format. This took a lot of trial and error. Later, moved it over by exporting it and tediously correcting syntax errors in the exported SQL that caused it not to import. Later, I changed another deleted user posts to assign it to them rather than Anonymous.
  • Hosting issue: database user for board’s forums lost INSERT and DELETE privileges to the database. Worked with NS support to resolve the issue. After a lot of back and forth we eventually figured out that some automatic process was revoking these privileges for the database user when they exceed their database quota of 1 gigabyte. This didn’t appear to be a problem because when I ran a query to determine its size, it was about 600mb. I “solved” the problem by truncating the search tables, so the built in board search is no longer available. The hosting is Network Solutions which I don’t recommend. There were multiple calls, temporary work arounds and lots of intermediate staff to tediously deal with to get the level of support needed, then they wanted to charge the user for their support! If you are running out of database quota, a good host will at least give you a warning so your system doesn’t abruptly come crashing down. Not only does Network Solutions not do this, we had to figure out the underlying problem ourselves to solve the problem.
  • I updated a board from phpBB 3.3.2 to phpBB 3.3.4. I also updated the stop forum spam extension to version 1.4.0. I added a self-renewing (and free) Let’s Encrypt certificate and set up automatic redirect of http to http, changing the server settings in phpBB. I had to change the client’s php.ini to set UTF-8 as the default character set to get rid of an error on the ACP general page after the update.
  • For another commercial client I performed a few troubleshooting tasks. I troubleshooted an issue with the board rules extension, which apparently only supports the prosilver style. To get it to work with five other styles on the board, I had to place the extension’s prosilver style changes into folders in the extension’s style folder each with the name of the style. Helped with a renewal of a SSL certificate, a paid certificate, which wasn’t needed because I had earlier installed free Let’s Encrypt certificates for the site, so it was mainly a matter of canceling the bill for the renewed certificate. Locked two posts as requested. Added a person to the administrator’s group and provided instructions on how to add new users using the ACP Add user extension.
  • Updated a board from phpBB from 3.3.3 to phpBB 3.3.4 and the Multi Design style to version 1.1.7.

My book is back for sale on Amazon

Having experimented with putting my Mastering phpBB Administration book on Lulu.com, the book is now back for sale on Amazon.com and I retired it from Lulu.com. You can buy the paper book (338 pages) for $19.99 here. Note it’s also for sale as a Kindle eBook for $9.99 here. Links are also in the sidebar ad and appended to every page and post. This version is fresh and covers up through phpBB 3.3.4.

The eBook is enhanced as I took the time to convert it to an ePub format which allowed me to do things like fix issues with some embedded screenshots and create a usable linked table of contents. Amazon converted the ePub version to its proprietary Kindle version, so only the Kindle version is available as an eBook.

I moved it from lulu.com because after months of trying to update the eBook format and getting no support from their support team, I realized they just didn’t care enough to fix the issue, plus I couldn’t offer the eBook with new content. I’m no fan of Amazon, but at least their publishing process is reliable if a bit cryptic.

Digests 3.3.5 released

Notes on the release are here. In particular note that:

  • phpBB 3.3 only is supported
  • Only the British English language pack is included in the archive. See the README for links to other translations.
  • Tested on PHP 8.0

It can be downloaded from my digests extension page or the branch’s page on GitHub. If downloaded from GitHub make sure to follow the procedures for disabling the digests first and replacing the files correctly. From GitHub, place the files in the /ext/phpbbservices/digests folder.

June 2021 work summary

Work in June kept me pretty busy.

As with most months since the start of the pandemic, one primary client occupied a lot of my time: 42.5 hours for this commercial client. Working with a key developer, we continued work on a custom OAuth extension. The extension ties into the client’s authentication system. I’ve learned much more about OAuth as a result than I ever expected (or wanted) to learn.

At the start of the month we concentrated on feature that when you sign out of phpBB you are also signed out of the site’s authentication system using OAuth methods. In addition a handshake was needed so that if a user was removed in the authentication system, the user was also automatically removed in phpBB. A method was also needed to ban the user on a signal from the authentication system, either permanently or for a fixed period. In the process there was some code clean up and centralizing of common logic into a common extension, called as needed by other extensions.

Toward the end of the month we worked on the issue of logging in indirectly, such as by logging into the accounting system first then going to the link to the forum and logging in automatically. It was all pretty confusing and hair tearing at times but we eventually got it to work. So most of the custom OAuth work is now done with some tweaks remaining, mainly to intelligently handle logging into the ACP by checking OAuth for proper authorization. Hopefully that will be figured out in July.

In work for other clients in June:

  • Upgraded a board from phpBB 3.2.7 to 3.3.4. I made changes to the Black custom style to bring its theme and templates compliant with similar prosilver style changes since phpBB 3.2.1. Upgraded these extensions: Advanced BBCode Box, Cleantalk, Media Embed, Tapatalk and Thanks for the Posts. The last one required entering two configuration variables to enable it, and to change the extension’s name to all lowercase. Changed the reCaptcha spambot countermeasure to V3. Tested all extensions and they seem to work okay. Two other styles installed were not upgraded because I was unsure if that was still used. As a result the Quick Style extension interface to pick a style did not appear. Later, I updated the prosilver_se and narruto styles to work wth phpBB 3.3.4 as well, applying small customizations that were there previously. This also let the Quick Style extension work.
  • Completed project started in April. The project was basically to change a calendar extension that will work for version 3.3 of phpBB. Previously a phpBB 3.0 mod was used. In April I deployed it to a test environment for feedback and refinement. In June I was finally given permission to replicate the changes to the production board. I first upgraded the test forum from phpBB 3.3.3 to 3.3.4, fixing the logo again. I then upgraded the production forum from phpBB 3.0.12 to phpBB 3.3.4 copying files on the test forum to save time and effort. There were no issues during database upgrade. I set up reCaptcha V3 as the spambot countermeasure. I then installed various calendar extensions and configured them to work as they did on the test board, created a test forum with the privilege and verified calendar showed up on navigation bar. I disabled the contact page and removed two errant old calendar modules.
  • Upgraded a board from phpBB 3.2.7 to phpBB 3.3.4. I reapplied the logo to the prosilver style. I upgraded the following extensions: Board rules, Stop forum spam, Pages, Notify admin on registration and Who visited this topic. I changed the Captcha to reCaptcha V2 invisible — reCaptcha V3 would not work. There was an HTTP 500 error after enabling Who visited this topic extension, but seemed transient and works fine. I changed PHP changed from version 7.2 to 7.3.
  • A client’s old board got hacked and backup was not available, so I created a new board replicating as best I could the look of the old board. Created the board in subdomain as the domain contained a WordPress site. Installed the Latte style, then created a custom style based on it. Incorporated old logo into it, with minor styling changes. Changed the username for the admin account. Set up forums requested. Set up default email address. Gave the client both administrator and founder privileges so he could take over the remaining configuration. Later, I did more styling to the navigation bar that the user later rejected. Even later, I worked on a WordPress issue for the client. He was getting emails for bogus WordPress user registrations. I installed the Google Captcha plug in and configured the plug in’s reCaptcha V3 keys using keys I set up for the board.
  • Wrote a small extension for a commercial client that enabled a user email notification for private message notifications by default when a user registers on the board, in this case via the ACP Add User extension, so it occurs automatically via that process. In addition, wrote a SQL query to create this notification for users who did not already have it set. I blogged about this here.
  • I helped troubleshoot some strange issues after a board was moved from a folder to the web root. Client could login but not into the ACP. Nonstandard German characters were part of the URL, which added some mystery, but also had only FTP and later phpMyAdmin to work with. Redirection was part of the issue. That gave client a clue on what the real issue was. He talked to his web host and they eventually solved the redirection issue. Charged an hour of my time.
  • Upgraded a board from phpBB 3.0.10 to phpBB 3.3.4. This was instigated by the web host (Hostgator) dropping PHP 5, which forced the issue when PHP errors subsequently occurred. I moved the board with 89,000 posts from one domain to another on same hosting. I installed the IDLaunch_Fresh style first, then created custom style inheriting from it to closely model the IDLaunch_Black style previously used but which was not available for phpBB 3.3. I disabled the contact page, set up a reCaptcha V3 spambot countermeasure, and created a home link. Added and integrated the old logo into the header.
  • A client wanted guests not to see attachments but to see the post text, but that’s not possible. I installed additional smilies. Initially changed the footer to include links to social media sites, but it turned out he wanted to share posts and topics, so I installed the ShareOn extension. I also changed the styling on the background image logo. It no longer sizes down proportionately, but the unused space below the logo no longer appears as screen width decreases.
  • A board with dozens of extensions was having issues running slowly. The immediate problem was an error when a user registered. Inspecting the database, I realized the issue was that the user_id in the phpbb_users table was not set for auto increment, so I changed that. A number of other tables had a similar issue, likely a result of moving the database around where the import did not totally finish. I compared his phpBB 3.2.2 database with a reference phpBB 3.2 database. By comparing the columns and their attributes, as well as the indexes with a reference, I was able to fix what was missing, which included some missing columns and lots of tables missing the necessary indexes. No surprise then that the board was running slowly since without an index a database management system will read files sequentially. I did more work today for this client that will go into the July report looking at other slowness issues. One unusual thing about this job was that he wanted to pay with cryptocurrency. I’ve been leery of accepting it but it would have been days or weeks to get paid in U.S. dollars otherwise. So I made an exception and went through the hassle of setting up a digital wallet, and got paid in bitcoin! (If I have to accept crypto, it’s likely to be ethereum next time, because unlike bitcoin is doesn’t use a lot of power to mine new coins.)

More in the July report.

Writing trivial extensions is not too hard

A client recently sought me out. A board user wanted to get email notifications when receiving private messages. These are disabled by default but can be enabled. Most users though won’t dig through the User Control Panel to find the setting: UCP > Board preferences > Edit notification options > Someone sends you a private message > Email.

The client wanted all his board users to have this enabled by default. Not one to ever reinvent the wheel, I searched for an extension. I found this one, in release candidate status, which allows an administrator to tweak notifications for a user on a case by case basis. But that didn’t meet the requirement.

I wasn’t sure how this setting was stored in the database. I did some experimentation by turning it on and off and looking in the phpbb_user_notifications table using phpMyAdmin. This provided a clue on what to do.

Private message email notification setting for user in the database

Essentially if I could add rows like this to this table, I’d effect the change needed. There were two aspects to this:

  • Ensure existing users has this setting set
  • Ensure that new users had this setting applied automatically with registration

If you know Structured Query Language (SQL) pretty well, it wasn’t that hard to figure out the SQL needed to ensure existing users who didn’t have this setting applied had it applied. This amounted to adding rows to the phpbb_user_notifications table for those who didn’t have a row for this permission already. The SQL was little complex but based on what I learned from testing in phpMyAdmin, straightforward and turned out to be:

INSERT INTO phpbb_user_notifications
SELECT ‘notification.type.pm’, 0, user_id, ‘notification.method.email’, 1
FROM phpbb_users
WHERE user_id not in
(SELECT user_id FROM phpbb_user_notifications WHERE item_type = ‘notification.type.pm’ and method = ‘notification.method.email’)
AND user_type = 0;

Having it work automatically with new registrations though was more complicated. Initially I didn’t consider the idea of writing a phpBB extension to do this. Rather, I proposed writing a SQL trigger to do this instead. But then I realized writing an extension would probably not be that big a deal and would have the advantage that if the user was deleted, phpBB’s code would delete these user notifications at the same time.

Writing extensions for phpBB is complex the first few times you try, as I discovered. The phpBB Group has this Wiki you can read to see if you can get your head around it. You need to be able to program in PHP but really you also generally need related web stills in HTML, CSS and Javascript too.

The more extensions I write though, the more I realize a lot of rather simple functionality can be done with rather trivial extensions. There is a skeleton extension you can install that will generate a lot of boilerplate code that makes it relatively easy to add the specialized functionality you need. I placed this on my test board and simply filled out the fields needed. Once installed a link appears on the navigation bar. The most baffling part for new extension authors is figuring out which components to check. Much of this comes from experience, but hovering over the component with your mouse helps explain that the component will do for you.

phpBB Skeleton extension interface

In this case, all I really needed was to check the PHP event listener and service checkboxes. This was for a client so it was not for general release, so I didn’t need to worry about database migrations. I didn’t need to add any Administration Control Panel user interface. It was to happen behind the scenes. When the form is submitted it creates a nice .zip file which can be decompressed and uploaded to your development environment. I enabled the extension.

What I needed to do was to add some logic during user registration. But where? And how? phpBB is all open source, so it’s a matter of reading the code. If you read the code, you realize that at some point the function user_add in /includes/functions_user.php is called and it does the grunt work of adding new users to lots of tables.

Inspecting the user_add function I found inside it a number of events that could be hooked into by my extension. I found the core.user_add_after event at the bottom of the function that looked like it would work. Essentially, after phpBB does all the normal stuff to create a user, you can have it do extra work. The event documentation shows:

/**
* Modify the notifications data to be inserted in the database when a user is added
*
* @event core.user_add_modify_notifications_data
* @var array    user_row            Array of user details submitted to user_add
* @var array    cp_data             Array of Custom profile fields submitted to user_add
* @var array    sql_ary             Array of data to be inserted when a user is added
* @var array    notifications_data  Array of notification data to be inserted when a user is added
* @since 3.2.2-RC1
*/
$vars = array('user_row', 'cp_data', 'sql_ary', 'notifications_data');
extract($phpbb_dispatcher->trigger_event('core.user_add_modify_notifications_data', compact($vars)));

The skeleton extension I used created a main_listener.php program in the /event folder where you can hook in code for events like these. To insert a row into the phpbb_users table, I would need to know the user_id that was created. The event passes a user_row array, so it seemed likely the user_id would be inside of it.

Since I was going to access the database, I needed main_listener.php to be able to use phpBB’s database abstraction layer service. So first I went into the /config/services.yml file for the extension and added this service. This was straightforward. Since I didn’t need to use the language service, I removed the language service too. The file became:

services:
phpbbservices.setemailpmnotifications.listener:
class: phpbbservices\setemailpmnotifications\event\main_listener
arguments:
- '@dbal.conn'
tags:
- { name: event.listener }

Next, to hook the database abstraction layer service into main_listener.php. I removed any references to the language service first, then hooked in the database service. The main_listener class looked in part like this:

public static function getSubscribedEvents()
{
   return [
      'core.user_add_after'           => 'user_add_enable_pm_email_notifications'
   ];
}

/* @var \phpbb\db\driver\factory */
protected $db;

/**
 * Constructor
 *
 * @param \phpbb\language\language $language  Language object
 */
public function __construct(\phpbb\db\driver\factory $db)
{
   $this->db     = $db;
}

The getSubscribedEvents function is where you hook in a custom function to an event, the core.user_add_after event in this case. I told phpBB to look for and execute a function in the program, user_add_enable_pm_email_notifications. Further down in main_listener.php I added a small amount of custom code to do what I wanted done inside this function:

public function user_add_enable_pm_email_notifications($vars)
{
$user_id = $vars['user_id'];
$sql = 'INSERT INTO ' . USER_NOTIFICATIONS_TABLE . "(item_type, item_id, user_id, method, notify)
VALUES ('notification.type.pm', 0, " . (int) $user_id . ", 'notification.method.email', 1)";
$this->db->sql_query($sql);
}

The incoming $vars variable contains a collection of stuff that can be read by my event. It turned out that $vars[‘user_id’] contained the user_id for the next user. Then, based on what I saw in the phpbb_user_notifications table, the SQL INSERT statement became straightforward to write and execute.

I think this demonstrates pretty well how a reasonably experienced web programmer can make a small custom extension to add some missing minor functionality that the phpBB Group did not think was needed.