<?PHP
// @codingStandardsIgnoreFile
#
#   FILE:  MailIt.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2002-2015 Edward Almasy and Internet Scout Research Group
#   http://scout.wisc.edu/cwis/
#

/**
* Plugin adds the ability to share a resource via email using a button on the
* FullRecord page.
*/
class MailIt extends Plugin
{
    # ---- STANDARD PLUGIN INTERFACE -----------------------------------------

    /**
    * Set up plugin upon installation.
    * Set defaults for configuration.
    * @return NULL on success
    */
    function Install()
    {
      # get the mailer template options
      # (we need to use this function because it gets called after all
      # the plugins are loaded; otherwise we might not have Mailer)
      $Mailer = $GLOBALS["G_PluginManager"]->GetPlugin("Mailer");
      $MailerTemplates = $Mailer->GetTemplateList();

      #Set up the default template for MailIt if it doesn't exist.
      if(!in_array("MailIt Default", $MailerTemplates))
      {
          $Mailer->AddTemplate( "MailIt Default",
                                "X-PORTALNAME-X <X-ADMINEMAIL-X>",
                                "X-MAILIT:SENDINGUSERNAME-X Sent a Resource from X-PORTALNAME-X",
                                '<p><strong>X-MAILIT:SENDINGUSERNAME-X
                                 </strong><em>(X-MAILIT:SENDINGUSEREMAIL-X)
                                 </em>sent information about this
                                 resource from X-PORTALNAME-X:
                                 <br/><br/>
                                 X-RESOURCELIST-X',
                                '<h1><a href="X-RESOURCEVIEWURL-X">X-FIELD:TITLE-X</a>
                                 </h1><h2><a href="X-FIELD:URL-X">X-FIELD:URL-X</a></h2>
                                 <p>X-FIELD:DESCRIPTION-X</p><p>
                                 <a href="X-RESOURCEVIEWURL-X/">more info</a></p>',
                                 'X-MAILIT:SENDINGUSERNAME-X (X-MAILIT:SENDINGUSEREMAIL-X) sent information about this resource from X-PORTALNAME-X:
                                  X-RESOURCELIST-X',
                                 'X-FIELD:TITLE-X

                                  X-FIELD:URL-X

                                  X-FIELD:DESCRIPTION-X
                                  More Info: X-RESOURCEVIEWURL-X/',
                                 "",
                                 FALSE);
       #Need to get the template again if we just added the template so we have up-to-date config
        #vaules.
        $MailerTemplates = $Mailer->GetTemplateList();
      }
      $DefaultTemplate = array_search("MailIt Default", $MailerTemplates);
      $this->ConfigSetting("EmailTemplate", $DefaultTemplate);
      $this->ConfigSetting("ButtonText", "Email Resource");
      $this->ConfigSetting("HeaderText", "Email Resource");
      $this->ConfigSetting("BodyText", "Please enter the email address(es) where you want to send information about this resource. If you wish to enter multiple recipients, please separate the addresses with commas.");
      $this->InitializeAfter = array("Mailer");

      return NULL;
    }

    /**
    * Register information about this plugin.
    */
    public function Register()
    {
        $this->Name = "Mail It";
        $this->Version = "1.0.0";
        $this->Description = "Plugin that adds the ability to share a resource
                via email using a button on the FullRecord page.";
        $this->Author = "Internet Scout";
        $this->Url = "http://scout.wisc.edu/cwis/";
        $this->Email = "scout@scout.wisc.edu";
        $this->Requires = array(
                "CWISCore" => "3.1.0",
                "Mailer" => "1.0.7");
        $this->EnabledByDefault = TRUE;
    }

