<?PHP

class OpenId extends Plugin
{
    function Register()
    {
        $this->Name = "OpenID Login";
        $this->Version = "1.0.0";
        $this->Description = "Provides users with the option to log in with an "
                ."<a href=\"http://openid.net\" target=\"_blank\">OpenID</a>, "
                ."allowing them to use the same login across multiple websites.";
        $this->Author = "Internet Scout";
        $this->Url = "http://scout.wisc.edu/cwis/";
        $this->Email = "scout@scout.wisc.edu";
        $this->Requires = array(
            "CWISCore" => "1.9.0"
            );
    }

    function Install()
    {
        $DB = new Database();

        $DB->Query("CREATE TABLE OpenId_UserMap ("
                   ."DisplayId TEXT, "
                   ."UserName TEXT)"
            );

    }

    function HookEvents()
    {
        return array(
            "EVENT_APPEND_HTML_TO_FORM" => "ModifyLoginForm",
            "EVENT_PHP_FILE_LOAD" => "InspectFormAndMaybeRedirect");
    }

    function InspectFormAndMaybeRedirect($PageName)
    {
        global $Session;

        $Destination = array("PageName" => $PageName);
        $OidDisplayed = (bool) $this->GetPostValue("F_OidDisplayed");
        $Provider = $this->GetPostValue("F_OpenIdProvider");
        $Name = $this->GetPostValue("F_OpenId");
        $Username = $this->GetPostValue("F_UserName");
        $Password = $this->GetPostValue("F_Password");
        $Skip = isset($_POST["SkipOpenId"]) || $Username
            || $Password || !$OidDisplayed;

        if ($Provider && array_key_exists($Provider, $this->ProviderUrls))
        {
            $ProviderUrl = $this->ProviderUrls[$Provider];

            # AOL is currently the only provider supporting user names
            if ($Provider == "aol")
            {
                $Name = $ProviderUrl . $Name;
                $_POST["F_OpenId"] = $Name;
            }

            else
            {
                $Name = $ProviderUrl;
                $_POST["F_OpenId"] = $Name;
            }
        }

        if ($PageName == "UserLogin" && !$Skip && $Name)
        {
            $Destination["PageName"] = "P_OpenId_TryAuth";
        }

        $OidLoginError = $Session->Get("OidLoginError");

        if (!is_null($OidLoginError))
        {
            $Session->PassVariable("OidLoginError", $OidLoginError);
        }

        return $Destination;
    }

    function ModifyLoginForm($PageName, $FormName, $Labels, $InputElements, $Notes)
    {
        global $AF, $Session;

        $Result = array(
            "PageName" => $PageName,
            "FormName" => $FormName,
            "Labels" => $Labels,
            "InputElements" => $InputElements,
            "Notes" => $Notes);

        # modify the login form only
        if ($FormName != "LoginForm")
        {
            return $Result;
        }

        if (1 > strlen($PageName))
        {
            # header
            $Result["Labels"][] = '
                <p class="oid-header"><b>Log In Using OpenID</b>:</p>';
            $Result["InputElements"][] = "";
            $Result["Notes"][] = "";

            # hidden flag field
            $Result["Labels"][] = "";
            $Result["InputElements"][] = '
                <input type="hidden" name="F_OidDisplayed" value="1" />';
            $Result["Notes"][] = "";

            # provider field
            $Result["Labels"][] = '
                <label class="oid-provider" for="F_OpenIdProvider">Use:</label>';
            $Result["InputElements"][] ='
                <select class="oid-provider" id="F_OpenIdProvider" name="F_OpenIdProvider">
                    <option value="">OpenID</option>
                    <option value="google">Google</option>
                    <option value="yahoo">Yahoo!</option>
                    <option value="aol">AOL</option>
                </select>';
            $Result["Notes"][] = "";

            # OpenID username field, submit button, styles, and javascript
            $Result["Labels"][] = '
                <label class="oid-name" for="F_OpenId">Name:</label>';
            $Result["InputElements"][] = '
                <input class="oid-name" type="text" id="F_OpenId" name="F_OpenId" value="" />
                <input class="oid-submit" type="image"
                    src="'.$AF->GUIFile("go.gif").'" alt="GO" />
                <style type="text/css">
                    p.oid-header {}
                    label.oid-provider { display: block; }
                    select.oid-provider { width: 108px; margin-top: 1px; }
                    div.oid-namegroup { display: block; }
                    label.oid-name { display: block; margin-top: 2px; }
                    input.oid-name { position: relative; bottom: 5px; width: 104px; }
                    input.oid-submit { position: relative; top: 1px; left: 7px; }
                </style>
                <script type="text/javascript" src="include/jquery.cookie.js"></script>
                <script type="text/javascript">
                  (function(){
                    var $providers, cookie;
                    if ($ && $.cookie) {
                      $providers = $("select.oid-provider");
                      cookie = $.cookie("oid-provider");

                      $providers.change(function(){
                        var $provider = $(this),
                            $option = $("option:selected", $provider),
                            $name = $("input.oid-name"),
                            label = $option.html();

                        $name.val("");
                        $.cookie("oid-provider", label, {
                            "expires": 365
                        });
                      });

                      if (cookie) {
                        $("option:selected", $providers).removeAttr("selected");
                        $("option:contains(\'"+cookie+"\')",
                            $providers).attr("selected", "selected");
                        $providers.change();
                      } else {
                        $("option:contains(\'Google\')",
                            $providers).attr("selected", "selected");
                      }
                    }
                  }())
                </script>';
            $Result["Notes"][] = trim(preg_replace('/\s+/', " ", "
                To login with an OpenId, enter your OpenID URL below.
                Login with a Google Profile by entering
                'google.com/profiles/YOUR_GOOGLE_PROFILE'. Login with yahoo by
                entering 'yahoo.com'"));
        }

        else if ($PageName == "LoginError")
        {
            $OidLoginError = $Session->Get("OidLoginError");

            if (!is_null($OidLoginError))
            {
                $Result["Labels"][] = $OidLoginError;
                $Result["InputElements"][] = "&nbsp;";
                $Result["Notes"][] = "";

                $Session->UnregisterVariable("OidLoginError");
            }
        }

        return $Result;
    }

    /**
     * Get a value from the POST array.
     * @param $Key POST array key
     * @return the value or NULL if not set or is an empty string
     */
    private function GetPostValue($Key)
    {
        if (!isset($_POST[$Key]) || 1 > strlen($_POST[$Key]))
        {
            return NULL;
        }

        return $_POST[$Key];
    }

    /**
     * @var $Providers OpenID provider URLs
     */
    private $ProviderUrls = array(
        "aol" => "https://openid.aol.com/",
        "google" => "https://www.google.com/accounts/o8/id",
        "yahoo" => "https://www.yahoo.com/");

}
