/**
  * Process IPN request from ClickBank. Only process POST request
  * 
  * @param	object	$_POST
  * @return	int		HTTP code 
  */
 public function ipn(SS_HTTPRequest $request)
 {
     if ($request->isPost()) {
         if (ClickBankManager::validate_ipn_request($request->postVars())) {
             ClickBankManager::process_ipn_request($request->postVars());
             return Director::get_status_code();
         }
     }
     return ErrorPage::response_for(404);
 }
 public function webhook(SS_HTTPRequest $request)
 {
     $mandrill_events = $request->postVars();
     foreach (json_decode($mandrill_events['mandrill_events']) as $event) {
         $MandrillEvent = new MandrillEvent();
         $MandrillEvent->ts = $event->ts;
         $MandrillEvent->event = $event->event;
         $MandrillEvent->url = $event->url;
         $MandrillEvent->user_agent = $event->user_agent;
         $MandrillEvent->MessageID = $event->_id;
         $MandrillEvent->write();
     }
 }
 public function update(SS_HTTPRequest $request)
 {
     $member = Customer::currentUser();
     if (!$member->canEdit()) {
         return $this()->httpError(401);
     }
     $updateData = $request->postVars();
     $updateData = ProfiledMemberForm::update_models('update', $updateData, $member);
     $member->write();
     /** @noinspection PhpParamsInspection */
     ProfiledMemberForm::set_form_message("ProfileUpdated", CrackerjackForm::Good);
     $this->sendEmail('Update', $member, $updateData);
     return $this()->redirectBack();
 }
 /**
  * This method passes through an HTTP request to another webserver. 
  * This proxy is used to avoid any cross domain issues. The proxy
  * uses a white-list of domains to minimize security risks. 
  *
  * @param SS_HTTPRequest $data array of parameters
  *
  * $data['u']:         URL (complete request string)
  * $data['no_header']: set to '1' to avoid sending header information 
  *                     directly. 
  * @return the CURL response
  */
 public function dorequest($data)
 {
     $headers = array();
     $vars = $data->requestVars();
     $no_header = false;
     if (!isset($vars['u'])) {
         return "Invalid request: unknown proxy destination.";
     }
     $url = $vars['u'];
     if (isset($vars['no_header']) && $vars['no_header'] == '1') {
         $no_header = true;
     }
     $checkUrl = explode("/", $url);
     if (!in_array($checkUrl[2], self::get_allowed_host())) {
         return "Access denied to ({$url}).";
     }
     // Open the Curl session
     $session = curl_init($url);
     // If it's a POST, put the POST data in the body
     $isPost = $data->isPOST();
     if ($isPost) {
         $postvars = '';
         $vars = $data->getBody();
         if ($vars) {
             $postvars = "body=" . $vars;
         } else {
             $vars = $data->postVars();
             if ($vars) {
                 foreach ($vars as $k => $v) {
                     $postvars .= $k . '=' . $v . '&';
                 }
             }
         }
         $headers[] = 'Content-type: text/xml';
         curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
         curl_setopt($session, CURLOPT_POST, true);
         curl_setopt($session, CURLOPT_POSTFIELDS, $postvars);
     }
     // Don't return HTTP headers. Do return the contents of the call
     curl_setopt($session, CURLOPT_HEADER, false);
     curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
     // Make the call
     $xml = curl_exec($session);
     // The web service returns XML. Set the Content-Type appropriately
     if ($no_header == false) {
         header("Content-Type: text/xml");
     }
     curl_close($session);
     return $xml;
 }
 /**
  * Action to handle upload of a single file
  *
  * @param SS_HTTPRequest $request
  * @return SS_HTTPResponse
  * @return SS_HTTPResponse
  */
 public function upload(SS_HTTPRequest $request)
 {
     // Find the first set of upload data that looks like it came from an
     // UploadField.
     // NOTE(Jake): There is only the SecurityID and the 'upload' data as this is done
     //             in it's own AJAX request, not sent along with all the other data.
     foreach ($request->postVars() as $key => $value) {
         // todo(Jake): Test SS 3.1 compatibility
         // NOTE(Jake): Only tested in SS 3.2, UploadField::upload data may not look like this in 3.1...
         if ($value && isset($value['name']) && isset($value['type']) && isset($value['tmp_name'])) {
             // NOTE(Jake): UploadField requires this FormField to be the correct name so it can retrieve
             //             the file information from postVar. So detect the first set of data that seems
             //             like upload info and use it.
             $this->setName($key);
             break;
         }
     }
     return parent::upload($request);
 }
 public function handleRequest(SS_HTTPRequest $request, DataModel $model = null)
 {
     self::$is_at_root = true;
     $this->setDataModel($model);
     $this->pushCurrent();
     $this->init();
     if (!($site = Multisites::inst()->getCurrentSiteId())) {
         return $this->httpError(404);
     }
     $page = SiteTree::get()->filter(array('ParentID' => $site, 'URLSegment' => 'home'));
     if (!($page = $page->first())) {
         return $this->httpError(404);
     }
     $request = new SS_HTTPRequest($request->httpMethod(), $page->RelativeLink(), $request->getVars(), $request->postVars());
     $request->match('$URLSegment//$Action', true);
     $front = new MultisitesFrontController();
     $response = $front->handleRequest($request, $model);
     $this->popCurrent();
     return $response;
 }
 /**
  * Renders the CheckfrontLinkGenerator template with filled in
  *  -   Package
  *  -   Posted array info
  *  -   AccessKey encoded so can copy/paste
  *  -   Link to copy paste to email
  *
  * @param SS_HTTPRequest $request
  *
  * @return HTMLText
  */
 protected function generateLinks(SS_HTTPRequest $request)
 {
     $postVars = $request->postVars();
     $packageID = $postVars[CheckfrontLinkGeneratorForm::PackageIDFieldName];
     $packageResponse = CheckfrontModule::api()->fetchPackage($packageID);
     if (!($package = $packageResponse->getPackage())) {
         throw new CheckfrontException(_t('Package.NoSuchPackageMessage', "Package {id}not found", array('id' => $packageID)), CheckfrontException::TypeError);
     }
     /*
             if (!$organiserEvent = $packageResponse->getEvent($postVars[CheckfrontLinkGeneratorForm::OrganiserEventFieldName])) {
                 throw new CheckfrontException(_t('Package.NoSuchEventMessage', "{type}event not found", array('type' => 'Organiser ')));
             }
             if (!$individualEvent = $packageResponse->getEvent($postVars[CheckfrontLinkGeneratorForm::IndividualEventFieldName])) {
                 throw new CheckfrontException(_t('Package.NoSuchEventMessage', "{type}event not found", array('type' => 'Individual ')));
             }
     */
     $accessKey = CheckfrontModule::crypto()->generate_key();
     $organiserLink = $this->makeLink($accessKey, $postVars[CheckfrontLinkGeneratorForm::PackageIDFieldName], $postVars[CheckfrontLinkGeneratorForm::OrganiserStartDate], $postVars[CheckfrontLinkGeneratorForm::OrganiserEndDate], $postVars[CheckfrontLinkGeneratorForm::LinkTypeFieldName], CheckfrontModule::UserTypeOrganiser, $postVars[CheckfrontLinkGeneratorForm::PaymentTypeFieldName]);
     $individualLink = $this->makeLink($accessKey, $postVars[CheckfrontLinkGeneratorForm::PackageIDFieldName], $postVars[CheckfrontLinkGeneratorForm::IndividualStartDate], $postVars[CheckfrontLinkGeneratorForm::IndividualEndDate], $postVars[CheckfrontLinkGeneratorForm::LinkTypeFieldName], CheckfrontModule::UserTypeIndividual, $postVars[CheckfrontLinkGeneratorForm::PaymentTypeFieldName]);
     $form = $this->buildLinkGeneratorForm();
     return $this->renderWith(array('CheckfrontLinkGenerator', 'Page'), array('ShowOutput' => true, 'Package' => $package, 'Posted' => new ArrayData($postVars), 'OrganiserLink' => $organiserLink, 'IndividualLink' => $individualLink, 'AccessKey' => $accessKey, 'CheckfrontForm' => $form));
 }
 /**
  * Handle a form submission.  GET and POST requests behave identically.
  * Populates the form with {@link loadDataFrom()}, calls {@link validate()},
  * and only triggers the requested form action/method
  * if the form is valid.
  *
  * @param SS_HTTPRequest $request
  * @throws SS_HTTPResponse_Exception
  */
 public function httpSubmission($request)
 {
     // Strict method check
     if ($this->strictFormMethodCheck) {
         // Throws an error if the method is bad...
         if ($this->formMethod != $request->httpMethod()) {
             $response = Controller::curr()->getResponse();
             $response->addHeader('Allow', $this->formMethod);
             $this->httpError(405, _t("Form.BAD_METHOD", "This form requires a " . $this->formMethod . " submission"));
         }
         // ...and only uses the variables corresponding to that method type
         $vars = $this->formMethod == 'GET' ? $request->getVars() : $request->postVars();
     } else {
         $vars = $request->requestVars();
     }
     // Populate the form
     $this->loadDataFrom($vars, true);
     // Protection against CSRF attacks
     $token = $this->getSecurityToken();
     if (!$token->checkRequest($request)) {
         $securityID = $token->getName();
         if (empty($vars[$securityID])) {
             $this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE", "There seems to have been a technical problem. Please click the back button, " . "refresh your browser, and try again."));
         } else {
             // Clear invalid token on refresh
             $data = $this->getData();
             unset($data[$securityID]);
             Session::set("FormInfo.{$this->FormName()}.data", $data);
             Session::set("FormInfo.{$this->FormName()}.errors", array());
             $this->sessionMessage(_t("Form.CSRF_EXPIRED_MESSAGE", "Your session has expired. Please re-submit the form."), "warning");
             return $this->controller->redirectBack();
         }
     }
     // Determine the action button clicked
     $funcName = null;
     foreach ($vars as $paramName => $paramVal) {
         if (substr($paramName, 0, 7) == 'action_') {
             // Break off querystring arguments included in the action
             if (strpos($paramName, '?') !== false) {
                 list($paramName, $paramVars) = explode('?', $paramName, 2);
                 $newRequestParams = array();
                 parse_str($paramVars, $newRequestParams);
                 $vars = array_merge((array) $vars, (array) $newRequestParams);
             }
             // Cleanup action_, _x and _y from image fields
             $funcName = preg_replace(array('/^action_/', '/_x$|_y$/'), '', $paramName);
             break;
         }
     }
     // If the action wasn't set, choose the default on the form.
     if (!isset($funcName) && ($defaultAction = $this->defaultAction())) {
         $funcName = $defaultAction->actionName();
     }
     if (isset($funcName)) {
         Form::set_current_action($funcName);
         $this->setButtonClicked($funcName);
     }
     // Permission checks (first on controller, then falling back to form)
     if ($this->controller->hasMethod($funcName) && !$this->controller->checkAccessAction($funcName) && !$this->actions->dataFieldByName('action_' . $funcName)) {
         return $this->httpError(403, sprintf('Action "%s" not allowed on controller (Class: %s)', $funcName, get_class($this->controller)));
     } elseif ($this->hasMethod($funcName) && !$this->checkAccessAction($funcName)) {
         return $this->httpError(403, sprintf('Action "%s" not allowed on form (Name: "%s")', $funcName, $this->name));
     }
     // TODO : Once we switch to a stricter policy regarding allowed_actions (meaning actions must be set
     // explicitly in allowed_actions in order to run)
     // Uncomment the following for checking security against running actions on form fields
     /* else {
     			// Try to find a field that has the action, and allows it
     			$fieldsHaveMethod = false;
     			foreach ($this->Fields() as $field){
     				if ($field->hasMethod($funcName) && $field->checkAccessAction($funcName)) {
     					$fieldsHaveMethod = true;
     				}
     			}
     			if (!$fieldsHaveMethod) {
     				return $this->httpError(
     					403,
     					sprintf('Action "%s" not allowed on any fields of form (Name: "%s")', $funcName, $this->Name())
     				);
     			}
     		}*/
     // Validate the form
     if (!$this->validate()) {
         return $this->getValidationErrorResponse();
     }
     // First, try a handler method on the controller (has been checked for allowed_actions above already)
     if ($this->controller->hasMethod($funcName)) {
         return $this->controller->{$funcName}($vars, $this, $request);
         // Otherwise, try a handler method on the form object.
     } elseif ($this->hasMethod($funcName)) {
         return $this->{$funcName}($vars, $this, $request);
     } elseif ($field = $this->checkFieldsForAction($this->Fields(), $funcName)) {
         return $field->{$funcName}($vars, $this, $request);
     }
     return $this->httpError(404);
 }
 /**
  * Update the order form cart, called via AJAX with current order form data.
  * Renders the cart and sends that back for displaying on the order form page.
  * 
  * @param SS_HTTPRequest $data Form data sent via AJAX POST.
  * @return String Rendered cart for the order form, template include 'CheckoutFormOrder'.
  */
 function updateOrderFormCart(SS_HTTPRequest $data)
 {
     if ($data->isPOST()) {
         $fields = array();
         $validator = new OrderFormValidator();
         $member = Customer::currentUser() ? Customer::currentUser() : singleton('Customer');
         $order = CartControllerExtension::get_current_order();
         //Update the Order
         $order->addAddressesAtCheckout($data->postVars());
         $order->addModifiersAtCheckout($data->postVars());
         //TODO update personal details, notes and payment type?
         //Create the part of the form that displays the Order
         $this->addItemFields($fields, $validator, $order);
         $this->addModifierFields($fields, $validator, $order);
         //This is going to go through and add modifiers based on current Form DATA
         //TODO This should be constructed for non-dropdown fields as well
         //Update modifier form fields so that the dropdown values are correct
         $newModifierData = array();
         $subTotalModifiers = isset($fields['SubTotalModifiers']) ? $fields['SubTotalModifiers'] : array();
         $totalModifiers = isset($fields['Modifiers']) ? $fields['Modifiers'] : array();
         $modifierFields = array_merge($subTotalModifiers, $totalModifiers);
         foreach ($modifierFields as $field) {
             if (method_exists($field, 'updateValue')) {
                 $field->updateValue($order);
             }
             $modifierClassName = get_class($field->getModifier());
             $newModifierData['Modifiers'][$modifierClassName] = $field->Value();
         }
         //Add modifiers to the order again so that the new values are used
         $order->addModifiersAtCheckout($newModifierData);
         $actions = new FieldSet(new FormAction('ProcessOrder', _t('CheckoutPage.PROCEED_TO_PAY', "Proceed to pay")));
         $form = new CheckoutForm($this, 'OrderForm', $fields, $actions, $validator, $order);
         $form->disableSecurityToken();
         $form->validate();
         return $form->renderWith('CheckoutFormOrder');
     }
 }
 /**
  * We intercept the submit handler since we have to alter some field
  * checks depending on the status of the field "InvoiceAddressAsShippingAddress".
  *
  * @param SS_HTTPRequest $data submit data
  * @param Form           $form form object
  *
  * @return ViewableData
  *
  * @author Sascha Koehler <*****@*****.**>,
  *         Sebastian Diel <*****@*****.**>
  * @since 20.01.2014
  */
 public function submit($data, $form)
 {
     // Disable the check instructions if the shipping address shall be
     // the same as the invoice address.
     if ($data['InvoiceAddressAsShippingAddress'] == '1') {
         $this->deactivateValidationFor('Shipping_Salutation');
         $this->deactivateValidationFor('Shipping_AcademicTitle');
         $this->deactivateValidationFor('Shipping_FirstName');
         $this->deactivateValidationFor('Shipping_Surname');
         $this->deactivateValidationFor('Shipping_Addition');
         $this->deactivateValidationFor('Shipping_Street');
         $this->deactivateValidationFor('Shipping_StreetNumber');
         $this->deactivateValidationFor('Shipping_Postcode');
         $this->deactivateValidationFor('Shipping_City');
         $this->deactivateValidationFor('Shipping_PhoneAreaCode');
         $this->deactivateValidationFor('Shipping_Phone');
         $this->deactivateValidationFor('Shipping_Country');
     }
     $formData = $data->postVars();
     if ($this->UseMinimumAgeToOrder()) {
         $formData['Birthday'] = $formData['BirthdayYear'] . '-' . $formData['BirthdayMonth'] . '-' . $formData['BirthdayDay'];
         if (!SilvercartConfig::CheckMinimumAgeToOrder($formData['Birthday'])) {
             $this->errorMessages['BirthdayDay'] = array('message' => SilvercartConfig::MinimumAgeToOrderError(), 'fieldname' => _t('SilvercartPage.BIRTHDAY') . ' - ' . _t('SilvercartPage.DAY'), 'BirthdayDay' => array('message' => SilvercartConfig::MinimumAgeToOrderError()));
             $this->errorMessages['BirthdayMonth'] = array('message' => SilvercartConfig::MinimumAgeToOrderError(), 'fieldname' => _t('SilvercartPage.BIRTHDAY') . ' - ' . _t('SilvercartPage.MONTH'), 'BirthdayMonth' => array('message' => SilvercartConfig::MinimumAgeToOrderError()));
             $this->errorMessages['BirthdayYear'] = array('message' => SilvercartConfig::MinimumAgeToOrderError(), 'fieldname' => _t('SilvercartPage.BIRTHDAY') . ' - ' . _t('SilvercartPage.YEAR'), 'BirthdayYear' => array('message' => SilvercartConfig::MinimumAgeToOrderError()));
             $this->setSubmitSuccess(false);
             return $this->submitFailure($data, $form);
         }
     }
     parent::submit($data, $form);
 }
 /**
  * Generates a fake request for the field
  * @param {SS_HTTPRequest} $request Source Request to base the fake request off of
  * @param {Widget} $sourceWidget Source widget
  * @param {string} $baseLink Base URL to be truncated off of the form
  * @return {SS_HTTPRequest} Fake HTTP Request used to fool the form field into thinking the request was made to it directly
  */
 protected function getFakeRequest(SS_HTTPRequest $request, Widget $sourceWidget, $baseLink)
 {
     $fieldName = rawurldecode($request->param('FieldName'));
     $objID = preg_replace('/Widget\\[(.*?)\\]\\[(.*?)\\]\\[(.*?)\\]$/', '$2', $fieldName);
     $finalPostVars = array();
     if ($request->isPOST()) {
         $postVars = $request->postVars();
         //Pull the post data for the widget
         if (isset($postVars['Widget'][$this->getName()][$objID])) {
             $finalPostVars = $postVars['Widget'][$this->getName()][$objID];
         } else {
             $finalPostVars = array();
         }
         $finalPostVars = array_merge($finalPostVars, $postVars);
         unset($finalPostVars['Widget']);
         //Workaround for UploadField's and GridFields confusing the request
         $fields = $sourceWidget->getCMSFields();
         $uploadFields = array();
         $gridFields = array();
         foreach ($fields as $field) {
             if ($field instanceof UploadField) {
                 $uploadFields[] = $field->getName();
             } else {
                 if ($field instanceof GridField) {
                     $gridFields[] = $field->getName();
                 }
             }
         }
         //Re-orgazine the upload field data
         if (count($uploadFields)) {
             foreach ($uploadFields as $field) {
                 $formFieldName = 'Widget[' . $this->getName() . '][' . $objID . '][' . $field . ']';
                 $fieldData = array($formFieldName => array('name' => array('Uploads' => array()), 'type' => array('Uploads' => array()), 'tmp_name' => array('Uploads' => array()), 'error' => array('Uploads' => array()), 'size' => array('Uploads' => array())));
                 if (isset($postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads'])) {
                     for ($i = 0; $i < count($postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads']); $i++) {
                         $fieldData[$formFieldName]['name']['Uploads'][] = $postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['type']['Uploads'][] = $postVars['Widget']['type'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['tmp_name']['Uploads'][] = $postVars['Widget']['tmp_name'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['error']['Uploads'][] = $postVars['Widget']['error'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['size']['Uploads'][] = $postVars['Widget']['size'][$this->getName()][$objID][$field]['Uploads'][$i];
                     }
                 }
                 $finalPostVars = array_merge_recursive($finalPostVars, $fieldData);
             }
         }
         //Reorganize the gridfield data
         if (count($gridFields) && isset($postVars['Widget'][$this->getName()][$objID])) {
             foreach ($gridFields as $field) {
                 $formFieldName = 'Widget[' . $this->getName() . '][' . $objID . '][' . $field . ']';
                 $fieldData = array($formFieldName => $postVars['Widget'][$this->getName()][$objID][$field]);
             }
             $finalPostVars = array_merge_recursive($finalPostVars, $fieldData);
         }
     }
     $headers = $request->getHeaders();
     $request = new SS_HTTPRequest($_SERVER['REQUEST_METHOD'], str_replace(rtrim($baseLink, '/'), '', rtrim($request->getURL(), '/')) . '/', $request->getVars(), $finalPostVars, $request->getBody());
     $request->match('$Action/$ID/$OtherID');
     //Merge in the headers
     foreach ($headers as $header => $value) {
         $request->addHeader($header, $value);
     }
     return $request;
 }
 /**
  * Action to do a login
  * 
  * @param SS_HTTPRequest $request    Request to check for product data
  * @param bool           $doRedirect Redirect after setting search settings?
  * 
  * @return void
  *
  * @author Sebastian Diel <*****@*****.**>
  * @since 30.06.2014
  */
 public function doLogin(SS_HTTPRequest $request, $doRedirect = true)
 {
     $postVars = $request->postVars();
     $emailAddress = $postVars['emailaddress'];
     $password = $postVars['password'];
     $member = Member::get()->filter('Email', $emailAddress)->first();
     if ($member instanceof Member && $member->exists()) {
         $customer = MemberAuthenticator::authenticate(array('Email' => $emailAddress, 'Password' => $password));
         if ($customer instanceof Member && $customer->exists()) {
             //transfer cart positions from an anonymous user to the one logging in
             $anonymousCustomer = SilvercartCustomer::currentAnonymousCustomer();
             if ($anonymousCustomer) {
                 if ($anonymousCustomer->getCart()->SilvercartShoppingCartPositions()->count() > 0) {
                     //delete registered customers cart positions
                     if ($customer->getCart()->SilvercartShoppingCartPositions()) {
                         foreach ($customer->getCart()->SilvercartShoppingCartPositions() as $position) {
                             $position->delete();
                         }
                     }
                     //add anonymous positions to the registered user
                     foreach ($anonymousCustomer->getCart()->SilvercartShoppingCartPositions() as $position) {
                         $customer->getCart()->SilvercartShoppingCartPositions()->add($position);
                     }
                 }
                 $anonymousCustomer->logOut();
                 $anonymousCustomer->delete();
             }
             $customer->logIn();
             $customer->write();
         } else {
             $messages = array('Authentication' => array('message' => _t('SilvercartPage.CREDENTIALS_WRONG')));
         }
     } else {
         $messages = array('Authentication' => array('message' => _t('SilvercartPage.CREDENTIALS_WRONG')));
     }
     $this->redirectBack($postVars['redirect_to']);
 }
 /**
  * Populates the form somewhat intelligently
  * @param SS_HTTPRequest $request Any request
  * @param Member $member Any member
  * @param array $required Any validation messages
  * @return $this
  */
 public function populateFromSources(SS_HTTPRequest $request = null, Member $member = null, array $required = null)
 {
     $dataPath = "FormInfo.{$this->FormName()}.data";
     if (isset($member)) {
         $this->loadDataFrom($member);
     } else {
         if (isset($request)) {
             $this->loadDataFrom($request->postVars());
         } else {
             if (Session::get($dataPath)) {
                 $this->loadDataFrom(Session::get($dataPath));
             } else {
                 if ($failover = $this->getSessionData()) {
                     $this->loadDataFrom($failover);
                 }
             }
         }
     }
     if (!empty($required)) {
         $this->setRequiredFields($required);
     }
     return $this;
 }
 /**
  * -    setup session in checkfront
  * -    add package to session
  * -    add items to session
  * -    call the 'book' endpoint to make the booking
  *
  * @param SS_HTTPRequest $request
  *
  * @return CheckfrontForm
  */
 protected function book(SS_HTTPRequest $request)
 {
     $message = '';
     $messageType = '';
     $result = array();
     // only post request should route here
     $postVars = $request->postVars();
     try {
         $this->clearCheckfrontSession();
         $packageID = $this->getTokenInfo(CheckfrontModule::TokenItemIDIndex, $postVars[CheckfrontForm::AccessKeyFieldName]);
         if ($request->isPOST()) {
             $startDate = $request->postVar('StartDate');
             $endDate = $request->postVar('EndDate');
             $ratedPackageResponse = $this->api()->fetchPackage($packageID, $startDate, $endDate);
             if ($ratedPackageResponse->isValid()) {
                 $package = $ratedPackageResponse->getPackage();
                 $this->api()->addPackageToSession($package);
                 foreach ($postVars['ItemID'] as $index => $itemID) {
                     if (isset($postVars['Quantity'][$index])) {
                         if ($quantity = $postVars['Quantity'][$index]) {
                             /**
                              * CheckfrontAPIItemResponse
                              */
                             $response = $this->api()->fetchItem($itemID, $quantity, $startDate, $endDate);
                             if ($response->isValid()) {
                                 if ($item = $response->getItem()) {
                                     $this->api()->addItemToSession($item);
                                 }
                             } else {
                                 throw new CheckfrontBookingException($response->getMessage(), CheckfrontException::TypeError);
                             }
                         }
                     }
                 }
                 $bookingResponse = $this->api()->makeBooking(CheckfrontBookingModel::create_from_checkfront($postVars, 'from-form'));
                 if ($bookingResponse->isValid()) {
                     $paymentMethod = $this->getTokenInfo(CheckfrontModule::TokenPaymentTypeIndex, $postVars[CheckfrontForm::AccessKeyFieldName]);
                     if ($paymentMethod == CheckfrontModule::PaymentPayNow) {
                         $message = 'Thanks for booking, please click the link below to complete payment on your booking';
                         $messageType = CheckfrontException::TypeOK;
                         if ($paymentURL = $bookingResponse->getPaymentURL()) {
                             $result = array('PaymentURL' => $paymentURL);
                             $this()->redirect($paymentURL);
                         }
                     } else {
                         $message = 'Thanks for booking, you will receive email confirmation shortly';
                         $messageType = CheckfrontException::TypeOK;
                         $result = array('CurrentPackage' => $package, 'Booking' => $bookingResponse->getBooking(), 'Items' => $bookingResponse->getItems());
                     }
                 } else {
                     throw new CheckfrontBookingException($bookingResponse->getMessage(), CheckfrontException::TypeError);
                 }
             }
         }
     } catch (CheckfrontException $e) {
         $message = $e->getMessage();
         $messageType = $e->getType();
         $this->api()->clearSession();
         Session::setFormMessage(CheckfrontPackageBookingForm::FormName, $message, 'bad');
         $result = $this->buildBookingForm($request);
     }
     return array_merge(array(self::MessageKey => $message, self::MessageTypeKey => $messageType), $result);
 }
 /**
  * handleGatewayResponse
  * This action should be used when a gateway submits a POST/GET response
  * for which we need to action. In this case, the PayPal IPN. We shall
  * return void as nothing is returned from this method. It is not public
  * facing and is present to handle system to system communications over 
  * HTTP communications only. If the gateway doesn't support POST/GET type
  * responses, implement the back office order updating within the
  * newPaymentSuccess() method instead.
  *
  * ATTRIBUTION
  * Snippets of IPN code were used from PayPal's GitHub samples on 15-10-2015.
  * https://github.com/paypal/ipn-code-samples/blob/master/paypal_ipn.php
  * @author PayPal 
  * 
  * @param SS_HTTPRequest $request The GET/POST variables and URL parameters.
  * @return Void
  */
 public function handleGatewayResponse($request)
 {
     /**
      * Only proceed if we have postVars set
      */
     if ($request->postVars()) {
         $gateway = DataObject::get_one("Gateway_PayPal");
         $debug = $gateway->Debug;
         /**
          * STEP ONE 
          * Prepend cmd=_notify-validate to the POST request from PayPal.
          * Reading posted data direction from $request->postVars() may
          * cause serialization isusues with array data. We therefore
          * will read directly from the input stream instead.
          */
         $raw_post_data = file_get_contents('php://input');
         $raw_post_array = explode('&', $raw_post_data);
         $myPost = array();
         foreach ($raw_post_array as $keyval) {
             $keyval = explode('=', $keyval);
             if (count($keyval) == 2) {
                 $myPost[$keyval[0]] = urldecode($keyval[1]);
             }
         }
         $req = 'cmd=_notify-validate';
         if (function_exists('get_magic_quotes_gpc')) {
             $get_magic_quotes_exists = true;
         }
         foreach ($myPost as $key => $value) {
             if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
                 $value = urlencode(stripslashes($value));
             } else {
                 $value = urlencode($value);
             }
             $req .= "&{$key}={$value}";
         }
         /**
          * STEP TWO
          * Which PayPal URL are we dealing with?
          */
         if (DataObject::get_one("Gateway_PayPal")->Sandbox) {
             $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
         } else {
             $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
         }
         /**
          * STEP THREE
          * Initiate curl IPN callback to post IPN data back to PayPal
          * to validate the IPN data is genuine. Without this step anyone
          * can fake IPN data and mess with your order system.
          */
         $ch = curl_init($paypal_url);
         if ($ch == FALSE) {
             return FALSE;
         }
         /* Set curl Options */
         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
         curl_setopt($ch, CURLOPT_POST, 1);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
         curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
         curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
         /* Set TCP timeout to 30 seconds */
         curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
         curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
         /* Execute Curl and Store Response in $res */
         $res = curl_exec($ch);
         /* Are there curl errors? If yes, log them if Debug is enabled. */
         if (curl_errno($ch) != 0) {
             if ($debug == 1) {
                 $this->newLogEntry("Can't connect to PayPal to validate IPN message: " . curl_error($ch));
             }
             curl_close($ch);
             exit;
             /* No errors */
         } else {
             /* If Debug is enabled, save to the log. */
             if ($debug == 1) {
                 $this->newLogEntry("HTTP request of validation request" . curl_getinfo($ch, CURLINFO_HEADER_OUT) . " for IPN payload: {$req}");
                 $this->newLogEntry("HTTP response of validation request: {$res}");
             }
             curl_close($ch);
         }
         /**
          * STEP FOUR
          * Inspect IPN validation result and act accordingly.
          * 1 - Split response headers and payload, a better way for strcmp.
          * 2 - Do the actions, based on response. 
          */
         $tokens = explode("\r\n\r\n", trim($res));
         $res = trim(end($tokens));
         if (strcmp($res, "VERIFIED") == 0) {
             /**
              * DEBUG
              * If debug is enabled, log the details
              * of this IPN response. 
              */
             if ($debug) {
                 $this->newLogEntry("Verified IPN: {$req} ");
             }
             /**
              * ERROR CHECK 1
              * txn_type must be of type 'web_accept'. (Buy Now Button) 
              */
             if (!$request->postVar("txn_type") == "web_accept") {
                 if ($debug == 1) {
                     $this->newLogEntry("ERROR: (txn_id: " . $request->postVar("txn_id") . ") txn_type is not of type 'web_accept'.");
                 }
                 return Store_Controller::create()->httpError(400);
                 exit;
             }
             /** 
              * ERROR CHECK 2
              * We must be the intended recipient for the transaction. 
              */
             if ($gateway->EmailAddress != $request->postVar("receiver_email")) {
                 if ($debug == 1) {
                     $this->newLogEntry("ERROR: (txn_id: " . $request->postVar("txn_id") . ") Intended recipient " . "(" . $request->postVar("receiver_email") . ") does not " . "match that set in the gateway settings.");
                 }
                 return Store_Controller::create()->httpError(400);
                 exit;
             }
             /**
              * ERROR CHECK 3
              * An order related to this payment must exist. 
              */
             $order = new SQLQuery("COUNT(*)");
             $order->setFrom("`order`")->addWhere("(`id`='" . $request->postVar("custom") . "')");
             if ($order->execute()->value() < 1) {
                 if ($debug == 1) {
                     $this->newLogEntry("ERROR: (txn_id: " . $request->postVar("txn_id") . ") The order number defined in 'custom' " . "(" . $request->postVar("custom") . ") does not exist in the system.");
                 }
                 return Store_Controller::create()->httpError(400);
                 exit;
             }
             /**
              * ERROR CHECK 4
              * This IPN message can not be a duplicate. 
              */
             $dup = new SQLQuery("COUNT(*)");
             $dup->setFrom("`Order_Payment_PayPal`");
             $dup->addWhere("(`txn_id`='" . $request->postVar("txn_id") . "') AND (`payment_status`='" . $request->postVar("payment_status") . "')");
             $dup_count = $dup->execute()->value();
             if ($dup_count > 0) {
                 if ($debug == 1) {
                     $this->newLogEntry("ERROR: (txn_id: " . $request->postVar("txn_id") . ") The IPN message received is a duplicate of one " . "previously received.");
                 }
                 return Store_Controller::create()->httpError(400);
                 exit;
             }
             /** 
              * ERROR CHECK 5
              * The mc_gross has to match the total order price. 
              */
             $order_total = DataObject::get_by_id("Order", $request->postVar("custom"))->calculateOrderTotal();
             $mc_gross = $request->postVar("mc_gross");
             if ($order_total != $mc_gross) {
                 if ($debug == 1) {
                     $this->newLogEntry("ERROR: (txn_id: " . $request->postVar("txn_id") . ") The payment amount did not match the order amount.");
                 }
                 return Store_Controller::create()->httpError(400);
                 exit;
             }
             /**
              * ERROR CHECK 6
              * If this IPN is not a duplicate, are there
              * any other entries for this txn_id?
              */
             if ($dup_count < 1) {
                 /* Count how many entries there are with the IPNs txn_id */
                 $record_count = new SQLQuery("COUNT(*)");
                 $record_count->setFrom("Order_Payment_PayPal");
                 $record_count->addWhere("(`txn_id`='" . $request->postVar("txn_id") . "')");
                 $record_count = $record_count->execute()->value();
                 /* The row ID for the record that was found, if one exists */
                 $payment_record_id = new SQLQuery("`id`");
                 $payment_record_id->setFrom("Order_Payment_PayPal")->addWhere("(`txn_id`='" . $request->postVar("txn_id") . "')");
                 $payment_record_id = $payment_record_id->execute()->value();
             }
             /**
              * VERIFIED STEP ONE 
              * 
              * Either create a payment record or update an existing one an send the applicable emails.
              */
             switch ($request->postVar("payment_status")) {
                 /* Payment has cleared, order can progress. */
                 case "Completed":
                     //Send email to admin notification email address
                     Order_Emails::create()->adminNewOrderNotification($request->postVar("custom"));
                     //Send email to the customer confirming their order, if they haven't had one already.
                     Order_Emails::create()->customerNewOrderConfirmation($request->postVar("custom"));
                     if ($record_count > 0) {
                         $this->updatePaymentRecord($request, $payment_record_id, "Completed", "Processing");
                     } else {
                         $this->newPaymentRecord($request, "Completed", "Processing");
                     }
                     break;
                     /* The payment is pending. See pending_reason for more information.	*/
                 /* The payment is pending. See pending_reason for more information.	*/
                 case "Pending":
                     /**
                      * We don't send emails for this status as 'Pending' orders are still awaiting a response from
                      * a payment gateway and should not be dispatched. It is safe to send a confirmation email to
                      * the customer, however.
                      */
                     //Send email to the customer confirming their order is currently pending
                     Order_Emails::create()->customerNewOrderConfirmation($request->postVar("custom"), "Pending");
                     if ($record_count > 0) {
                         $this->updatePaymentRecord($request, $payment_record_id, "Pending", "Pending / Awaiting Payment");
                     } else {
                         $this->newPaymentRecord($request, "Pending", "Pending / Awaiting Payment");
                     }
                     break;
                     /* You refunded the payment. */
                 /* You refunded the payment. */
                 case "Refunded":
                     /* Notify the customer of a change to their order status */
                     Order_Emails::create()->customerOrderStatusUpdate($request->postVar("custom"), "Refunded");
                     if ($record_count > 0) {
                         $this->updatePaymentRecord($request, $payment_record_id, "Refunded", "Refunded");
                     } else {
                         $this->newPaymentRecord($request, "Refunded", "Refunded");
                     }
                     break;
                     /**
                      * A payment was reversed due to a chargeback or other type of reversal.
                      * The funds have been removed from your account balance and returned to the buyer.
                      * The reason for the reversal is specified in the ReasonCode element.
                      */
                 /**
                  * A payment was reversed due to a chargeback or other type of reversal.
                  * The funds have been removed from your account balance and returned to the buyer.
                  * The reason for the reversal is specified in the ReasonCode element.
                  */
                 case "Reversed":
                     /* Notify the admin that an order has had an order has been reversed */
                     /* Notify the customer of a change to their order status */
                     Order_Emails::create()->customerOrderStatusUpdate($request->postVar("custom"), "Cancelled");
                     if ($record_count > 0) {
                         $this->updatePaymentRecord($request, $payment_record_id, "Refunded", "Cancelled");
                     } else {
                         $this->newPaymentRecord($request, "Refunded", "Cancelled");
                     }
                     break;
                     /* The reveral was cancelled */
                 /* The reveral was cancelled */
                 case "Canceled_Reversal":
                     /* Notify an admin that an order reversal has been cancelled */
                     /**
                      * We don't send customers an email update for this status as it might
                      * cause confustion.
                      */
                     /**
                      * For canceled reversals, lets set the order to Pending as an admin will need to manually review it.
                      * we don't want it to fall in the standard Processing queue as goods could be shipped twice.
                      */
                     if ($record_count > 0) {
                         $this->updatePaymentRecord($request, $payment_record_id, "Pending", "Pending / Awaiting Payment");
                     } else {
                         $this->newPaymentRecord($request, "Pending", "Pending / Awaiting Payment");
                     }
                     break;
                     /* This authorization has been voided. */
                 /* This authorization has been voided. */
                 case "Voided":
                     /* Notify the customer of a change to their order status */
                     Order_Emails::create()->customerOrderStatusUpdate($request->postVar("custom"), "Cancelled");
                     if ($record_count > 0) {
                         $this->updatePaymentRecord($request, $payment_record_id, "Refunded", "Cancelled");
                     } else {
                         $this->newPaymentRecord($request, "Refunded", "Cancelled");
                     }
                     break;
                     /**
                      * The payment has failed.
                      */
                 /**
                  * The payment has failed.
                  */
                 case "Failed":
                     /* Notify the customer of a change to their order status */
                     Order_Emails::create()->customerOrderStatusUpdate($request->postVar("custom"), "Cancelled");
                     if ($record_count > 0) {
                         $this->updatePaymentRecord($request, $payment_record_id, "Refunded", "Cancelled");
                     } else {
                         $this->newPaymentRecord($request, "Refunded", "Cancelled");
                     }
                     break;
                     /* Other IPN statuses are ignored. */
                 /* Other IPN statuses are ignored. */
                 default:
                     exit;
                     break;
             }
         } elseif (strcmp($res, "INVALID") == 0) {
             $status = "INVALID";
             // log for manual investigation
             // Add business logic here which deals with invalid IPN messages
             /* If Debug is enabled, log response */
             if ($debug == 1) {
                 error_log(date('[Y-m-d H:i e] ') . "Invalid IPN: {$req}" . PHP_EOL, 3, "../ipn.log");
             }
         }
     }
 }
 public function modifiedUpload(SS_HTTPRequest $request)
 {
     if ($this->isDisabled() || $this->isReadonly() || !$this->canUpload()) {
         return $this->httpError(403);
     }
     // Protect against CSRF on destructive action
     $token = $this->getForm()->getSecurityToken();
     //if(!$token->checkRequest($request)) return $this->httpError(400);
     $name = $this->getName();
     $contentFieldName = $this->contentModuleFieldName;
     $postVars = $request->postVars();
     $tmpfile = $request->postVar('ContentModule');
     $record = $this->getRecord();
     // Check if the file has been uploaded into the temporary storage.
     if (!$tmpfile) {
         $return = array('error' => _t('UploadField.FIELDNOTSET', 'File information not found'));
     } else {
         $return = array('name' => $tmpfile['name'][$this->getRecord()->ID][$name], 'size' => $tmpfile['size'][$this->getRecord()->ID][$name], 'type' => $tmpfile['type'][$this->getRecord()->ID][$name], 'error' => $tmpfile['error'][$this->getRecord()->ID][$name], 'tmp_name' => $tmpfile['tmp_name'][$this->getRecord()->ID][$name]);
     }
     // Check for constraints on the record to which the file will be attached.
     if (!$return['error'] && $this->relationAutoSetting && $record && $record->exists()) {
         $tooManyFiles = false;
         // Some relationships allow many files to be attached.
         if ($this->getConfig('allowedMaxFileNumber') && ($record->has_many($name) || $record->many_many($name))) {
             if (!$record->isInDB()) {
                 $record->write();
             }
             $tooManyFiles = $record->{$name}()->count() >= $this->getConfig('allowedMaxFileNumber');
             // has_one only allows one file at any given time.
         } elseif ($record->has_one($name)) {
             // If we're allowed to replace an existing file, clear out the old one
             if ($record->{$name} && $this->getConfig('replaceExistingFile')) {
                 $record->{$name} = null;
             }
             $tooManyFiles = $record->{$name}() && $record->{$name}()->exists();
         }
         // Report the constraint violation.
         if ($tooManyFiles) {
             if (!$this->getConfig('allowedMaxFileNumber')) {
                 $this->setConfig('allowedMaxFileNumber', 1);
             }
             $return['error'] = _t('UploadField.MAXNUMBEROFFILES', 'Max number of {count} file(s) exceeded.', array('count' => $this->getConfig('allowedMaxFileNumber')));
         }
     }
     // Process the uploaded file
     if (!$return['error']) {
         $fileObject = null;
         if ($this->relationAutoSetting) {
             // Search for relations that can hold the uploaded files.
             if ($relationClass = $this->getRelationAutosetClass()) {
                 // Create new object explicitly. Otherwise rely on Upload::load to choose the class.
                 $fileObject = Object::create($relationClass);
             }
         }
         // Get the uploaded file into a new file object.
         try {
             $this->upload->loadIntoFile($return, $fileObject, $this->folderName);
         } catch (Exception $e) {
             // we shouldn't get an error here, but just in case
             $return['error'] = $e->getMessage();
         }
         if (!$return['error']) {
             if ($this->upload->isError()) {
                 $return['error'] = implode(' ' . PHP_EOL, $this->upload->getErrors());
             } else {
                 $file = $this->upload->getFile();
                 // Attach the file to the related record.
                 if ($this->relationAutoSetting) {
                     $this->attachFile($file);
                 }
                 // Collect all output data.
                 $file = $this->customiseFile($file);
                 $return = array_merge($return, array('id' => $file->ID, 'name' => $file->getTitle() . '.' . $file->getExtension(), 'url' => $file->getURL(), 'thumbnail_url' => $file->UploadFieldThumbnailURL, 'edit_url' => $file->UploadFieldEditLink, 'size' => $file->getAbsoluteSize(), 'buttons' => $file->UploadFieldFileButtons));
             }
         }
     }
     $response = new SS_HTTPResponse(Convert::raw2json(array($return)));
     $response->addHeader('Content-Type', 'text/plain');
     return $response;
 }
 /**
  * Passes the values from the SS_HTTPRequest object to the defined form;
  * missing values will be set to false
  *
  * during the transmission the values will become SQL secure
  *
  * @param SS_HTTPRequest $request the submitted data
  *
  * @return array
  *
  * @author Sebastian Diel <*****@*****.**>,
  *         Sascha Koehler <*****@*****.**>
  * @since 11.10.2016
  */
 public function getFormData($request)
 {
     $formData = array();
     $postVars = $request->postVars();
     if ($this->securityTokenEnabled) {
         $formData['SecurityID'] = Convert::raw2sql($postVars['SecurityID']);
     }
     // read defined form fields
     // Definierte Formularfelder auslesen
     foreach ($this->fieldGroups as $groupName => $groupFields) {
         foreach ($groupFields as $fieldName => $fieldDefinition) {
             if (array_key_exists($fieldName, $postVars)) {
                 $formData[$fieldName] = Convert::raw2sql($postVars[$fieldName]);
             } else {
                 $formData[$fieldName] = false;
             }
         }
     }
     // read dynamically added form fields
     // Dynamisch hinzugefuegte Formularfelder auslesen
     if (isset($this->customParameters)) {
         foreach ($this->customParameters as $customParameterKey => $customParameterValue) {
             if (isset($request[$customParameterKey])) {
                 $formData[$customParameterKey] = Convert::raw2sql($request[$customParameterKey]);
             } else {
                 $formData[$customParameterKey] = false;
             }
         }
     }
     return $formData;
 }
 /**
  * @param SS_HTTPRequest $request
  * @return SS_HTTPResponse
  */
 public function handleRequest(SS_HTTPRequest $request, DataModel $model = null)
 {
     self::$is_at_root = true;
     $this->setDataModel($model);
     $this->pushCurrent();
     $this->init();
     if (!DB::isActive() || !ClassInfo::hasTable('SiteTree')) {
         $this->response = new SS_HTTPResponse();
         $this->response->redirect(Director::absoluteBaseURL() . 'dev/build?returnURL=' . (isset($_GET['url']) ? urlencode($_GET['url']) : null));
         return $this->response;
     }
     $request = new SS_HTTPRequest($request->httpMethod(), self::get_homepage_link() . '/', $request->getVars(), $request->postVars());
     $request->match('$URLSegment//$Action', true);
     $controller = new ModelAsController();
     $result = $controller->handleRequest($request, $model);
     $this->popCurrent();
     return $result;
 }
Beispiel #19
0
 public function update(SS_HTTPRequest $request)
 {
     if ($request->isPOST()) {
         $member = Customer::currentUser() ? Customer::currentUser() : singleton('Customer');
         $order = Cart::get_current_order();
         //Update the Order
         $order->update($request->postVars());
         $order->updateModifications($request->postVars())->write();
         $form = OrderForm::create($this->controller, 'OrderForm')->disableSecurityToken();
         // $form->validate();
         return $form->renderWith('OrderFormCart');
     }
 }