/**
  * Publish an array of arrays as a CSV download
  * @param array[array] $data
  * @throws Exception
  */
 public static function PublishData($data)
 {
     # Check that the data is an array
     if (!is_array($data)) {
         throw new Exception('$data must be an array of arrays');
     }
     # Respond with HTTP headers that download this data is a file
     # and allow it to be cached for up to one hour
     header("Content-type: text/csv");
     header("Cache-Control: max-age=3600, public");
     header('Content-Disposition: attachment; filename="stoolball-england.csv"');
     # Use PHP function to get the CSV format right
     $outstream = fopen("php://output", 'w');
     # Add Unicode BOM to ensure correct encoding, but only needed locally as no problem on live,
     # but this causes one. http://www.24k.com.sg/blog-55.html
     if (SiteContext::IsDevelopment()) {
         fprintf($outstream, chr(0xef) . chr(0xbb) . chr(0xbf));
     }
     foreach ($data as $row) {
         fputcsv($outstream, $row, ',', '"');
     }
     fclose($outstream);
     exit;
 }
 public function GetDomain()
 {
     return SiteContext::IsDevelopment() ? 'stoolball.local' : 'www.stoolball.org.uk';
 }
 /**
  * Customise the display of posts as they are being rendered by the browser
  *
  * @param string $content
  * @return string
  */
 public function TheContent($content = '')
 {
     $searches = array();
     $replaces = array();
     # Use title as alt where there's a title and an empty alt attribute
     $searches[] = '/ title="([^"]+)"([^>]*) alt=""/';
     $replaces[] = '$2 alt="$1"';
     # Remove title where there's also a populated alt attribute
     $searches[] = '/ title="[^"]+"([^>]* alt="[^"]+")/';
     $replaces[] = '$1';
     # Remove link to original image, which has no navigation
     $searches[] = '/<a href="[^"]+.(jpg|gif|png|jpeg)"[^>]*>(<img [^>]*>)<\\/a>/';
     $replaces[] = '$2';
     # Strip these by providing no replacement text
     $searches[] = '/ title="[a-z0-9-]*"/';
     # remove meaningless title attributes containing filenames
     $replaces[] = '';
     $content = preg_replace($searches, $replaces, $content);
     $content = str_replace("http://www.stoolball.org.uk", "https://www.stoolball.org.uk", $content);
     if (is_home()) {
         # Take out and remember images
         $content = preg_replace_callback('/(<img[^>]*>)/', array($this, 'ExtractImage'), $content);
         $strip_these = array('/<h[0-9][^>]*>.*?<\\/h[0-9]>/', '/<p class="wp-caption-text">.*?<\\/p>/', '/<a[^>]* class="more-link[^>]*>.*?<\\/a>/', '/style="width: [0-9]+px;?"/', '/<div[^>]*><\\/div>/');
         $content = preg_replace($strip_these, '', $content);
         # Don't want home page to be too long, so cut off after first para
         $pos = strpos($content, '</p>');
         if ($pos) {
             $pos = $pos + 4;
             # length of </p>
             $content = substr($content, 0, $pos);
         }
         # If there were images, put the first one at the start of the text
         if (count($this->a_matches)) {
             # Remove unused class, width and height
             $image = preg_replace('/ (class|width|height)="[A-Za-z0-9-_ ]+"/', '', $this->a_matches[0]);
             # Try to isolate the src attribute and swop it for the corresponding thumbnail
             $pos = strpos($image, ' src="');
             if ($pos !== false) {
                 $pos = $pos + 6;
                 # move to start to attr value
                 $len = strpos($image, '"', $pos);
                 if ($len !== false) {
                     # Get path to image on server
                     $wordpress_image_folder = $this->settings->GetServerRoot();
                     if (SiteContext::IsDevelopment()) {
                         $wordpress_image_folder .= "../";
                     }
                     # on dev setup, WordPress image uploads are outside web root
                     require_once 'Zend/Uri.php';
                     $uri = Zend_Uri::factory(substr($image, $pos, $len - $pos));
                     /* @var $uri Zend_Uri_Http */
                     # Change it to the thumbnail path and see whether the thumbnail exists
                     $thumbnail = $wordpress_image_folder . $uri->getPath();
                     $pos = strrpos($thumbnail, '.');
                     if ($pos !== false) {
                         $thumbnail = substr($thumbnail, 0, $pos) . "-150x150" . substr($thumbnail, $pos);
                         if (file_exists($thumbnail)) {
                             # if it does exist, update the original image tag with the thumbnail suffix and size
                             # important to do all these checks because thumbnails don't exist for images smaller than 150px
                             $image = preg_replace('/\\.(jpg|jpeg|gif|png)"/', '-150x150.$1" width="150" height="150"', $image);
                         }
                     }
                 }
             }
             # Add image before content
             $content = $image . $content;
         }
     } else {
         # Increase image width by 10px (caption must be 100%, so space around image must be margin on inner element, not padding on this element)
         $content = preg_replace_callback('/class="wp-caption([A-Za-z0-9-_ ]*)" style="width: ([0-9]+)px;?"/', array($this, 'ReplaceImageWidth'), $content);
         # Add extra XHTML around photo captions as hook for CSS
         $content = preg_replace('/(<p class="wp-caption-text">[^<]*<\\/p>)/', '<div class="photoCaption">$1</div>', $content);
     }
     $protector = new EmailAddressProtector($this->settings);
     $content = $protector->ApplyEmailProtection($content, is_object(AuthenticationManager::GetUser()) and AuthenticationManager::GetUser()->IsSignedIn());
     return $content;
 }
