// We have to package from the root
        $edition_tag = '';
        $return_manifest_asset_urls = FALSE;
        $save_root = $_GET['pf'];
        $cdn = isset($_GET['cdn']) ? $_GET['cdn'] : '';
        $package_url_base = isset($_GET['urlbase']) ? $_GET['urlbase'] : '';
        $debug = FALSE;
        if (isset($_GET['debug'])) {
            $debug = TRUE;
        }
        $test_mode = FALSE;
        if (isset($_GET['testmode'])) {
            $test_mode = TRUE;
        }
        $image_test_mode = FALSE;
        if (isset($_GET['image_test_mode'])) {
            $image_test_mode = TRUE;
        }
        // Get the XML for the package
        $package_xml = _pugpig_package_edition_package($final_package_url, $content_xml_url, $relative_path, $debug, $edition_tag, $return_manifest_asset_urls, $timestamp, $tmp_root, $save_root, $cdn, $package_url_base, $test_mode, $image_test_mode, $concurrent_connections);
    } else {
        if ($action == 'checkendpoints') {
            $feeds = $_GET['f'];
            $endpoints = explode("\r\n", $feeds);
            _pugpig_package_test_endpoints($endpoints, $timestamp, $tmp_root);
        }
    }
    print '<br><br>Done.';
}
print_r("<br /><em style='font-size:small'>Packager Version: " . pugpig_get_standalone_version() . " </em><br />");
Esempio n. 2
0
function _pugpig_package_edition_package($final_package_url, $content_xml_url, $relative_path, $debug = FALSE, $edition_tag = '', $return_manifest_asset_urls = FALSE, $timestamp = '', $tmp_root, $save_root, $cdn = '', $package_url_base = '', $test_mode = FALSE, $image_test_mode = FALSE, $concurrent = 5)
{
    $output = '';
    $html_zip_paths = array();
    $asset_zip_paths = array();
    $save_root = str_replace(DIRECTORY_SEPARATOR, '/', $save_root);
    $tmp_root = str_replace(DIRECTORY_SEPARATOR, '/', $tmp_root);
    $domain = '/';
    $colon_pos = strpos($content_xml_url, '://');
    if ($colon_pos > 0) {
        $domain = substr($content_xml_url, 0, strpos($content_xml_url, '/', $colon_pos + 3));
    }
    // $relative_path = _pugpig_package_url_remove_domain(substr($content_xml_url, 0, strrpos($content_xml_url, '/')) . '/');
    // WORDPRESS TEST
    //if (endsWith($content_xml_url, "pugpig_atom_contents.manifest")) $relative_path = '/';
    if (!$test_mode && !file_exists($save_root)) {
        mkdir($save_root, 0777, TRUE);
    }
    $tmp_path = $tmp_root . 'package-' . $timestamp . '/';
    pugpig_interface_output_header("Pugpig - Edition Packager");
    if ($test_mode) {
        print_r("<h1>Performing Pugpig Package Test Run</h1>");
    } else {
        if ($image_test_mode) {
            print_r("<h1>Performing Pugpig Package Image Preview</h1>");
        } else {
            print_r("<h1>Creating Pugpig Package</h1>");
        }
    }
    print_r("<button style='cursor: pointer;' onclick=\"toggle_visibility('info');\">Info</button> ");
    print_r("<button style='cursor: pointer;' onclick=\"toggle_visibility('key');\">Key</button> ");
    print_r("<br />Packager version " . pugpig_get_standalone_version() . " <br />");
    print_r("<span id='key' style='display:none;'>");
    print_r("<span class='pass'>* - downloaded</span><br />");
    print_r("<span class='skip'>* - skipped as already downloaded</span><br />");
    print_r("<span class='warning'>* - downloaded, but large file warning</span><br />");
    print_r("<span class='bigwarning'>* - downloaded, but VERY large file warning</span><br />");
    print_r("<span class='slowwarning'>* - downloaded, but a little bit slowly</span><br />");
    print_r("<span class='veryslowwarning'>* - downloaded, but too slowly for comfort</span><br />");
    print_r("<span class='fail'>* - failed to fetch or save resource</span><br />");
    print_r("</span>");
    print_r("<span id='info' style='display:none;'>");
    print_r("<em>Final Package URL: <a href='{$final_package_url}'>" . $final_package_url . '</a></em><br />');
    print_r("<em>Packaging ATOM URL: <a href='{$content_xml_url}'>" . $content_xml_url . '</a></em><br />');
    print_r("<em>Domain is: " . $domain . '</em><br />');
    print_r("<em>Relative path is: " . $relative_path . '</em><br />');
    print_r("<em>Package URL base is: " . $package_url_base . '</em><br />');
    print_r("<em>Save root is: " . $save_root . '</em><br />');
    print_r("<em>Temp path is: " . $tmp_path . '</em><br />');
    print_r("<em>CDN is: " . $cdn . '</em><br />');
    print_r("<em>Debug Mode is: " . ($debug ? "ON" : "OFF") . '</em><br />');
    print_r("<em>Test Mode is: " . ($test_mode ? "ON" : "OFF") . '</em><br />');
    print_r("<em>Image Mode is: " . ($image_test_mode ? "ON" : "OFF") . '</em><br />');
    print_r("<em>cURL timeout is: " . PUGPIG_CURL_TIMEOUT . ' seconds with ' . $concurrent . ' concurrent requests</em><br />');
    print_r("</span>");
    print_r("<h1>Retrieving files</h1>");
    _print_immediately('Package ' . $timestamp . ' started at ' . date(PUGPIG_DATE_FORMAT, $timestamp) . '<br />');
    // Array used to store errors in the responses
    $format_failures = array();
    // Get the ATOM feeds - the real and and the one that might contain hidden extras
    $entries = array();
    $content_xml_hidden_save_path = $tmp_path . 'content-hidden.xml';
    $content_xml_hidden_path = $content_xml_url . (strpos($content_xml_url, '?') > 0 ? '&' : '?') . 'include_hidden=yes';
    $entries = _pugpig_relative_urls_to_download_array($relative_path, array($content_xml_url), $domain, $tmp_path);
    $entries[$content_xml_hidden_path] = $content_xml_hidden_save_path;
    $entries = _pugpig_package_download_batch("Public and Hidden ATOM Feeds", $entries, $debug, $concurrent);
    $content_xml_save_path = $entries[$content_xml_url];
    if (file_exists($content_xml_save_path)) {
        // Read the ATOM from the hidden file
        $fhandle = fopen($content_xml_save_path, 'r');
        $atom_excluding_hidden = fread($fhandle, filesize($content_xml_save_path));
        fclose($fhandle);
        $msg = check_xml_is_valid($atom_excluding_hidden);
        if ($msg != '') {
            $format_failures[$content_xml_url] = "XML Invalid: " . $msg;
            $atom_excluding_hidden = '';
        }
    }
    $atom_ret = null;
    if (file_exists($content_xml_hidden_save_path)) {
        // Read the ATOM from the hidden file
        $fhandle = fopen($content_xml_hidden_save_path, 'r');
        $atom_including_hidden = fread($fhandle, filesize($content_xml_hidden_save_path));
        fclose($fhandle);
        $msg = check_xml_is_valid($atom_including_hidden);
        if ($msg != '') {
            $format_failures[$content_xml_hidden_path] = "XML Invalid: " . $msg;
            $atom_including_hidden = '';
        } else {
            $atom_ret = _pugpig_package_parse_atom($atom_including_hidden);
        }
        unset($entries[$content_xml_hidden_path]);
        // We only want the real atom in the zip
        $html_zip_paths = array_merge($html_zip_paths, _pugpig_package_zip_paths($entries, $tmp_path, $package_url_base, $relative_path, $debug));
    }
    // Check that the XML is valid, and show the errors if not.
    _pugpig_package_show_failures($format_failures);
    if (!$atom_ret) {
        return;
    }
    // Update the edition tag if we have something from the feed
    if ($debug) {
        _print_immediately('Edition tag was <b>' . $edition_tag . '<br />');
    }
    if (!strlen($edition_tag)) {
        $edition_tag = $atom_ret['edition_tag'];
    }
    _print_immediately('Edition tag is <b>' . $edition_tag . '<br />');
    // Process the manifests - these are relative to the ATOM content XML
    $entries = _pugpig_relative_urls_to_download_array($relative_path, $atom_ret['manifest_urls'], $content_xml_url, $tmp_path);
    $entries = _pugpig_package_download_batch("Manifests", $entries, $debug, $concurrent);
    $asset_zip_paths = array_merge($asset_zip_paths, _pugpig_package_zip_paths($entries, $tmp_path, $package_url_base, $relative_path, $debug));
    // Keep for the asset zip
    // Getting the list of static files from the manifests
    $manifest_entries = array();
    $format_failures = array();
    foreach ($entries as $url => $sfile) {
        $fhandle = fopen($sfile, 'r');
        $fcontents = trim(fread($fhandle, filesize($sfile)));
        fclose($fhandle);
        if (!startsWith($fcontents, "CACHE MANIFEST")) {
            // This is dodgy. We have a 200 that isn't a manifest.
            // Sometimes under really high concurrency, Drupal doesn't load includes properly
            // Delete the saved file in case it is better next time.
            $format_failures[$url] = "Manifest format not correct - CACHE MANIFEST not at start of response. Got: " . $fcontents;
            unlink($sfile);
        } else {
            //print_r("Read: " . $sfile . " - " . filesize($sfile) . " bytes<br />");
            $manifest_entries = _pugpig_package_get_asset_urls_from_manifest($fcontents, $manifest_entries, $url);
        }
    }
    _pugpig_package_show_failures($format_failures);
    $manifest_entries = array_unique($manifest_entries);
    // Stop now and return the list of manifest items if required
    if ($return_manifest_asset_urls) {
        _print_immediately('<em>Returning ' . count($manifest_entries) . ' assets</em><br />');
        return $manifest_entries;
    }
    // Process the static files
    $entries = _pugpig_relative_urls_to_download_array($relative_path, $manifest_entries, $domain, $tmp_path);
    if ($image_test_mode) {
        _pugpig_package_show_images_in_package($entries);
    } else {
        $entries = _pugpig_package_download_batch("Static Files", $entries, $debug, $concurrent);
        $asset_zip_paths = array_merge($asset_zip_paths, _pugpig_package_zip_paths($entries, $tmp_path, $package_url_base, $relative_path, $debug));
        // Keep for the asset zip
        // Process the HTML files
        $entries = _pugpig_relative_urls_to_download_array($relative_path, $atom_ret['html_urls'], $content_xml_url, $tmp_path);
        $entries = _pugpig_package_download_batch("HTML Pages", $entries, $debug, $concurrent);
        $html_zip_paths = array_merge($html_zip_paths, _pugpig_package_zip_paths($entries, $tmp_path, $package_url_base, $relative_path, $debug));
        // Keep for the html zip
        if (!$test_mode) {
            print_r("<h2>Packaging files</h2>");
            // Figure put where the packages will live
            $zip_base_url = $relative_path;
            if (!empty($package_url_base)) {
                $zip_base_url = $package_url_base;
            }
            _pugpig_package_create_zip("public assets", $edition_tag . '-assets-' . $timestamp . '.zip', $tmp_path, $save_root, $asset_zip_paths, $zip_base_url);
            _pugpig_package_create_zip("secure html", $edition_tag . '-html-' . $timestamp . '.zip', $tmp_path, $save_root, $html_zip_paths, $zip_base_url);
            // Create package - TODO: Check on why we save this
            print_r("<h3>Creating Package XML</h3>");
            $package_name = $edition_tag . '-package-' . $timestamp . '.xml';
            _print_immediately('<em>Saving package xml to ' . $save_root . $package_name . '</em><br />');
            $package_xml = _package_edition_package_list_xml($save_root, $edition_tag, $package_url_base, $cdn, $save_root . $package_name, $timestamp);
            _print_immediately("<a target='_blank' href='" . $final_package_url . "'>View XML file</a><br />");
            if (is_null($package_xml)) {
                _print_immediately('Error in saving package file.<br /><br /><b>Aborting!</b><br /><a href="javascript:location.reload(true);">Refresh this page to reload and try again. (It will resume from where it last succeeded.)</a><br />');
                exit;
            }
            $deleted_files = _pugpig_clean_package_folder($save_root);
            if (count($deleted_files)) {
                print_r("<h3>Deleting old packagage files</h3>");
                _print_immediately("<b>Deleted " . count($deleted_files) . " old files</b><br />");
                foreach ($deleted_files as $f) {
                    _print_immediately("Deleted {$f}<br />");
                }
            }
        }
    }
    // Delete the temp area
    if (!$debug) {
        _package_rmdir($tmp_path);
    } else {
        _print_immediately("<p><b>Debug mode - not deleting temp files</b></p>");
    }
    _fill_buffer(16000);
    if (!$test_mode && !$image_test_mode) {
        print_r("<h2>Packaging Complete</h2>");
    } else {
        print_r("<h2>Test Run Complete</h2>");
    }
    return $edition_tag . '-package-' . $timestamp . '.xml';
}
Esempio n. 3
0
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 />");
}
require_once 'pugpig_filesystem.php';
require_once 'pugpig_manifests_wordpress.php';
require_once 'pugpig_admin.php';
require_once 'pugpig_ad_bundles.php';
require_once 'pugpig_change_hooks.php';
require_once 'pugpig_settings.php';
require_once 'pugpig_notifications_wordpress.php';
require_once 'pugpig_html_manifest.php';
require_once 'pugpig_url_rewrites.php';
require_once 'pugpig_article_rewrite.php';
require_once 'pugpig_metaboxes.php';
/************************************************************************
Messy Boilerplate
*************************************************************************/
// some definition we will use
define('PUGPIG_CURRENT_VERSION', '2.3.4  (standalone ' . pugpig_get_standalone_version() . ')');
//define('WP_DEBUG', true);
//define('WP_DEBUG_DISPLAY', true);
// error_reporting(E_ALL | E_NOTICE);
//ini_set('display_errors', '1');
//phpinfo();
// Directories to store logs and manifests
$wp_ud_arr = wp_upload_dir();
define('PUGPIG_MANIFESTURL', pugpig_strip_domain($wp_ud_arr['baseurl'] . '/pugpig-api/'));
define('PUGPIG_MANIFESTPATH', str_replace('\\', '/', $wp_ud_arr['basedir']) . '/pugpig-api/');
// define( 'PUGPIG_THEME_MANIFEST', PUGPIG_MANIFESTPATH . 'wordpress-theme.manifest');
/************************************************************************
Using the session for admin messages
*************************************************************************/
if (!session_id()) {
    session_start();
<?php

/**
 * @file
 * Standalone iTunes receipt validator
 * You will need to modify the configuration values to suit your environment:
 */
/*

Licence:
==============================================================================
(c) 2011, Kaldor Holdings Ltd
This module is released under the GNU General Public License.
See COPYRIGHT.txt and LICENSE.txt
*/
include_once "pugpig_utilities.php";
include_once "pugpig_subs.php";
if (!file_exists('standalone_config.php')) {
    echo "<h2>Warning - standalone_config.php not found</h2>";
    echo "In order to use this page, you will need to configure settings in the file: <code>standalone_config.php</code>";
    exit;
}
include_once 'standalone_config.php';
if (!defined('PUGPIG_CURL_TIMEOUT')) {
    define('PUGPIG_CURL_TIMEOUT', 20);
}
$binaryReceipt = file_get_contents("php://input");
$comments = array();
$comments[] = "From Standalone PHP version " . pugpig_get_standalone_version();
pugpig_send_itunes_edition_credentials($iTunesSecret, $subscriptionPrefix, array('1MOSUB1', '1YRSUB1'), $binaryReceipt, $pugpigCredsSecret, $comments, $proxy_server, $proxy_port);
function _pugpig_package_edition_package($final_package_url, $content_xml_url, $relative_path, $debug = false, $edition_tag = '', $return_manifest_asset_urls = false, $timestamp = '', $tmp_root, $save_root, $cdn = '', $package_url_base = '', $test_mode = false, $image_test_mode = false, $concurrent = 5, $bucket_allocator = null)
{
    $verbose = $debug;
    if (empty($bucket_allocator)) {
        // create default bucket allocator
        $bucket_allocator = new PackagedFileAllocatorOriginal();
    }
    $bucket_allocator->setVerbose($verbose);
    // sanitise inputs
    $save_root = str_replace(DIRECTORY_SEPARATOR, '/', $save_root);
    $tmp_root = str_replace(DIRECTORY_SEPARATOR, '/', $tmp_root);
    // process inputs
    $domain = '/';
    $colon_pos = strpos($content_xml_url, '://');
    if ($colon_pos > 0) {
        $domain = substr($content_xml_url, 0, strpos($content_xml_url, '/', $colon_pos + 3));
    }
    $last_slash = strrpos($content_xml_url, '/');
    $content_xml_leaf = $last_slash === false ? $content_xml : substr($content_xml_url, $last_slash + 1);
    $tmp_path = $tmp_root . 'package-' . $timestamp . '/';
    // ensure save root folder exists
    if (!$test_mode && !file_exists($save_root)) {
        mkdir($save_root, 0777, true);
    }
    pugpig_interface_output_header("Pugpig - Edition Packager");
    if ($test_mode) {
        echo "<h1>Performing Pugpig Package Test Run</h1>";
    } elseif ($image_test_mode) {
        echo "<h1>Performing Pugpig Package Image Preview</h1>";
    } else {
        echo "<h1>Creating Pugpig Package</h1>";
    }
    $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>";
    }
    print_r("<button style='cursor: pointer;' onclick=\"toggle_visibility('info');\">Info</button> ");
    print_r("<button style='cursor: pointer;' onclick=\"toggle_visibility('key');\">Key</button> ");
    print_r("<br />Packager version " . pugpig_get_standalone_version() . " <br />");
    print_r("<span id='key' style='display:none;'>");
    print_r("<span class='pass'>* - downloaded</span><br />");
    print_r("<span class='skip'>* - skipped as already downloaded</span><br />");
    print_r("<span class='fail'>* - failed to fetch or save resource</span><br />");
    print_r("</span>");
    print_r("<span id='info' style='display:none;'>");
    print_r("<em>Final Package URL: <a href='{$final_package_url}'>" . $final_package_url . '</a></em><br />');
    print_r("<em>Packaging ATOM URL: <a href='{$content_xml_url}'>" . $content_xml_url . '</a></em><br />');
    print_r("<em>Content leaf: {$content_xml_leaf}</em><br />");
    print_r("<em>Domain is: " . $domain . '</em><br />');
    print_r("<em>Relative path is: " . $relative_path . '</em><br />');
    print_r("<em>Package URL base is: " . $package_url_base . '</em><br />');
    print_r("<em>Save root is: " . $save_root . '</em><br />');
    print_r("<em>Temp path is: " . $tmp_path . '</em><br />');
    print_r("<em>CDN is: " . $cdn . '</em><br />');
    print_r("<em>Debug Mode is: " . ($debug ? "ON" : "OFF") . '</em><br />');
    print_r("<em>Test Mode is: " . ($test_mode ? "ON" : "OFF") . '</em><br />');
    print_r("<em>Image Mode is: " . ($image_test_mode ? "ON" : "OFF") . '</em><br />');
    print_r("<em>cURL timeout is: " . PUGPIG_CURL_TIMEOUT . ' seconds with ' . $concurrent . ' concurrent requests</em><br />');
    echo $bucket_allocator->describeAllocator();
    print_r("</span>");
    print_r("<h1>Retrieving: {$content_xml_url}</h1>");
    _print_immediately('Package ' . $timestamp . ' started at ' . date(PUGPIG_DATE_FORMAT, $timestamp) . '<br />');
    // Array used to store errors in the responses
    $format_failures = array();
    // Get the ATOM feeds - the real and and the one that might contain hidden extras
    $entries = array();
    $content_xml_hidden_save_path = $tmp_path . 'content-hidden.xml';
    $content_xml_hidden_path = $content_xml_url . (strpos($content_xml_url, '?') > 0 ? '&' : '?') . 'include_hidden=yes';
    // get the entry for the content xml
    $entries = _pugpig_relative_urls_to_download_array($relative_path, array($content_xml_url), $domain, $tmp_path);
    // and the hidden version
    $entries[$content_xml_hidden_path] = $content_xml_hidden_save_path;
    $entries = _pugpig_package_download_batch("Public and Hidden ATOM Feeds", $entries, $debug, $concurrent);
    // validate feed that doesn't have hidden entries
    _pugpig_validate_saved_feed($entries[$content_xml_url], $content_xml_url, $format_failures);
    // validate feed that has hidden entries
    $feed_contents_with_hidden = _pugpig_validate_saved_feed($content_xml_hidden_save_path, $content_xml_hidden_path, $format_failures);
    $atom_filenames = null;
    $atom_ret = null;
    if (!empty($feed_contents_with_hidden)) {
        $atom_ret = _pugpig_package_parse_atom($feed_contents_with_hidden);
        unset($entries[$content_xml_hidden_path]);
        // we only want the real atom in the zip
        $atom_filenames = _pugpig_package_zip_paths($entries, $tmp_path, $package_url_base, $relative_path, $debug);
    }
    _pugpig_package_show_failures($format_failures);
    if (!$atom_ret) {
        return;
    }
    $contextualised_urls = $atom_ret['contextualised_urls'];
    foreach ($contextualised_urls as $page_id => &$context) {
        $context['manifest_urls'] = _pugpig_relative_urls_to_download_array($relative_path, $context['manifest_urls'], $content_xml_url, $tmp_path);
        $context['html_urls'] = _pugpig_relative_urls_to_download_array($relative_path, $context['html_urls'], $content_xml_url, $tmp_path);
    }
    unset($context);
    $manifest_pages = $atom_ret['manifest_pages'];
    $manifest_pages_absolute = array();
    foreach ($manifest_pages as $url => $page_ids) {
        $filenames = array_keys(_pugpig_relative_urls_to_download_array($relative_path, array($url), $content_xml_url, $tmp_path));
        if (count($filenames > 0)) {
            $absolute_filename = $filenames[0];
            $manifest_pages_absolute[$absolute_filename] = $page_ids;
        }
    }
    // Get the Edition Tag if we don't have it
    if (!strlen($edition_tag)) {
        $edition_tag = $atom_ret['edition_tag'];
    }
    // Update the edition tag if we have something from the feed
    _print_immediately('<h2>Edition: ' . $atom_ret['edition_title'] . ' (' . $edition_tag . ')</h2>');
    // Process the manifests - these are relative to the ATOM content XML
    $entries = _pugpig_relative_urls_to_download_array($relative_path, $atom_ret['manifest_urls'], $content_xml_url, $tmp_path);
    $entries = _pugpig_package_download_batch("Manifests", $entries, $debug, $concurrent);
    // Getting the list of static files from the manifests
    $manifest_entries = array();
    $format_failures = array();
    foreach ($entries as $url => $sfile) {
        $fhandle = fopen($sfile, 'r');
        $fcontents = trim(fread($fhandle, filesize($sfile)));
        fclose($fhandle);
        if (!startsWith($fcontents, "CACHE MANIFEST")) {
            // This is dodgy. We have a 200 that isn't a manifest.
            // Sometimes under really high concurrency, Drupal doesn't load includes properly
            // Delete the saved file in case it is better next time.
            $format_failures[$url] = "Manifest format not correct - CACHE MANIFEST not at start of response. Got: " . $fcontents;
            unlink($sfile);
        } else {
            //print_r("Read: " . $sfile . " - " . filesize($sfile) . " bytes<br />");
            //
            $this_manifest_files = _pugpig_package_get_asset_urls_from_manifest($fcontents, array(), $url);
            $this_manifest_files_src_dest = _pugpig_relative_urls_to_download_array($relative_path, $this_manifest_files, $content_xml_url, $tmp_path);
            //$this_manifest_files_src_dest = _pugpig_package_zip_paths($this_manifest_files_src_dest, $tmp_path, $package_url_base, $relative_path, $debug);
            $manifest_pages = $manifest_pages_absolute[$url];
            foreach ($manifest_pages as $manifest_page) {
                if (empty($contextualised_urls[$manifest_page]['manifest_files'])) {
                    $contextualised_urls[$manifest_page]['manifest_files'] = $this_manifest_files_src_dest;
                } else {
                    $contextualised_urls[$manifest_page]['manifest_files'][] = $this_manifest_files_src_dest;
                }
            }
            $entries = _pugpig_relative_urls_to_download_array($relative_path, $atom_ret['manifest_urls'], $content_xml_url, $tmp_path);
            $manifest_entries = _pugpig_package_get_asset_urls_from_manifest($fcontents, $manifest_entries, $url);
        }
    }
    _pugpig_package_show_failures($format_failures);
    $manifest_entries = array_unique($manifest_entries);
    // Stop now and return the list of manifest items if required
    if ($return_manifest_asset_urls) {
        _print_immediately('<em>Returning ' . count($manifest_entries) . ' assets</em><br />');
        return $manifest_entries;
    }
    // Process the static files
    $entries = _pugpig_relative_urls_to_download_array($relative_path, $manifest_entries, $domain, $tmp_path);
    if ($image_test_mode) {
        _pugpig_package_show_images_in_package($entries);
    } else {
        $entries = _pugpig_package_download_batch("Static Files", $entries, $debug, $concurrent);
        // Process the HTML files
        $entries = _pugpig_relative_urls_to_download_array($relative_path, $atom_ret['html_urls'], $content_xml_url, $tmp_path);
        $entries = _pugpig_package_download_batch("HTML Pages", $entries, $debug, $concurrent);
        if (!$test_mode) {
            print_r("<h2>Packaging files</h2>");
            $bucket_allocator->allocateAtomFileToBuckets($atom_filenames);
            foreach ($contextualised_urls as $page_id => $info) {
                $html_files = _pugpig_package_zip_paths($info['html_urls'], $tmp_path, $package_url_base, $relative_path, $debug);
                $manifest_files = _pugpig_package_zip_paths($info['manifest_urls'], $tmp_path, $package_url_base, $relative_path, $debug);
                $manifest_contents = _pugpig_package_zip_paths($info['manifest_files'], $tmp_path, $package_url_base, $relative_path, $debug);
                $context_xml = $info['entry'];
                $bucket_allocator->allocatePageFilesToBuckets($html_files, $manifest_files, $manifest_contents, $context_xml);
            }
            $bucket_allocator->finaliseBuckets();
            // Figure put where the packages will live
            $zip_base_url = $relative_path;
            if (!empty($package_url_base)) {
                $zip_base_url = $package_url_base;
            }
            $prefered_max_size = 20 * 1024 * 1024;
            $bucket_zips = _pugpig_package_create_chunked_zips_for_buckets($bucket_allocator->getBuckets(), $edition_tag, $timestamp, $tmp_path, $save_root, $zip_base_url, $prefered_max_size, $verbose);
            // Create package - TODO: Check on why we save this
            print_r("<h3>Creating Package XML</h3>");
            $package_name = "{$edition_tag}-package-{$timestamp}.xml";
            _print_immediately("<em>Saving package xml to {$save_root}{$package_name}</em><br />");
            $package_xml = _package_edition_package_list_xml_using_buckets($save_root, $edition_tag, $bucket_allocator, $bucket_zips, $package_url_base, $cdn, $save_root . $package_name, $timestamp, $content_xml_leaf);
            _print_immediately("<a target='_blank' href='" . $final_package_url . "'>View XML file</a><br />");
            if (is_null($package_xml)) {
                _print_immediately('Error in saving package file.<br /><br /><b>Aborting!</b><br /><a href="javascript:location.reload(true);">Refresh this page to reload and try again. (It will resume from where it last succeeded.)</a><br />');
                exit;
            }
            $deleted_files = _pugpig_clean_package_folder($save_root);
            if (count($deleted_files)) {
                print_r("<h3>Deleting old package files</h3>");
                _print_immediately("<b>Deleted " . count($deleted_files) . " old files</b><br />");
                foreach ($deleted_files as $f) {
                    _print_immediately("Deleted {$f}<br />");
                }
            }
        }
    }
    // Delete the temp area
    if (!$debug) {
        _package_rmdir($tmp_path);
    } else {
        _print_immediately("<p><b>Debug mode - not deleting temp files</b></p>");
    }
    _fill_buffer(16000);
    if (!$test_mode && !$image_test_mode) {
        print_r("<h2>Packaging Complete</h2>");
    } else {
        print_r("<h2>Test Run Complete</h2>");
    }
    return $edition_tag . '-package-' . $timestamp . '.xml';
}
 */
/*

Licence:
==============================================================================
(c) 2011, Kaldor Holdings Ltd
This module is released under the GNU General Public License.
See COPYRIGHT.txt and LICENSE.txt
*/
include_once 'pugpig_utilities.php';
include_once 'pugpig_interface.php';
pugpig_interface_output_header("Pugpig - Standalone Tests");
?>

<h1><img src="images/pugpig-32x32.png" style="vertical-align: text-bottom;"/> Pugpig PHP Suite (Version <?php 
echo pugpig_get_standalone_version();
?>
)</h1>

<?php 
if (!file_exists('standalone_config.php')) {
    echo "<h2>Warning - standalone_config.php not found</h2>";
    echo "In order to use these pages, you will need to configure settings in the file: <code>standalone_config.php</code>";
} else {
    include_once 'standalone_config.php';
}
?>

<h2>Testing Tools</h2>

<p>Sample High Volume Content Endpoint: <a href="content_test/entry.php/editions-atom.xml">(Atom)</a> <a href="content_test/entry.php/editions.xml">(Package)</a> <a href="content_test/entry.php/newsstand.xml">(Newsstand Atom)</a> <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 />");
}