    /**
    * Set up plugin configuration options.
    * @return NULL if configuration setup succeeded, otherwise a string with
    *       an error message indicating why config setup failed.
    */
    public function SetUpConfigOptions()
    {
        # get the mailer template options
        # (we need to use this function because it gets called after all
        # the plugins are loaded; otherwise we might not have Mailer)
        $Mailer = $GLOBALS["G_PluginManager"]->GetPlugin("Mailer");

        $TemplateOptions = $Mailer->GetTemplateList();
        $DefaultTemplate = array_search("MailIt_DEFAULT", $TemplateOptions);

        $this->CfgSetup["EmailTemplate"] = array(
                "Type" => "Option",
                "Label" => "E-mail Template",
                "Help" => "The Mailer template to use for full record emails.",
                "Default" => $DefaultTemplate,
                "Options" => $TemplateOptions);

        $this->CfgSetup["HeaderText"] = array(
                "Type" => "Text",
                "Label" => "Mail It Header Text",
                "Default" => "Share this Resource",
                "Help" => "The header to use when asking to send a resource.");

        $this->CfgSetup["BodyText"] = array(
                "Type" => "Paragraph",
                "Label" => "Mail It Body Text",
                "Default" => "Please enter the email address(es) where you want to send information about this resource. If you wish to enter multiple recipients, please separate the addresses with commas.",
                "Help" => "The text to use when asking to send a resource.");

        $this->CfgSetup["ButtonText"] = array(
                "Type" => "Text",
                "Label" => "Button Text",
                "Default" => "Email Resource",
                "Help" => "The text to use in the button users click to send email about a resource.");

        return NULL;
    }

    /**
    * Hook event callbacks into the application framework.
    * @return Returns an array of events to be hooked into the application
    *      framework.
    */
    public function HookEvents()
    {
        return array("EVENT_HTML_INSERTION_POINT" => "InsertButton",
                "EVENT_IN_HTML_HEADER" => "InHtmlHeader");
    }

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

    /**
    * Callback for the EVENT_HTML_INSERTION_POINT event. Inserts a "Mail It"
    * button on the FullRecord page at the location "After Description Block".
    * @param $PageName The name of the page
    * @param $Location The name of the location on the page
    * @param $Context The context of the insertion point
    */
    public function InsertButton($PageName, $Location, $Context = NULL)
    {
        # before we do anything make sure this is the right insertion point
        if ($PageName !== "FullRecord" || $Location !== "After Description Block") return;

        # the user must be logged in to see the button
        global $G_User;
        if (!is_object($G_User) || !$G_User->IsLoggedIn()) return;

        #Ensure errors are output correctly.
        $Errors = "";

        if(array_key_exists("ER",$_GET))
        {
          $ErrorNumber = $_GET["ER"];
          $ErrorMessages = array( 0 => "<br>The \"Resource\" parameter is necessary.</br>",
                                  1 => "<br>The resource you are trying to send is not valid.</br>",
                                  2 => "<br>You can only send resources that are OK for viewing.</br>",
                                  4 => "<br>An unknown error prevented this resource from being sent. Please try again.</br>"
                                );
          $Errors = $ErrorMessages[$ErrorNumber];
        }

        $Success = "";

        if(array_key_exists("SC",$_GET))
        {
           $Success = "<br>Email successfully sent!</br>";
        }

        # insert the button markup and javascript
?>
<a id="MailItButton" class="cw-button cw-button-elegant" title="Email this resource" href="index.php?P=P_MailIt_ConfirmMailIt&ID=<?PHP
        isset($Context["Resource"])? print $Context["Resource"]->Id() : print ""; ?>"><?PHP print $this->ConfigSetting("ButtonText");?></a>
<span id="MailItErrors" style="color: red"><?PHP print $Errors; ?></span>
<span id="MailItSuccess" style="color: green"><?PHP print $Success; ?></span>
<script type="text/javascript" src="<?PHP print OurBaseUrl() . "plugins/MailIt/interface/default/include/MailIt.js"; ?>"></script>
<?PHP

    }

    /**
    * Callback for the EVENT_IN_HTML_HEADER event. Inserts the plugin stylsheet
    * into the HTML header.
    */
    public function InHtmlHeader()
    {
        # only put header content in when we are on the full record page and
        #       have a resource available
        if (($GLOBALS["AF"]->GetPageName() != "FullRecord")
                || !isset($GLOBALS["G_Resource"])
                || !($GLOBALS["G_Resource"] instanceof Resource))
                {  return;  }
?>
<!-- Mail It -->
<script type="text/javascript">
  var MailItHeaderText = "<?PHP print $this->ConfigSetting("HeaderText"); ?>";
  var MailItBodyText = "<?PHP print $this->ConfigSetting("BodyText"); ?>";
  var MailItResourceId = "<?PHP print $GLOBALS["G_Resource"]->Id(); ?>";
  var MailItPostUrl = "<?PHP print OurBaseUrl() . "plugins/MailIt/pages/response.php"; ?>";
  var MailItDefaultEmail = "<?PHP print $GLOBALS["G_User"]->Get("EMail"); ?>";
</script>

<link rel="stylesheet" type="text/css" href="<?PHP print OurBaseUrl() . "plugins/MailIt/interface/default/include/mailit.css"; ?>" />
<?PHP
    }

