Source of file EmailDownloadPage.php
Size: 16,113 Bytes - Last Modified: 2021-12-23T10:39:29+00:00
/var/www/docs.ssmods.com/process/src/code/EmailDownloadPage.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 | <?php /** * Page for Email Download * Easiest changed by extending this page * and using the hide_ancestor static to hide this page itself. */ class EmailDownloadPage extends Page { /** * standard SS Variable */ private static $description = "Allow the user to download a file through their e-mail."; /** * standard SS Variable */ private static $icon = "downloadtoemail/images/treeicons/EmailDownloadPage"; /** * standard SS Variable */ private static $db = array( "LinkToThirdPartyDownload" => "Varchar(255)", "TitleOfFile" => "Varchar(50)", "EmailSubject" => "Varchar(200)", "NoAccessContent" => "Varchar(255)", "ValidityInDays" => "Float", "AllowReRequest" => "Boolean", "AllowReRequestLabel" => "Varchar(255)", "DeclineReRequestLabel" => "Varchar(255)", "ThankYouForRequesting" => "Varchar(255)", "ThankYouLink" => "Varchar(255)", "CopyOfAllEmailsToAdmin" => "Boolean" ); /** * standard SS Variable */ private static $has_one = array( "DownloadFile" => "File" ); /** * standard SS Variable */ private static $has_many = array( "EmailsSent" => "EmailDownloadPage_Registration" ); /** * standard SS Variable */ private static $defaults = array( "NoAccessContent" => "Sorry, you do not have access to this file right now. Please request access again.", "ThankYouForRequesting" => "Thank you for requesting this download, please check your e-mail for more information ...", "AllowReRequest" => true, "AllowReRequestLabel" => "Request another copy.", "DeclineReRequestLabel" => "You have already requested this file and you can not request it again." ); /** * * @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields * */ public function fieldLabels($includerelations = true) { $labels = parent::fieldLabels($includerelations); $labels["TitleOfFile"] = _t("EmailDownloadPage.TITLEOFFILE", "Title of file"); $labels["LinkToThirdPartyDownload"] = _t("EmailDownloadPage.LINKTOTHIRDPARTYDOWNLOAD", "Link to third-party download file / page"); $labels["ValidityInDays"] = _t("EmailDownloadPage.VALIDITYINDAYS", "Validity in days (you can use 0.5 for 12 hours, etc...)"); $labels["DownloadFile"] = $labels["DownloadFileID"] = _t("EmailDownloadPage.DOWNLOADFILE", "Select file to download"); $labels["ThankYouForRequesting"] = _t("EmailDownloadPage.THANKYOUFORREQUESTING", "Thank you for requesting message"); $labels["ThankYouLink"] = _t("EmailDownloadPage.THANKYOULINK", "Thank you link"); $labels["EmailSubject"] = _t("EmailDownloadPage.EMAILSUBJECT", "E-mail Subject"); $labels["AllowReRequest"] = _t("EmailDownloadPage.ALLOWREREQUEST", "Allow the user to make more than one request for the file (not strictly enforced) - change and reload to see more options"); $labels["AllowReRequestLabel"] = _t("EmailDownloadPage.ALLOWREREQUESTLABEL", "Label for requesting another copy"); $labels["DeclineReRequestLabel"] = _t("EmailDownloadPage.DECLINEREREQUESTLABEL", "Explanation of why the user can not request another copy"); $labels["NoAccessContent"] = _t("EmailDownloadPage.NOACCESSCONTENT", "Content shown when the user does not have access"); $labels["EmailsSent"] = _t("EmailDownloadPage.EMAILSSENT", "Downloads requested"); $labels["CopyOfAllEmailsToAdmin"] = _t("EmailDownloadPage.COPYOFALLEMAILSTOADMIN", "Send a copy of all e-mails to the website administrator "); return $labels; } /** * standard SS Method */ public function getCMSFields() { $fields = parent::getCMSFields(); $labels = $this->fieldLabels(true); $fieldsToAdd = array( new TextField("TitleOfFile", $labels["TitleOfFile"]), $uploadField = new UploadField("DownloadFile", $labels["DownloadFile"]) ); if ($this->DownloadFileID) { $fieldsToAdd = array_merge($fieldsToAdd, array( new NumericField("ValidityInDays", $label["ValidityInDays"]) )); } else { $fieldsToAdd = array_merge($fieldsToAdd, array( $linkToThirdPartyDownloadField = new TextField("LinkToThirdPartyDownload", $labels["LinkToThirdPartyDownload"]) )); $linkToThirdPartyDownloadField->setRightTitle(_t("EmailDownloadPage.LINKTOTHIRDPARTYDOWNLOAD_RIGHT_TITLE", "Set this to a third-party website link (e.g. dropbox) - e.g. http://www.mycooldownloadpage.com/mydownloadpage/")); } $fieldsToAdd = array_merge($fieldsToAdd, array( new CheckboxField("AllowReRequest", $labels["AllowReRequest"]), new TextField("EmailSubject", $labels["EmailSubject"]), new CheckboxField("CopyOfAllEmailsToAdmin", $labels["CopyOfAllEmailsToAdmin"]." (".Email::getAdminEmail().")"), new TextField("ThankYouForRequesting", $labels["ThankYouForRequesting"]), new TextField("ThankYouLink", $labels["ThankYouLink"]) )); if ($this->AllowReRequest) { $fieldsToAdd = array_merge($fieldsToAdd, array( new TextField("AllowReRequestLabel", $labels["AllowReRequestLabel"]), )); } else { $fieldsToAdd = array_merge($fieldsToAdd, array( new TextField("DeclineReRequestLabel", $labels["DeclineReRequestLabel"]), )); } $fieldsToAdd = array_merge($fieldsToAdd, array( new TextField("NoAccessContent", $labels["NoAccessContent"]), $gridField = new GridField("EmailsSent", $labels["EmailsSent"], $this->EmailsSent(), GridFieldConfig_RelationEditor::create()) )); $gridField->getConfig()->addComponent(new GridFieldExportButton()); $fields->addFieldsToTab( "Root.DownloadToEmail", $fieldsToAdd ); return $fields; } } class EmailDownloadPage_Controller extends Page_Controller { /** * standard SS Variable */ private static $allowed_actions = array( "DownloadForm", "dodownload", "thankyou", "requestrerequest", "noaccess" ); /** * Template to be used for sending e-mail. * @var String */ private static $email_template = "DownloadToEmailEmail"; /** * Show the download form? * @var Boolean */ protected $showDownloadForm = true; /** * Message to user (e.g. you do not have access to this file) * @var String */ protected $feedbackMessage = ""; /** * Type of feedback (Good | Bad | Warning) * @var String */ protected $feedbackMessageStyle = ""; /** * Standard SS method */ public function init() { parent::init(); $this->showDownloadForm = $this->AlreadyRequestedSuccessfully() ? false : true; } /** * * @return Boolean */ public function AlreadyRequestedSuccessfully() { return Session::get($this->sessionVarNameForSending()) ? true : false; } public function ReRequestLink() { return $this->Link("requestrerequest"); } /** * feedback message for user * @return Varchar */ public function ShowDownloadForm() { return $this->showDownloadForm; } /** * feedback message for user * @return Varchar */ public function FeedbackMessage() { return DBField::create_field('Varchar', $this->feedbackMessage); } /** * feedback message for user * @return Varchar */ public function FeedbackMessageStyle() { return DBField::create_field('Varchar', $this->feedbackMessageStyle); } /** * show the download form. * * @return Form */ public function DownloadForm() { Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js'); Requirements::javascript('downloadtoemail/javascript/DownloadToEmail.js'); $form = new Form( $this, 'DownloadForm', new FieldList($emailField = new EmailField('EmailDownloadPageEmail', _t("EmailDownloadPage.EMAIL", "enter your e-mail address"))), new FieldList(new FormAction('sendmail', _t("EmailDownloadPage.REQUEST_ACCESS", "request access"))), RequiredFields::create(array("EmailDownloadPageEmail")) ); return $form; } /** * Sent the e-mail. * * @param Array $data * @param Form $form */ public function sendmail($data, $form) { $email = Convert::raw2sql($data["EmailDownloadPageEmail"]); $obj = EmailDownloadPage_Registration::get() ->filter(array("Email" => $email, "DownloadFileID" => $this->DownloadFileID)) ->first(); if (!$obj) { $obj = new EmailDownloadPage_Registration(); $obj->Email = $email; $obj->DownloadFileID = $this->DownloadFileID; } else { $obj->Used = false; } $obj->EmailDownloadPageID = $this->ID; $obj->write(); $adminEmail = Email::getAdminEmail(); if (!$adminEmail) { user_error("You need to set an admin email in order to use this page", E_USER_NOTICE); } $email = new Email($adminEmail, $data["EmailDownloadPageEmail"], $this->EmailSubject); if ($this->CopyOfAllEmailsToAdmin) { $email->setBcc($adminEmail); } $email->setTemplate($this->config()->get("email_template")); // You can call this multiple times or bundle everything into an array, including DataSetObjects $email->populateTemplate( new ArrayData( array( "EmailSubject" => DBField::create_field('Varchar', $this->EmailSubject), "TitleOfFile" => DBField::create_field('Varchar', $this->TitleOfFile), "ValidUntil" => date('Y-M-d', strtotime("+".($this->ValidityInDays * 86400)." seconds")), "HasLink" => $this->LinkToThirdPartyDownload ? true : false, "HasFile" => $this->DownloadFileID ? true : false, "LinkToThirdPartyDownload" => $this->LinkToThirdPartyDownload, "File" => $this->DownloadFile(), "DownloadLink" => Director::absoluteURL($this->Link("dodownload/".$obj->ID."/".$obj->Code.'/')), "FileLocation" => Director::absoluteURL($this->DownloadFile()->Link()) ) ) ); $outcome = $email->send(); Session::set($this->sessionVarNameForSending(), $outcome); $this->redirect($this->Link("thankyou/".($outcome ? "success" : "fail")."/")); return array(); } /** * Do the download itself. * URL should be formatted as * /thankyou/outcome/ * * @param HTTPRequest */ public function thankyou($request) { $outcome = $request->param("ID"); if ($outcome == "success") { $this->feedbackMessage = $this->ThankYouForRequesting; $this->feedbackMessageStyle = "good"; $this->showDownloadForm = false; $this->DeclineReRequestLabel = ""; } else { $this->feedbackMessage = "E-mail could not be sent."; $this->feedbackMessageStyle = "bad"; $this->DeclineReRequestLabel = ""; } return array(); } /** * Do the download itself. * URL should be formatted as * /dodownload/$ID/$CodeForObject/ * * @param HTTPRequest */ public function dodownload($request) { Session::set($this->sessionVarNameForSending(), true); $id = intval($request->param("ID")); $code = Convert::raw2sql($request->param("OtherID")); if ($id && $code) { $obj = EmailDownloadPage_Registration::get()->filter( array( "ID" => $id, "Code" => $code, "Used" => 0 ) )->First(); if ($obj) { if ($this->ValidityInDays) { $tsNow = strtotime("NOW"); $validUntilTs = strtotime($obj->Created." +".(86400 * $this->ValidityInDays)." seconds"); if ($tsNow > $validUntilTs) { return $this->redirect($this->Link("noaccess")); } } $obj->DownloadTimes++; $obj->Used = true; $obj->write(); return $this->sendFile($obj->DownloadFile()); } } $this->redirect($this->Link("noaccess")); } /** * * What happens when the person does not have access. */ public function noaccess() { $this->feedbackMessage = $this->NoAccessContent; $this->feedbackMessageStyle = "warning"; return array(); } /** * * What happens when the person does not have access. */ public function requestrerequest() { if ($this->AllowReRequest) { Session::set($this->sessionVarNameForSending(), false); Session::clear($this->sessionVarNameForSending()); $this->redirect($this->Link()); } else { $this->redirect($this->Link("noaccess")); } return array(); } // We calculate the timelimit based on the filesize. Set to 0 to give unlimited timelimit. // The calculation is: give enough time for the user with x kB/s connection to donwload the entire file. // E.g. The default 50kB/s equates to 348 minutes per 1GB file. private static $min_download_bandwidth = 50; // [in kilobytes per second] /** * * COPIED CODE!!!!! * * This is copied from here: * https://github.com/silverstripe-labs/silverstripe-secureassets/blob/master/code/SecureFileController.php * * @param File $file */ protected function sendFile($file) { $path = $file->getFullPath(); if (SapphireTest::is_running_test()) { return file_get_contents($path); } header('Content-Description: File Transfer'); // Quotes needed to retain spaces (http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download) header('Content-Disposition: inline; filename="' . basename($path) . '"'); header('Content-Length: ' . $file->getAbsoluteSize()); header('Content-Type: ' . HTTP::get_mime_type($file->getRelativePath())); header('Content-Transfer-Encoding: binary'); // Fixes IE6,7,8 file downloads over HTTPS bug (http://support.microsoft.com/kb/812935) header('Pragma: '); if ($this->config()->min_download_bandwidth) { // Allow the download to last long enough to allow full download with min_download_bandwidth connection. increase_time_limit_to((int)(filesize($path)/($this->config()->min_download_bandwidth*1024))); } else { // Remove the timelimit. increase_time_limit_to(0); } // Clear PHP buffer, otherwise the script will try to allocate memory for entire file. while (ob_get_level() > 0) { ob_end_flush(); } // Prevent blocking of the session file by PHP. Without this the user can't visit another page of the same // website during download (see http://konrness.com/php5/how-to-prevent-blocking-php-requests/) session_write_close(); readfile($path); die(); } /** * * @return String */ protected function sessionVarNameForSending() { return "EmailDownloadPage_Controller_".$this->ID."_Sent"; } } |