<?PHP
#
#   FILE:  Piwik.php  (Piwik plugin)
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2016 Edward Almasy and Internet Scout Research Group
#   http://scout.wisc.edu/cwis/
#

/**
* Plugin to add Piwik tracking code to the HTML header.  The code
* is inserted via the EVENT_IN_HTML_HEADER event, so that event must be
* signaled in the active user interface for the plugin to work correctly.
*/
class Piwik extends Plugin
{
    # ---- STANDARD PLUGIN INTERFACE -----------------------------------------

    /**
    * Set plugin attributes.
    */
    public function Register()
    {
        $this->Name = "Piwik";
        $this->Version = "1.0.1";
        $this->Description = "Add Piwik web analytics tracking code to the HTML"
                ." page header.";
        $this->Author = "Internet Scout";
        $this->Url = "http://scout.wisc.edu/cwis/";
        $this->Email = "scout@scout.wisc.edu";
        $this->Requires = array(
                "CWISCore" => "3.1.0");
        $this->EnabledByDefault = FALSE;

        $this->CfgSetup["PiwikUrl"] = array(
                "Type" => "URL",
                "Label" => "Piwik URL",
                "Help" => "The URL for your Piwik installation.",
                "ValidateFunction" => array($this, "ValidatePiwikUrl"),
                "Size" => 60);
        $this->CfgSetup["SiteId"] = array(
                "Type" => "Number",
                "Label" => "Site ID",
                "Help" => "The ID for this site in Piwik");
    }

    /**
    * Initialize the plugin.  This is called (if the plugin is enabled) after
    * all plugins have been loaded but before any methods for this plugin
    * (other than Register()) have been called.
    * @return NULL if initialization was successful, otherwise a string or
    *       array of strings containing error messages indicating why
    *       initialization failed.
    */
    public function Initialize()
    {
        # check to make sure we have a Piwik installation URL
        $Errors = array();
        if (strlen($this->ConfigSetting("PiwikUrl")) == 0)
        {
            $Errors[] = "A Piwik installation URL has not been set.";
        }

        # check to make sure we have a site ID
        if (strlen($this->ConfigSetting("SiteId")) == 0)
        {
            # return error message about no tracking ID
            $Errors[] = "A Piwik site ID has not been set.";
        }

        # report successful initialization
        return count($Errors) ? $Errors: NULL;
    }

    /**
    * Hook methods to be called when specific events occur.
    * For events declared by other plugins the name string should start with
    * the plugin base (class) name followed by "::" and then the event name.
    * @return Array of method names to hook indexed by the event constants
    *       or names to hook them to.
    */
    public function HookEvents()
    {
        return array("EVENT_IN_HTML_HEADER" => "PrintTrackingCode");
    }

    /**
    * Validate Piwik installation URL.
    * @param string $FieldName Name of config setting being validated.
    * @param string $NewValue Setting value to validate.
    * @return string Error message or NULL if no error found.
    */
    public function ValidatePiwikUrl($FieldName, $NewValue)
    {
        $OurScheme = parse_url(ApplicationFramework::RootUrl(), PHP_URL_SCHEME);
        $ParamScheme = parse_url($NewValue, PHP_URL_SCHEME);
        if (($ParamScheme !== NULL) && ($ParamScheme != $OurScheme))
        {
            return "Because of browser consistency checks, the protocol"
                    ." (<i>http</i> or <i>https</i>) for the Piwik installation"
                    ." URL must match the protocol for the website.";
        }
        return NULL;
    }


    # ---- HOOKED METHODS ----------------------------------------------------

    /**
    * HOOKED METHOD: PrintTrackingCode
    * Write the code for Piwik tracking to output.
    */
    public function PrintTrackingCode()
    {
        # if Piwik URL and site ID look valid
        if (strlen($this->ConfigSetting("SiteId"))
                && strlen($this->ConfigSetting("PiwikUrl")))
        {
            # load Piwik URL and ID for this site
            $PiwikUrl = $this->ConfigSetting("PiwikUrl");
            $SiteId = intval($this->ConfigSetting("SiteId"));

            # make sure URL does not have a trailing slash
            if (substr($PiwikUrl, -1) == "/")
            {
                $PiwikUrl = substr($PiwikUrl, 0, -1);
            }

            # write out tracking code
            ?>
            <!-- Piwik (start) -->
            <script type="text/javascript">
                var _paq = _paq || [];
                _paq.push(['trackPageView']);
                _paq.push(['enableLinkTracking']);
                (function() {
                    var u="<?= $PiwikUrl ?>/";
                    _paq.push(['setTrackerUrl', u+'piwik.php']);
                    _paq.push(['setSiteId', <?= $SiteId ?>]);
                    var d=document, g=d.createElement('script');
                    var s=d.getElementsByTagName('script')[0];
                    g.type='text/javascript'; g.async=true; g.defer=true;
                    g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
                })();
            </script>
            <noscript><p><img src="<?= $PiwikUrl ?>/piwik.php?idsite=<?=
                    $SiteId ?>" style="border:0;" alt="" /></p></noscript>
            <!-- Piwik (end)  -->
            <?PHP
        }
    }
}