    # ---- PUBLIC INTERFACE --------------------------------------------------

    /**
    * Get an array of tokens to replace with special values that can be
    * used in a Mailer template. Tokens are based on the schema and user.
    * @param CWUser $User User to use as context
    * @param Resource $Resource Resource to use as context
    * @param string $Recommendee The address the email will be sent to.
    * @return array Array of token replacements
    */
    private function GetMailerTokens(CWUser $User, Resource $Resource, $Recomendee)
    {
        # make the return array
        $TokenArray = array();

        # check parameters
        if (!$User || !$Resource) return $TokenArray;

        # get the schema for the resource
        $Schema = new MetadataSchema($Resource->SchemaId());

        # get the fields in the schema
        $Fields = $Schema->GetFields();

        # iterate over all the fields, adding the appropriate tokens
        foreach ($Fields as $Field)
        {
            # if the user can't view the field, replace it with nothing
            if (!$Resource->UserCanViewField($User, $Field))
            {
                $TokenArray["MAILIT:" . $Field->Name()] = "";
                continue;
            }

            # otherwise add the token
            $Values = $Resource->Get($Field);

            # handle if there are multiple
            if (is_array($Values))
            {
                # start with an empty replacement
                $Replacement = "";

                # iterate over all the values, adding them to the replacement
                foreach ($Values as $Value)
                {
                    if ($Replacement !== "") $Replacement = $Replacement . ", ";
                    $Replacement = $Replacement . $Value;
                }

                # add them to the tokens
                $UppercaseName = strtoupper(str_replace(" ", "", $Field->Name()));
                $TokenArray["MAILIT:" . $UppercaseName] = $Replacement;
            }
            else
            {
                # otherwise, just add the value right away
                $UppercaseName = strtoupper(str_replace(" ", "", $Field->Name()));
                $TokenArray["MAILIT:" . $UppercaseName] = $Values;
            }
        }

        $TokenArray["MAILIT:SENDINGUSERNAME"] = $User->Name();
        $TokenArray["MAILIT:SENDINGUSEREMAIL"] = $User->Get("EMail");
        $TokenArray["MAILIT:RECIPIENTEMAIL"] = $Recomendee;

        # return the tokens
        return $TokenArray;
    }

    /**
    * Determine if a full record email can be sent out.
    * @param CWUser $User User to check
    * @return Returns TRUE if the full record email can be sent out and FALSE
    *      otherwise.
    */
    public function EmailCanBeSent(Resource $Resource)
    {

        # resource must be ok for viewing
        if (!$Resource->UserCanView($GLOBALS["G_User"]))
        {
            return FALSE;
        }

        # notifications could be sent
        return TRUE;
    }

    /**
    * Send out an email to a given user containing the full record of a
    * resource.
    * @param Resource $Resource the resource to send
    * @param String $Recomendee the email address to send the record to
    * @return either SENT or an error message.
    */
    function SendFullRecordEmail(Resource $Resource, $Recomendee)
    {
        # get the logged in User
        $User = $GLOBALS["G_User"];

        # don't send full record email if not allowed
        if (!$this->EmailCanBeSent($Resource))
        {
            return "You can only send resources that are released.";
        }

        $Mailer = $GLOBALS["G_PluginManager"]->GetPlugin("Mailer");
        $UserSchema = new MetadataSchema(MetadataSchema::SCHEMAID_USER);
        $UserField = $UserSchema->GetFieldByName("UserId");

        # the extra mailer replacement tokens for future use
        $ExtraTokens = $this->GetMailerTokens($User, $Resource, $Recomendee);

        # send the notification e-mails using tasks
        $Sent = $Mailer->SendEmailUsingTasks(
            $this->ConfigSetting("EmailTemplate"),
            $Recomendee,
            $Resource,
            $ExtraTokens);

        return "SENT";
    }
}
