Thursday, March 15, 2018

[PHP] Include a data structure once

Today's job at work was to get some data into GravityForms, a forms tool for WordPress.

So one page has a postcode entry, and the next page has some hidden postcode-specific fields that are used to calculate values later in the form-set, in this case freight costs on goods delivered by
TNT (no relation to the song by AC/DC).

The documentation for GravityForms suggests putting code into functions.php in the active theme. I'm a little wary of doing that given that changes there can work or not work in a rather catastrophic way.

Nevertheless, I ended up coding against the gform_field_input hook
add_filter('gform_field_input', 'update_hidden', 10, 5);
function update_hidden($input, $field, $value, $lead_id, $form_id)
{
}
So then the was the issue of how to include the postcode-to-charges array (PCA) (stored in an external php file) once rather than each time gform_field_input fired, which is once per control. With the PCA being just shy of a megabyte in length, I wasn't particularly interested in having it load repeatedly.

The PCA looks like this
<?php
return array(
 '0221' => array(
  'BasicChrg' => 9.982, 
  'KgChrg' => 0.5405, 
  'MinChrg' => 15.3755, 
  'RemotAreaChrg' => 0, 
  'ResidChrg' => 5, 
  '0to15Chrg' => 0, 
  '15to199Chrg' => 10, 
  '200to299Chrg' => 30, 
  '300to399Chrg' => 40, 
  '400to499Chrg' => 150, 
  '500to599Chrg' => 250, 
  '600plusChrg' => 300, 
  'FuelSurchrg' => 0.07)
  ...
);
StackOverflow did offer a suggestion on how to deal with this but I had no joy with it. So I went with using include_once. That, however, also had problems. According to the documentation, include_once returns a boolean true when it gets called the second time for the same file. So one must use a temporary variable to hold the result rather than committing it immediately to your PCA variable.

So the code I have ended up with is (some omitted for brevity's sake):
function update_hidden($input, $field, $value, $lead_id, $form_id)
{
 global $TNTFreightPrices, $PostCode;

 $path = $_SERVER['DOCUMENT_ROOT'] . '/wp-content/uploads/tntfreightprices/TNTFreightPrices.php';
 $tmp = include_once $path;
 if (gettype($tmp) == "array") {
  $TNTFreightPrices = $tmp;
  $PostCode = rgpost('input_52');
 }

 if ($form_id == 8) {
  $BasicChrg = $TNTFreightPrices[$PostCode]['BasicChrg'];
  
  ...

  $fid = $field['id'];
  
  if ($fid == 53) {
   $input = "<input id='input_8_53' class='gform_hidden' name='input_53' aria-invalid='false' value='$BasicChrg' type='hidden'>";
  }
  ...
 }
}
It remains to be seen whether I stay with $TNTFreightPrices and $PostCode in global space as that's a carryover from other experiments.

It was part fun and part hairloss but at least we're closer to a solution. Probably there are better ways. WooCommerce?


© Copyright Bruce M. Axtens., 2018