function pugpig_subs_test_form($title, $urls, $params, $test_users, $helptext = "")
{
    if (isset($urls["base"])) {
        $urls["sign_in"] = $urls["base"] . "sign_in";
        $urls["verify_subscription"] = $urls["base"] . "verify_subscription";
        $urls["edition_credentials"] = $urls["base"] . "edition_credentials";
    }
    $vals = array();
    $params[] = "product_id";
    foreach ($params as $param) {
        if (isset($_REQUEST[$param])) {
            $vals[$param] = $_REQUEST[$param];
        }
    }
    if (empty($vals['product_id'])) {
        $vals['product_id'] = "com.pugpig.test.issue12345";
    }
    $product_id = $vals['product_id'];
    $authToken = null;
    $error = '';
    $issues = array();
    echo <<<EOT
    <style>
       form {border: 1px solid grey; padding: 2px; margin: 2px;}
      .pugpig_active { color: green;}
      .pugpig_inactive { color: orange;}
      .pugpig_stale { color: gray;}
      .pugpig_unknown { color: red;}
      .testusers { -webkit-column-count: 4; }
    </style>
EOT;
    echo "<h2>Pugpig Authentication Test Console - {$title}</h2>\n";
    if (!empty($helptext)) {
        echo "<p><em>{$helptext}</em></p>";
    }
    echo "Supplied test users:\n<ul class='testusers'>\n";
    foreach ($test_users as $test_user) {
        $state = strtolower($test_user['state']);
        unset($test_user['state']);
        $p = array();
        $p["product_id"] = $product_id;
        // We need this to retain the position on WordPress
        if (isset($_REQUEST["page"])) {
            $p["page"] = $_REQUEST["page"];
        }
        $query_params = http_build_query(array_merge($test_user, $p));
        $description = implode(", ", $test_user);
        echo "<li><b class='pugpig_{$state}'>{$description}</b> - <a href='?{$query_params}'>Test</a></li>\n";
    }
    echo "</ul>\n";
    echo "<form method='GET'>\n";
    // Need to WordPress settings pages
    if (isset($_REQUEST["page"])) {
        echo "<input type='hidden' name='page' value='" . $_REQUEST["page"] . "' />\n";
    }
    echo "Enter test values:<br />\n";
    foreach ($params as $param) {
        if (isset($vals[$param])) {
            $val = $vals[$param];
        } else {
            $val = '';
        }
        echo "{$param}: <input id='{$param}' name='{$param}' type='text' value='{$val}' /> \n";
    }
    echo "<br /><input type='submit' />\n";
    echo "</form>\n";
    // We will always have product_id. Need at least one more.
    echo "<p>Using <em><a href='" . $urls["sign_in"] . "'>" . $urls["sign_in"] . "</a></em><br />\n";
    echo "Using <em><a href='" . $urls["verify_subscription"] . "'>" . $urls["verify_subscription"] . "</a></em><br />\n";
    echo "Using <em><a href='" . $urls["edition_credentials"] . "'>" . $urls["edition_credentials"] . "</a></em></p>\n";
    if (count($vals) > 1) {
        unset($vals['product_id']);
        $sep = strpos($urls["sign_in"], "?") ? "&" : "?";
        $sign_in_req = $urls["sign_in"] . $sep . http_build_query($vals);
        $http_status = pugpig_subs_http_request($sign_in_req, $sign_in_response);
        $status = "unknown";
        if ($http_status != 200) {
            echo "<b class='pugpig_unknown'>SIGN IN ERROR: Status {$http_status}</b><br />\n";
        } else {
            $token = pugpig_subs_get_single_xpath_value("/token", $sign_in_response);
            // Backup format to support the Dovetail response format
            if (empty($token)) {
                $token = pugpig_subs_get_single_xpath_value("/result_response/authToken", $sign_in_response);
            }
            if (!empty($token)) {
                echo "Auth Token: <b class='pugpig_active'>{$token}</b><br />\n";
                $query_vars = array("token" => $token);
                $sep = strpos($urls["verify_subscription"], "?") ? "&" : "?";
                $verify_subscription_req = $urls["verify_subscription"] . $sep . http_build_query($query_vars);
                $query_vars['product_id'] = $product_id;
                $sep = strpos($urls["edition_credentials"], "?") ? "&" : "?";
                $edition_creds_req = $urls["edition_credentials"] . $sep . http_build_query($query_vars);
                $http_status = pugpig_subs_http_request($verify_subscription_req, $verify_subscription_response);
                if ($http_status != 200) {
                    echo "<b class='pugpig_unknown'>VERIFY SUBSCRIPTION ERROR: Status {$http_status}</b><br />\n";
                } else {
                    $message = pugpig_subs_get_single_xpath_value("/subscription/@message", $verify_subscription_response);
                    $status = pugpig_subs_get_single_xpath_value("/subscription/@state", $verify_subscription_response);
                    $issues_exists = pugpug_subs_get_xpath_value("/subscription/issues", $verify_subscription_response);
                    $issues = pugpug_subs_get_xpath_value("/subscription/issues/issue", $verify_subscription_response);
                    if (empty($status)) {
                        echo "Status: <b class='pugpig_unknown'>Got a 200, but did not get back the expected response</b><br />\n";
                    } else {
                        echo "Status: <b class='pugpig_{$status}'>{$status}</b><br />\n";
                        if (!empty($message)) {
                            echo "Message: <b class='pugpig_{$status}'>{$message}</b><br />\n";
                        }
                        if ($issues_exists == '' || $issues_exists->length == 0) {
                            echo "<b>You have access to all issues</b><br />\n";
                        } else {
                            if ($issues->length == 0) {
                                echo "<b>You do not have access to any issues</b><br />\n";
                            } else {
                                echo "<b>You have access to " . $issues->length . " issues</b><br />\n";
                                echo "<ul>\n";
                                foreach ($issues as $issue) {
                                    echo "<li>" . $issue->textContent . "</li>\n";
                                }
                                echo "</ul>\n";
                            }
                        }
                    }
                }
                $http_status = pugpig_subs_http_request($edition_creds_req, $edition_creds_response);
                if ($http_status != 200) {
                    echo "<b class='pugpig_unknown'>EDITION CREDENTIALS ERROR: Status {$http_status}</b>\n";
                } else {
                    $userid = pugpig_subs_get_single_xpath_value("/credentials/userid", $edition_creds_response);
                    $password = pugpig_subs_get_single_xpath_value("/credentials/password", $edition_creds_response);
                    if (!empty($userid) && !empty($password)) {
                        echo "Got credentials for <b class='pugpig_active'>{$product_id}</b>\n";
                    } else {
                        $status = pugpig_subs_get_single_xpath_value("/credentials/error/@status", $edition_creds_response);
                        $message = pugpig_subs_get_single_xpath_value("/credentials/error/@message", $edition_creds_response);
                        echo "Denied credentials for <b class='pugpig_unknown'>{$product_id}</b> (status: <b class='unknown'>{$status}</b>)<br />\n";
                        if (!empty($message)) {
                            echo "Message: <b class='pugpig_unknown'>{$message}</b><br />\n";
                        }
                    }
                }
            } else {
                echo "Credentials not recognised - did not get a token<br />\n";
            }
        }
        echo "<h3 class='pugpig_{$status}'>All done</h3><br />\n";
        if (!empty($sign_in_req)) {
            echo "<a href='{$sign_in_req}'>Raw Sign In</a><br />\n";
            echo "<hr />" . htmlspecialchars($sign_in_response) . "<hr />\n";
        }
        if (!empty($verify_subscription_req)) {
            echo "<a href='{$verify_subscription_req}'>Verify Subscription</a><br />\n";
            echo "<hr />" . htmlspecialchars($verify_subscription_response) . "<hr />\n";
        }
        if (!empty($edition_creds_req)) {
            echo "<a href='{$edition_creds_req}'>Edition Credentials</a><br />\n";
            echo "<hr />" . htmlspecialchars($edition_creds_response) . "<hr />\n";
        }
    }
    print_r("<br /><em style='font-size:small'>Test Form Version: " . pugpig_get_standalone_version() . " </em><br />");
}
function pugpig_subs_test_form($title, $urls, $params, $test_users, $helptext = "", $use_http_post = false, $default_product_id = 'com.pugpig.edition0100')
{
    if (!headers_sent()) {
        header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    }
    if (isset($urls["base"])) {
        $urls["sign_in"] = $urls["base"] . "sign_in";
        $urls["verify_subscription"] = $urls["base"] . "verify_subscription";
        $urls["edition_credentials"] = $urls["base"] . "edition_credentials";
        // sign_out needs to be set explicitly to be enabled
    }
    $vals = array();
    $user_format = '';
    foreach ($params as $param) {
        if (!empty($user_format)) {
            $user_format .= ', ';
        }
        $user_format .= '<strong>' . $param . '</strong>';
    }
    $params[] = "product_id";
    foreach ($params as $param) {
        if (isset($_REQUEST[$param])) {
            $vals[$param] = htmlspecialchars($_REQUEST[$param]);
        }
    }
    if (empty($vals['product_id'])) {
        $vals['product_id'] = $default_product_id;
    }
    $product_id = $vals['product_id'];
    $authToken = null;
    $error = '';
    $issues = array();
    echo <<<EOT
    <style>
       form {border: 1px solid grey; padding: 2px; margin: 2px;}
      .pugpig_active { color: green;}
      .pugpig_inactive { color: orange;}
      .pugpig_stale { color: gray;}
      .pugpig_unknown { color: red;}
      .testusers { -webkit-column-count: 4; }
    </style>
EOT;
    echo "<h2>Pugpig Authentication Test Console - {$title}</h2>\n";
    $host = $_SERVER['HTTP_HOST'];
    if (!pugpig_test_ping($host)) {
        echo "<p><b><font color='red'>{$host}: Ping Failed. Maybe you need a local host entry?<br />127.0.0.1 {$host}</b></p>";
    }
    if (!empty($helptext)) {
        echo "<p><em>{$helptext}</em></p>";
    }
    echo "Supplied test users:\n<ul class='testusers'>\n";
    foreach ($test_users as $test_user) {
        $state = strtolower($test_user['state']);
        unset($test_user['state']);
        $p = array();
        $p["product_id"] = $product_id;
        // We need this to retain the position on WordPress
        if (isset($_REQUEST["page"])) {
            $p["page"] = $_REQUEST["page"];
        }
        $query_params = http_build_query(array_merge($test_user, $p));
        $description = implode(", ", $test_user);
        echo "<li><b class='pugpig_{$state}'>{$description}</b> - <a href='?{$query_params}'>Test</a></li>\n";
    }
    echo "</ul>\n";
    echo "<form method='GET'>\n";
    // Need to WordPress settings pages
    if (isset($_REQUEST["page"])) {
        echo "<input type='hidden' name='page' value='" . $_REQUEST["page"] . "' />\n";
    }
    echo "Enter test values:<br />\n";
    foreach ($params as $param) {
        if (isset($vals[$param])) {
            $val = $vals[$param];
        } else {
            $val = '';
        }
        echo "{$param}: <input id='{$param}' name='{$param}' type='text' value='{$val}' /> \n";
    }
    echo "<br /><input type='submit' />\n";
    echo "</form>\n";
    echo "<small>Note that the authorisation parameters for sign in are : {$user_format}. Make sure your client config matches.</small>\n\n";
    // We will always have product_id. Need at least one more.
    echo "<p>Using <em><a href='" . $urls["sign_in"] . "'>" . $urls["sign_in"] . "</a></em><br />\n";
    echo "Using <em><a href='" . $urls["verify_subscription"] . "'>" . $urls["verify_subscription"] . "</a></em><br />\n";
    echo "Using <em><a href='" . $urls["edition_credentials"] . "'>" . $urls["edition_credentials"] . "</a></em><br />\n";
    if (array_key_exists("renew_token", $urls)) {
        echo "Using <em><a href='" . $urls["renew_token"] . "'>" . $urls["renew_token"] . "</a></em><br />\n";
    }
    if (!empty($urls["sign_out"])) {
        echo "Using <em><a href='" . $urls["sign_out"] . "'>" . $urls["sign_out"] . "</a></em><br />\n";
    }
    echo "</p>";
    if (count($vals) > 1) {
        unset($vals['product_id']);
        $sep = strpos($urls["sign_in"], "?") ? "&" : "?";
        if ($use_http_post) {
            $sign_in_req = $urls["sign_in"];
            $http_status = pugpig_subs_http_request($sign_in_req, $sign_in_response, $vals);
        } else {
            $sign_in_req = $urls["sign_in"] . $sep . http_build_query($vals);
            $http_status = pugpig_subs_http_request($sign_in_req, $sign_in_response);
        }
        $status = "unknown";
        if ($http_status != 200) {
            echo "<b class='pugpig_unknown'>SIGN IN ERROR: Status {$http_status}</b><br />\n";
        } else {
            $token = pugpig_subs_get_single_xpath_value("/token", $sign_in_response);
            // Backup format to support the Dovetail response format
            if (empty($token)) {
                $token = pugpig_subs_get_single_xpath_value("/result_response/authToken", $sign_in_response);
            }
            if (empty($token)) {
                echo "Credentials not recognised - did not get a token<br />\n";
            } else {
                echo "Auth Token: <b class='pugpig_active'>{$token}</b>";
                if (array_key_exists("renew_token", $urls)) {
                    $query_vars = array("token" => $token);
                    $sep = strpos($urls["renew_token"], "?") ? "&" : "?";
                    $renew_url = $urls["renew_token"] . $sep . http_build_query($query_vars);
                    echo " [<a href='{$renew_url}'>renew</a>]";
                }
                $global_auth_password = pugpig_subs_get_single_xpath_value("/token/@global_auth_password", $sign_in_response);
                if (!empty($global_auth_password)) {
                    echo " (global auth password: <b class='pugpig_active'>{$global_auth_password}</b>)<br/>";
                    echo "Authorization: Basic " . base64_encode($token . ":" . $global_auth_password);
                }
                echo "<br />\n";
                $query_vars = array("token" => $token);
                $verify_subscription_req = $urls["verify_subscription"];
                if ($use_http_post) {
                    $http_status = pugpig_subs_http_request($verify_subscription_req, $verify_subscription_response, $query_vars);
                } else {
                    $sep = strpos($verify_subscription_req, "?") ? "&" : "?";
                    $verify_subscription_req .= $sep . http_build_query($query_vars);
                    $http_status = pugpig_subs_http_request($verify_subscription_req, $verify_subscription_response);
                }
                $query_vars['product_id'] = $product_id;
                $edition_creds_req = $urls["edition_credentials"];
                if ($http_status != 200) {
                    echo "<b class='pugpig_unknown'>VERIFY SUBSCRIPTION ERROR: Status {$http_status}</b><br />\n";
                } else {
                    $message = pugpig_subs_get_single_xpath_value("/subscription/@message", $verify_subscription_response);
                    $status = pugpig_subs_get_single_xpath_value("/subscription/@state", $verify_subscription_response);
                    $issues_exists = pugpug_subs_get_xpath_value("/subscription/issues", $verify_subscription_response);
                    $issues = pugpug_subs_get_xpath_value("/subscription/issues/issue", $verify_subscription_response);
                    if (empty($status)) {
                        echo "Status: <b class='pugpig_unknown'>Got a 200, but did not get back the expected response</b><br />\n";
                    } elseif (!in_array($status, array('unknown', 'active', 'inactive', 'stale', 'suspended'))) {
                        echo "Status: <b class='pugpig_unknown'>Did not recognise status '{$status}'</b><br />";
                    } else {
                        echo "Status: <b class='pugpig_{$status}'>{$status}</b><br />\n";
                        if (!empty($message)) {
                            echo "Message: <b class='pugpig_{$status}'>{$message}</b><br />\n";
                        }
                        if ($issues_exists == '' || $issues_exists->length == 0) {
                            if (strtolower($status) == "active") {
                                echo "<b>Access based: As an active user, you have access to all issues</b><br />\n";
                            } else {
                                echo "<b>Access based: As an inactive user, you get nothing</b><br />\n";
                            }
                        } elseif ($issues->length == 0) {
                            echo "<b>Issue based: You do not have access to any issues</b><br />\n";
                        } else {
                            echo "<b>Issue based: You have access to " . $issues->length . " issues</b><br />\n";
                            echo "<ul>\n";
                            foreach ($issues as $issue) {
                                echo "<li>" . $issue->textContent . "</li>\n";
                            }
                            echo "</ul>\n";
                        }
                    }
                }
                if ($use_http_post) {
                    $http_status = pugpig_subs_http_request($edition_creds_req, $edition_creds_response, $query_vars);
                } else {
                    $sep = strpos($edition_creds_req, "?") ? "&" : "?";
                    $edition_creds_req .= $sep . http_build_query($query_vars);
                    $http_status = pugpig_subs_http_request($edition_creds_req, $edition_creds_response);
                }
                if ($http_status != 200) {
                    echo "<b class='pugpig_unknown'>EDITION CREDENTIALS ERROR: Status {$http_status}</b>\n";
                } else {
                    $userid = pugpig_subs_get_single_xpath_value("/credentials/userid", $edition_creds_response);
                    $password = pugpig_subs_get_single_xpath_value("/credentials/password", $edition_creds_response);
                    if (!empty($userid) && !empty($password)) {
                        echo "Got credentials for <b class='pugpig_active'>{$product_id}</b><br />\n";
                    } else {
                        $status = pugpig_subs_get_single_xpath_value("/credentials/error/@status", $edition_creds_response);
                        $message = pugpig_subs_get_single_xpath_value("/credentials/error/@message", $edition_creds_response);
                        echo "Denied credentials for <b class='pugpig_unknown'>{$product_id}</b> (status: <b class='unknown'>{$status}</b>)<br />\n";
                        if (!empty($message)) {
                            echo "Message: <b class='pugpig_unknown'>{$message}</b><br />\n";
                        }
                    }
                }
                if (!empty($urls["sign_out"])) {
                    $query_vars = array("token" => $token);
                    $sign_out_req = $urls["sign_out"];
                    if ($use_http_post) {
                        $http_status = pugpig_subs_http_request($sign_out_req, $sign_out_response, $query_vars);
                    } else {
                        $sep = strpos($sign_out_req, "?") ? "&" : "?";
                        $sign_out_req .= $sep . http_build_query($query_vars);
                        $http_status = pugpig_subs_http_request($sign_out_req, $sign_out_response);
                    }
                    if ($http_status == 501) {
                        echo "<b class='pugpig_unknown'>SIGN OUT: Not implemented</b>\n";
                    } else {
                        if ($http_status != 200) {
                            echo "<b class='pugpig_unknown'>SIGN OUT ERROR: Status {$http_status}</b>\n";
                        } else {
                            // todo: check response content
                            echo "Signed out OK\n";
                        }
                    }
                }
            }
        }
        echo "<h3 class='pugpig_{$status}'>All done</h3><br />\n";
        if (!empty($sign_in_req)) {
            echo "<a href='{$sign_in_req}'>Raw Sign In</a> (HTTP " . ($use_http_post ? "POST" : "GET") . ")<br />\n";
            echo "<hr />" . htmlspecialchars($sign_in_response) . "<hr />\n";
        }
        if (!empty($verify_subscription_req)) {
            echo "<a href='{$verify_subscription_req}'>Verify Subscription</a> (HTTP " . ($use_http_post ? "POST" : "GET") . ")<br />\n";
            echo "<hr />" . htmlspecialchars($verify_subscription_response) . "<hr />\n";
        }
        if (!empty($edition_creds_req)) {
            echo "<a href='{$edition_creds_req}'>Edition Credentials</a> (HTTP " . ($use_http_post ? "POST" : "GET") . ")<br />\n";
            echo "<hr />" . htmlspecialchars($edition_creds_response) . "<hr />\n";
        }
        if (!empty($sign_out_req)) {
            echo "<a href='{$sign_out_req}'>Sign Out</a> (HTTP " . ($use_http_post ? "POST" : "GET") . ")<br />\n";
            echo "<hr />" . htmlspecialchars($sign_out_response) . "<hr />\n";
        }
    }
    print_r("<br /><em style='font-size:small'>Test Form Version: " . pugpig_get_standalone_version() . " </em><br />");
}