As I look back at the changelog for 4.0.12, I’m kind of surprised at how large this week’s update is. When you look across all the elements, you begin to see how the changes are related and that there is a pattern in the process.
This is reflective of my fundamental approach to coding, which is to limit work to given areas at any given time. Imagine you’re remodeling a bathroom. Let’s say you need to tear out some walls to update the plumbing. While you’re in there, you might as well check the electrical wiring. But just because you’re ripping out walls in a bathroom doesn’t mean you’re going to open up a wall in your living room to check wiring there.
I do this with coding. While there’s certainly a lot less drywall dust when I dig into an area of code to do some remodeling, I try to stay in one general area or one general context per project. I’ve found it’s a very productive way to code, reduces errors, and increases the chance I’ll complete according to my self-imposed deadlines.
4.0.12 update
In 4.0.12, I wanted to tackle a long-time architectural weakness in Seamless Donations: how funds and donations cross-indexed. Every donation can be assigned to both one donor and one fund. To do this in WordPress, an entry is dropped into the postmeta database to reflect that linkage.
Up until now, the entry that was dropped was the full name of the fund, and it was dropped only in the donation postmeta database. That meant you couldn’t — from a given fund, find out its donations. Instead, you’d have to scan all the donations and build a list. It also meant that if a single character in the fund name changed, everything would break.
What I did was add a dual-linking cross reference based on id, not name. Every donation with a fund got the id of the fund in its postmeta. Every fund got a list of the ids associated with its donations. This is how the relationship between donors and donations worked, but for some reason it wasn’t built into funds.
Doing this required some other supporting functions, including an updater routine that would provide these cross-references for all the databases out there where the cross-links didn’t exist. But since I was building a re-index function for funds, I decided to go ahead and build a re-index function for donors as well.
Both re-index functions are name-centric. What that means is that it looks for the name in the donation and connects it to the corresponding name in either funds or donors. This is good for now, as we rebuild indexes based on name. At some point, we might also want an id-centric rebuild function, to rebuild based on id.
I also built a running total data item in both donors and funds, so we can find out totals without having to iterate across tables for many objects. This data structure was accompanied by a recalculate function to keep the information up to date should there be any change to the associated donation data.
Since re-indexing cross-references might prove useful to users, I added an admin UI option to Debug Mode that can be triggered from the dashboard.
And, since I was in the funds code, I added something to funds that was long overdue: the ability to click into a fund and see all its donations.
Delete Monster
While I was digging around through the cross-referencing code, I realized this was an ideal time to create an add-on I hadn’t been planning to do for a while: Delete Monster. Fundamentally, Delete Monster simply lets you delete donation, fund, and donor records.
You might think that something as simple as a delete option ought to be part of the plugin’s core, and you might be right — for most plugins. But not for Seamless Donations.
This goes to the fundamental question of what should go into a freemium plugin’s core, and what should go into paid add-ons? There are both business considerations (which are less of a concern to me since I’m not building this as a business) and design considerations (which, as a code artist, I am very careful to consider).
For those in business to sell add-ons, the challenge is to make the core compelling enough to attract users, but not so useful that users don’t go out and spend on add-ons. It’s a valid model and I’ve certainly bought and licensed a bunch of freemium products and find the model quite beneficial as a consumer.
But the other issue is what belongs in core and what shouldn’t be included? In today’s update, clearly building in proper cross-referencing is a necessary architectural function of the core plugin. Likewise, having the ability to see donations associated with a fund should just be something you’re able to do, and since it was both available in the original adopted plugin and exists on the donor side, it’s really something that needs to be in the free plugin.
But deleting donation records? That opens a whole bunch of worm cans, not the least of which is whether commonly accepted accounting practices require special actions or management before deleting the records. There’s the potential to lose important data if a record is mistakenly deleted.
So, I decide to add some friction to the practice of deleting donations. Requiring payment for the function certainly will reduce the number of installations with it actively installed. I also built in a bunch of confirmation check marks so users have to confirm they understand the risks, and recorded a 13-minute tutorial going through all the details so users would be informed of how they should think about this.
The why, where, and when of how I code
This add-on takes us all the way back to the beginning of this lab note: why I code where I code when I code. As you might expect for the most popular donations plugin for WordPress, I get a tremendous number of requests for additional features in Seamless Donations. But since it’s a side project, I have to pick and choose the work I do to both fit into my available time and address important structural issues.
Because I’d already ripped apart all of the re-indexing code, an add-on that relies and modifies that particular set of data structures made sense this week. Next time I have some project time, I will again look at what core needs and deal with that first. If there is remaining time, I’ll see what add-on might be interesting to work on.
Who knows? Now that the fund data structure is considerably more robust, maybe there’s more love I can give to the fund management process.
Stay tuned.