<?php

ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] . '/../' . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] . '/../classes/');
require_once 'data/mysql-connection.class.php';
require_once 'context/stoolball-settings.class.php';
require_once 'context/site-context.class.php';
require_once 'stoolball/match-manager.class.php';
require_once 'xhtml/html.class.php';
require_once "Zend/Feed.php";
# set up error handling, unless local and using xdebug
$settings = new StoolballSettings();
if (!SiteContext::IsDevelopment()) {
    require_once 'page/exception-manager.class.php';
    require_once 'page/email-exception-publisher.class.php';
    $errors = new ExceptionManager(array(new EmailExceptionPublisher($settings->GetTechnicalContactEmail())));
    # Use production settings recommended by
    # http://perishablepress.com/advanced-php-error-handling-via-htaccess/
    # Not possible to set in .htaccess because PHP is running as a CGI. This is the
    # next best thing.
    ini_set("display_startup_errors", "off");
    ini_set("display_errors", "off");
    ini_set("html_errors", "off");
    ini_set("log_errors", "on");
    ini_set("ignore_repeated_errors", "off");
    ini_set("ignore_repeated_source", "off");
    ini_set("report_memleaks", "on");
    ini_set("track_errors", "on");
    ini_set("docref_root", "0");
    ini_set("docref_ext", "0");
    ini_set("error_reporting", "-1");
    ini_set("log_errors_max_len", "0");
    /**
     * @return void
     * @desc Fires before closing the body element of the page
     */
    protected function OnBodyClosing()
    {
        # Close open divs
        if ($this->b_col1_open) {
            echo '</div></div>';
        }
        if ($this->b_col2_open) {
            echo '</div>';
        }
        if ($this->i_constraint_type != StoolballPage::ConstrainNone()) {
            echo '</div>';
        }
        # Close <div id="constraint">
        ?>
	</div>
	<div id="sidebar">
	<?php 
        if (AuthenticationManager::GetUser()->Permissions()->HasPermission(PermissionType::VIEW_ADMINISTRATION_PAGE)) {
            $o_menu_link = new XhtmlElement('a', 'Menu');
            $o_menu_link->AddAttribute('href', '/yesnosorry/');
            echo new XhtmlElement('p', $o_menu_link, "screen");
        }
        # Add WordPress edit page link if relevant
        if (SiteContext::IsWordPress() and AuthenticationManager::GetUser()->Permissions()->HasPermission(PermissionType::VIEW_WORDPRESS_LOGIN)) {
            global $post;
            $b_wordpress_edit_allowed = true;
            echo '<ul>';
            if ($post->post_type == 'page') {
                if (!current_user_can('edit_page', $post->ID)) {
                    $b_wordpress_edit_allowed = false;
                }
            } else {
                if (!current_user_can('edit_post', $post->ID)) {
                    $b_wordpress_edit_allowed = false;
                }
            }
            if ($b_wordpress_edit_allowed) {
                echo '<li><a href="' . apply_filters('edit_post_link', get_edit_post_link($post->ID), $post->ID) . '">Edit page</a></li>';
            }
            if (function_exists('wp_register')) {
                wp_register();
                echo '<li>';
                wp_loginout();
                echo '</li>';
                wp_meta();
            }
            echo '</ul>';
        }
        echo '<h2 id="your" class="large">Your stoolball.org.uk</h2>';
        $authentication = new AuthenticationControl($this->GetSettings(), AuthenticationManager::GetUser());
        $authentication->SetXhtmlId('authControl');
        echo $authentication;
        # Add admin options
        $this->Render();
        # Add next matches
        $num_matches = count($this->a_next_matches);
        if ($num_matches) {
            $next_alt = $num_matches > 1 ? "Next {$num_matches} matches" : 'Next match';
            echo '<h2 id="next' . $num_matches . '" class="large"><span></span>' . $next_alt . '</h2>';
            $o_match_list = new MatchListControl($this->a_next_matches);
            $o_match_list->UseMicroformats(false);
            # Because parse should look at other match lists on page
            $o_match_list->AddCssClass("large");
            echo $o_match_list;
            echo '<p class="large"><a href="/matches">All matches and tournaments</a></p>';
        }
        $this->Render();
        ?>
	</div>
	<div id="boardBottom">
		<div>
			<div></div>
		</div>
	</div>
</div></div></div>
<div id="post"></div>
	<?php 
        if (!SiteContext::IsDevelopment() and !AuthenticationManager::GetUser()->Permissions()->HasPermission(PermissionType::EXCLUDE_FROM_ANALYTICS)) {
            ?>
<script>
var _gaq=[['_setAccount','UA-1597472-1'],['_trackPageview'],['_setDomainName','.stoolball.org.uk'],['_trackPageLoadTime']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.async=1;
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
		<?php 
        }
        if ($this->GetHasGoogleMap()) {
            // Load Google AJAX Search API for geocoding (Google Maps API v3 Geocoding is still rubbish 29 Oct 2009)
            $s_key = SiteContext::IsDevelopment() ? 'ABQIAAAA1HxejNRwsLuCM4npXmWXVRRQNEa9vqBL8sCMeUxGvuXwQDty9RRFMSpVT9x-PVLTvFTpGlzom0U9kQ' : 'ABQIAAAA1HxejNRwsLuCM4npXmWXVRSqn96GdhD_ATNWxDNgWa3A5EXWHxQrao6MHCS6Es_c2v0t0KQ7iP-FTg';
            echo '<script src="https://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=' . $s_key . '"></script>';
            // Load Google Maps API v3
            echo '<script src="https://maps.google.co.uk/maps/api/js?sensor=false"></script>';
        }
    }