function pugpig_get_page($id, $edition_id, $content_filter = null)
{
    $post = get_post($id);
    // Just in case this item has been deleted
    if (!is_object($post) || apply_filters('pugpig_filter_page', false, $post, $content_filter)) {
        return null;
    }
    // Get the link for sharing
    // TODO: Allow post specific values in future
    // Get canonical URL for sharing (e.g. Twitter, Facebook)
    $sharing_link = apply_filters('pugpig_page_sharing_link', pugpig_get_canonical_url($post), $post);
    $status = $post->post_status;
    // We want everything except draft, pending and trashed posts in an edition
    if ($status != 'draft' && $status != 'trash' && $status != 'pending') {
        $status = 'published';
        // We expect the word 'published'
    }
    $stop_id_prefixes = false;
    $page = array('id' => pugpig_get_atom_post_id($post, $stop_id_prefixes), 'title' => pugpig_get_feed_post_title($post), 'access' => pugpig_get_atom_post_access($post), 'summary' => pugpig_get_feed_post_summary($post), 'status' => $status, 'modified' => pugpig_get_page_modified($post), 'date' => strtotime($post->post_date), 'type' => $post->post_type, 'categories' => pugpig_get_feed_post_categories($post, $content_filter), 'url' => url_create_deep_dot_url(pugpig_strip_domain(pugpig_get_html_url($post, $edition_id))), 'sharing_link' => $sharing_link, 'manifest' => url_create_deep_dot_url(pugpig_strip_domain(pugpig_get_manifest_url($post))), 'custom_categories' => pugpig_get_feed_post_custom_categories($post, $content_filter), 'links' => pugpig_get_links($post, $content_filter), 'author' => pugpig_get_feed_post_author($post));
    $level = pugpig_get_feed_post_level($post, $content_filter);
    if (!empty($level)) {
        $page['level'] = $level;
    }
    if ($stop_id_prefixes) {
        $page['id_prefix'] = '';
    }
    return $page;
}
function pugpig_get_custom_field_manifest_item($post, $field)
{
    $attach_ids = get_post_meta($post->ID, $field);
    print_r($attach_ids);
    die;
    $ret = "";
    foreach ($attach_ids as $attach_id) {
        // We have a custom image
        $ret .= "\n# Custom Meta Field: {$field}\n";
        $ret .= pugpig_strip_domain(wp_get_attachment_url($attach_id)) . "\n";
    }
    return $ret;
}
function _package_edition_package_list_xml($base, $edition_tag, $url_root = '', $cdn = '', $output = 'string', $timestamp = '*', $content_xml_url = "content.xml")
{
    $url_root = pugpig_strip_domain($url_root);
    $contents = _package_edition_package_contents($base, $edition_tag, $timestamp);
    if (!file_exists($contents['html_archive'])) {
        return NULL;
    }
    $total_size = 0;
    //$content_xml = "content.xml";
    $d = new DomDocument('1.0', 'UTF-8');
    $d->formatOutput = TRUE;
    $package = $d->createElement('package');
    $package->setAttribute('root', $content_xml_url);
    $comment = "Generated: " . date(DATE_RFC822);
    $package->appendChild($d->createComment($comment));
    $part = $d->createElement('part');
    $part->setAttribute('name', 'html');
    $part->setAttribute('src', $url_root . $contents['html_url']);
    $part->setAttribute('size', $contents['html_size']);
    $total_size += $contents['html_size'];
    $part->setAttribute('modified', gmdate(DATE_ATOM, $contents['html_timestamp']));
    $package->appendChild($part);
    if (is_numeric($contents['assets_size']) && $contents['assets_size'] > 0) {
        $part = $d->createElement('part');
        $part->setAttribute('name', 'assets');
        $part->setAttribute('src', $cdn . $url_root . $contents['assets_url']);
        $part->setAttribute('size', $contents['assets_size']);
        $total_size += $contents['assets_size'];
        $part->setAttribute('modified', gmdate(DATE_ATOM, $contents['assets_timestamp']));
        $package->appendChild($part);
    }
    $package->setAttribute('size', $total_size);
    $d->appendChild($package);
    if ($output == 'string') {
        return $d->saveXML();
    } else {
        $d->save($output);
        return $output;
    }
}
function pugpig_path_to_rel_url($path)
{
    return pugpig_strip_domain(pugpig_path_to_abs_url($path));
}
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();
}
if (!defined('PUGPIG_CURL_TIMEOUT')) {
    define('PUGPIG_CURL_TIMEOUT', 20);
}
/************************************************************************
Admin Interface Elements
*************************************************************************/
register_activation_hook(__FILE__, 'pugpig_activate');
function _pugpig_show_batch($rows, $file_warning_size_kb = 250, $file_warning_time_secs = 10)
{
    echo "<table style='font-size:small;''>\n";
    echo "<tr>";
    echo "<th colspan='5'>Metrics</th>";
    echo "<th colspan='2'>Cache Headers</th>";
    echo "<th colspan='4'>Edge</th>";
    echo "<th></th>";
    echo "</tr>";
    echo "<tr>";
    echo "<th>HTTP</th>";
    echo "<th>Time</th>";
    echo "<th>Type</th>";
    echo "<th>Size</th>";
    echo "<th>Valid</th>";
    echo "<th>Modified</th>";
    echo "<th>Expires</th>";
    echo "<th>Server</th>";
    echo "<th>Encoding</th>";
    echo "<th>Auth</th>";
    echo "<th>Status</th>";
    echo "<th>URL</th>";
    echo "</tr>";
    foreach ($rows as $key => $vals) {
        echo "<tr>";
        $vals['h'] = _getHeadersFromString($vals['headers']);
        if (isset($vals['curl_info'])) {
            $http_code = $vals['curl_info']['http_code'];
            $http_code_style = '';
            if ($http_code != 200) {
                $http_code_style = 'background:#ff6600';
            }
            echo "<td style='{$http_code_style}'>{$http_code}</td>\n";
            $time = $vals['curl_info']['total_time'];
            $percentage = $time / $file_warning_time_secs * 100;
            $barcolor = "lightblue";
            if ($percentage > 100) {
                $barcolor = "orange";
            }
            if ($percentage > 200) {
                $barcolor = "red";
            }
            $time_style = "white-space: nowrap; background: -webkit-gradient(linear, left top,right top, color-stop({$percentage}%,{$barcolor}), color-stop({$percentage}%,white))";
            echo "<td style='{$time_style}'>" . $vals['curl_info']['total_time'] . "</td>\n";
        } else {
            echo "<td> - </td>\n";
            echo "<td> - </td>\n";
        }
        $content_type = "";
        $content_type_style = "";
        if (isset($vals['h']['content-type'])) {
            $content_type = $vals['h']['content-type'];
        } else {
            $content_type_style = 'background: pink';
        }
        $char = pugpig_get_download_char($key, $content_type);
        echo "<td style='{$content_type_style}'>" . $char . "</td>";
        $bytes = 0;
        if (file_exists($vals['file'])) {
            $bytes = filesize($vals['file']);
        }
        $percentage = $bytes / (1024 * $file_warning_size_kb) * 100;
        $barcolor = "lightblue";
        if ($percentage > 100) {
            $barcolor = "orange";
        }
        if ($percentage > 200) {
            $barcolor = "red";
        }
        $size_style = "white-space: nowrap; background: -webkit-gradient(linear, left top,right top, color-stop({$percentage}%,{$barcolor}), color-stop({$percentage}%,white))";
        echo "<td style='{$size_style}'>" . pugpig_bytestosize($bytes) . "</td>\n";
        $error = pugpig_validate_file($vals['file'], $content_type);
        if (!empty($error)) {
            echo "<td style='background: pink'>{$error}</td>\n";
        } else {
            echo "<td>Y</td>\n";
        }
        if (isset($vals['h']['last-modified'])) {
            echo "<td>" . _ago(strtotime($vals['h']['last-modified']), 0, true) . " ago</td>\n";
        } else {
            echo "<td style='background: pink'>?</td>\n";
        }
        if (isset($vals['h']['expires'])) {
            echo "<td>in " . _ago(strtotime($vals['h']['expires']), 0, false) . "</td>\n";
        } else {
            if (isset($vals['h']['etag'])) {
                echo "<td>eTag</td>\n";
            } else {
                echo "<td style='background: pink'>?</td>\n";
            }
        }
        $cache_layer = _pugpig_get_cache_layer($vals['h']);
        $cache_layer_style = "";
        if (in_array($cache_layer, array('PPITC', 'AKAMAI', 'CLOUDFRONT'))) {
            $cache_layer_style = 'background:#6ce1c4';
        } elseif (in_array($cache_layer, array('VARNISH'))) {
            $cache_layer_style = 'background:#66ccff';
        } elseif (in_array($cache_layer, array('PHP'))) {
            $cache_layer_style = 'background:#b20047';
        }
        echo "<td style='{$cache_layer_style}'>{$cache_layer}</td>\n";
        $content_encoding = "";
        $content_encoding_style = '';
        if (isset($vals['h']['content-encoding'])) {
            $content_encoding .= $vals['h']['content-encoding'] . " ";
        }
        if (isset($vals['h']['transfer-encoding'])) {
            $content_encoding .= $vals['h']['transfer-encoding'] . " ";
        }
        if (in_array($content_encoding, array('gzip'))) {
            $content_encoding_style = 'background:#6ce1c4';
        }
        echo "<td style='{$content_encoding_style}'>{$content_encoding}</td>\n";
        if (isset($vals['h']["x-pugpig-entitlement"])) {
            echo "<td>LOCKED</td>\n";
        } else {
            echo "<td>-</td>\n";
        }
        $status = "";
        if (isset($vals['h']["x-pugpig-status"])) {
            $status .= $vals['h']["x-pugpig-status"];
        }
        echo "<td>{$status}</td>\n";
        $suspect_style = pugpig_check_suspect_path($key) ? 'background:#ff6600' : ($char == 'f' ? 'background:#66ccff' : '');
        echo "<td style=' {$suspect_style}'><a title='" . $vals['headers'] . "' target='_blank' href='{$key}'>" . pugpig_strip_domain($key) . "</a></td>\n";
        echo "</tr>";
    }
    echo "</table>\n";
}
function pugpig_wp_get_attachment_url($url)
{
    $absoluteprefix = pugpig_get_root();
    if (startsWith($url, $absoluteprefix)) {
        return $url;
    }
    if (!empty($url)) {
        $url = pugpig_strip_domain($url);
    }
    return $url;
}
function _package_edition_package_list_xml_core($base, $edition_tag, $bucket_infos, $url_root = '', $cdn = '', $output_type = 'string', $timestamp = '*', $content_xml_url = "content.xml")
{
    $d = new DomDocument('1.0', 'UTF-8');
    $d->formatOutput = true;
    $package = $d->createElement('package');
    $package->setAttribute('root', $content_xml_url);
    $package->appendChild($d->createComment("Generated: " . date(DATE_RFC822)));
    $url_root_without_domain = pugpig_strip_domain($url_root);
    $total_size = 0;
    foreach ($bucket_infos as $bucket_name => $bucket_info) {
        $bucket_cdn = $bucket_info['is_cdn'] ? $cdn : '';
        $total_size += _package_edition_package_list_xml_part($package, $d, $url_root_without_domain, $bucket_info['zips'], $bucket_name, $bucket_cdn, $base);
    }
    $package->setAttribute('size', $total_size);
    $d->appendChild($package);
    $out = null;
    if ($output_type === 'string') {
        $out = $d->saveXML();
    } else {
        $d->save($output_type);
        $out = 'string';
    }
    return $out;
}
function pugpig_rewrite_wpcontent_links($markup)
{
    $content_fragment = pugpig_strip_domain(content_url());
    $regex = '#([\'"])(' . $content_fragment . '/.*?)\\1#i';
    $index = 0;
    if (preg_match_all($regex, $markup, $matches)) {
        foreach ($matches[2] as $src) {
            $quote = $matches[1][$index];
            $new_uri = url_create_deep_dot_url($src);
            // Strip version number?
            $new_uri = remove_query_arg('ver', $new_uri);
            $markup = str_replace($quote . $src . $quote, $quote . $new_uri . $quote, $markup);
            ++$index;
        }
    }
    return _pugpig_rewrite_pugpig_html_links($markup);
}
function pugpig_ppitc_create_zip($edition_zip_root, $zip_prefix, $entries, $ts)
{
    $edition_zip_root .= DIRECTORY_SEPARATOR . date('Y\\' . DIRECTORY_SEPARATOR . 'm\\' . DIRECTORY_SEPARATOR . 'd', $ts) . DIRECTORY_SEPARATOR;
    $zip_path = pugpig_get_local_save_path($edition_zip_root, $zip_prefix . "-" . $ts . ".zip");
    echo "<font color='green'>ZIP {$zip_path}</font><br />";
    // Make the folder
    if (!file_exists($edition_zip_root)) {
        mkdir($edition_zip_root, 0777, true);
    }
    if (!file_exists($zip_path)) {
        $zip = new ZipArchive();
        if ($zip->open($zip_path, ZipArchive::CREATE) === TRUE) {
            foreach ($entries as $src => $dest) {
                $src = pugpig_strip_domain($src);
                if (startsWith($src, '/')) {
                    $src = substr($src, 1);
                }
                $zip->addFile($dest, $src);
            }
            $zip->close();
            if (file_exists($zip_path)) {
                echo "<font color='green'>Created ZIP {$zip_path}:<br>" . count($entries) . " file(s)</font> [" . pugpig_bytestosize(filesize($zip_path)) . "]<br />";
            }
        }
    } else {
        echo "<font color='grey'>Found ZIP {$zip_path}:<br>" . count($entries) . " file(s)</font> [" . pugpig_bytestosize(filesize($zip_path)) . "]<br />";
    }
}
function _pugpig_package_get_asset_urls_from_manifest($manifest_contents, $entries = array(), $base_url, $mode = 'all')
{
    $active = false;
    $last_line_was_ad = false;
    if ($mode != 'theme') {
        $active = true;
    }
    $found_manifest_start = false;
    $lines = preg_split('/\\n/m', $manifest_contents, 0, PREG_SPLIT_NO_EMPTY);
    foreach ($lines as $line) {
        // Temporary hacks to determine what is a theme asset
        // These will work with our Drupal and WordPress connector only
        // In the longer term, we need a better way to mark assets as Theme assets
        if (!$last_line_was_ad && startsWith($line, '# Theme assets')) {
            if ($mode == 'theme') {
                $active = true;
            }
            if ($mode == 'page') {
                $active = false;
            }
        }
        if (startsWith($line, '# Ad Package Zip Contents') || startsWith($line, '# Package Zip Contents')) {
            $last_line_was_ad = true;
        } else {
            $last_line_was_ad = false;
        }
        preg_match('/\\s*([^#]*)/', $line, $matches);
        if (count($matches) > 1) {
            $m = trim($matches[1]);
            // Ignore all lines until we find the "CACHE MANIFEST one"
            // Can't do this as it is currently used to scan partial manifests too
            /*
            if ($m == "CACHE MANIFEST") $found_manifest_start = TRUE;
            if (!$found_manifest_start) {
              continue;
            }
            */
            if (!empty($m) && !in_array($m, $entries) && substr($m, 0, strlen('CACHE')) != 'CACHE' && substr($m, 0, strlen('NETWORK')) != 'NETWORK' && $m != '*') {
                if (!startsWith($m, "/")) {
                    // We have a relative URL
                    $m = pugpig_strip_domain(url_to_absolute($base_url, $m));
                }
                if (!empty($m)) {
                    if ($active) {
                        $entries[] = $m;
                    }
                }
            }
        }
    }
    return $entries;
}