blainehansen

Skiracing Paywall and Reporting Tool

The user paywall and reporting tool needed to be fixed and improved for the skiracing.com team.

published: December 3, 2016 - last updated: May 13, 2024

The Skiracing.com team uses a Leaky Paywall tool in order to monetize their content while allowing it to be searchable and shareable. This is obviously a business critical system for them, and when I was originally brought on in January of 2016, one of the first important tasks I was given was to discover why the paywall and wasn't working at all.

The largest problem I detected in the paywall plugin was in a bug in its "test mode" feature. The system allowed for a "test mode" versus a "live mode", and user data was saved differently depending on which one the plugin was in. However, the checks within the paywall that determined which mode it was in were incorrect, and always placed certain portions in test mode regardless of what the settings database indicated. So although some paywall functionality was in live mode, other parts were in test mode. This was fairly easy to solve, by correcting the logic.

Originally, the plugin was using an incredibly un-DRY method of performing a check on the settings variable every single time it was needed. This of course was an incredibly brittle method prone to update breaks.

$mode = 'off' === $settings['test_mode'] ? 'live' : 'test';

I created two functions encapsulating this behavior, and replaced them everywhere needed.

function is_in_test_mode() {
	$settings = get_leaky_paywall_settings();
	$test_mode = $settings['test_mode'];
	if ($test_mode === 'on' || $test_mode === TRUE) {
		return TRUE;
	}
	else {
		return FALSE;
	}
}

function test_mode_string() {
	return is_in_test_mode() ? 'test' : 'live';
}

You'll notice that although the original check was simply performing a truthy test on the $settings['test_mode'] variable, the value in the database actually resolved to 'on' or 'off'. This caused the truthy test to pass regardless of which value it was.

Several other custom portions of the paywall had also not considered the test versus live functionality, and I fixed those wherever necessary.

§ Fixing and Improving the Reporting Tool

Their paywall also comes with several add-on plugins that can improve it's abilities. One such add-on is a reporting tool, allowing csv reports of users fitting certain filters to be downloaded.

In the reporting tool, the first problem was simply that although the plugin authors had created an updated version with improved features, they had forgotten to rename some of the files in the plugin manifest file. This caused the entire tool to simply not work. It was a truly foolish and unprofessional mistake which I easily fixed.

The team needed the reporting tool to be more intuitive. At the time, in order to query users by their account's status (current or expired), which is computed based on the user's expiration date database value, the team member had to enter the current date as the end date in an "Expiration Range" input in the Reporting Tool form. This was an irritating amount of thinking and work for something that should have been simple, so I added two checkboxes to the interface.

<tr>
	<th><?php _e( 'Account is Current', 'lp-reporting-tool' ); ?></th>
	<td>
		<input type="checkbox" id="account-current" name="account-current" value="1" />
	</td>
</tr>
<tr>
	<th><?php _e( 'Account is Expired', 'lp-reporting-tool' ); ?></th>
	<td>
		<input type="checkbox" id="account-expired" name="account-expired" value="1" />
	</td>
</tr>

A little bit of jQuery ensured that the form values couldn't conflict with each other or with the existing expiration date range inputs.

$('#account-current').change(function() {
	if (this.checked) {
		$('#expire-start').val('');
		$('#expire-end').val('');
		$('#account-expired').prop('checked', false);
	}
});

$('#account-expired').change(function() {
	if (this.checked) {
		$('#expire-start').val('');
		$('#expire-end').val('');
		$('#account-current').prop('checked', false);
	}
});

$('#expire-start, #expire-end').change(function() {
	if ($('#expire-start').val() || $('#expire-end').val()) {
		$('#account-current').prop('checked', false);
		$('#account-expired').prop('checked', false);
	}
});

And modifying the php query to reflect these changes completed the task.

if ( !empty( $post['account-current'] ) ) {
	$args['meta_query'][] = array(
		'key'     => '_issuem_leaky_paywall_' . $mode . '_expires',
		'value'   => date( 'Y-m-d' ),
		'type'    => 'DATE',
		'compare' => '>='
	);
	$thereAreParameters = TRUE;
}

if ( !empty( $post['account-expired'] ) ) {
	$args['meta_query'][] = array(
		'key'     => '_issuem_leaky_paywall_' . $mode . '_expires',
		'value'   => date( 'Y-m-d' ),
		'type'    => 'DATE',
		'compare' => '<'
	);
	$thereAreParameters = TRUE;
}

These kind of bugs and poor design choices are unfortunately endemic in the wordpress development community. Since php is such an established language with a short learning curve and little in the way of standards and patterns enforcement, and wordpress such a widespread system with many easy employment opportunities available, it encourages sloppy code by inexperienced developers.

Sometimes all a project like this needs is someone like me to come along and actually get it working.

Want to hear from me in the future?

Usual fine print, I won't spam you or sell your info.
Thank you! Come again.