/** * Render a resultswitcher page */ protected function handleResultRequest() { //no longer letting people in without these things. If this is //preventing you from doing something, you almost certainly want to be //somewhere else. $deadSession = false; if (!$this->adapter->session_hasDonorData()) { $deadSession = true; } $oid = $this->adapter->getData_Unstaged_Escaped('order_id'); $request = $this->getRequest(); $referrer = $request->getHeader('referer'); $liberated = false; if ($this->adapter->session_getData('order_status', $oid) === 'liberated') { $liberated = true; } // XXX need to know whether we were in an iframe or not. global $wgServer; if ($this->isReturnFramed() && strpos($referrer, $wgServer) === false && !$liberated) { $sessionOrderStatus = $request->getSessionData('order_status'); $sessionOrderStatus[$oid] = 'liberated'; $request->setSessionData('order_status', $sessionOrderStatus); $this->logger->info("Resultswitcher: Popping out of iframe for Order ID " . $oid); $this->getOutput()->allowClickjacking(); $this->getOutput()->addModules('iframe.liberator'); return; } $this->setHeaders(); if ($deadSession) { if ($this->adapter->isReturnProcessingRequired()) { wfHttpError(403, 'Forbidden', wfMessage('donate_interface-error-http-403')->text()); throw new RuntimeException('Resultswitcher: Request forbidden. No active donation in the session. ' . "Adapter Order ID: {$oid}"); } // If it's possible for a donation to go through without our // having to do additional processing in the result switcher, // we don't want to falsely claim it failed just because we // lost the session data. We also don't want to give any // information to scammers hitting this page with no session, // so we always show the thank you page. We don't want to do // any post-processing if we're not sure whether we actually // originated this attempt, so we return right after. $this->logger->warning('Resultswitcher: session is dead, but the ' . 'donor may have made a successful payment.'); $this->displayThankYouPage('dead session'); return; } $this->logger->info("Resultswitcher: OK to process Order ID: " . $oid); if ($this->adapter->checkTokens()) { $this->getOutput()->allowClickjacking(); // FIXME: do we really need this again? $this->getOutput()->addModules('iframe.liberator'); // processResponse expects some data, so let's feed it all the // GET and POST vars $response = $this->getRequest()->getValues(); // TODO: run the whole set of getResponseStatus, getResponseErrors // and getResponseData first. Maybe do_transaction with a // communication_type of 'incoming' and a way to provide the // adapter the GET/POST params harvested here. $this->adapter->processResponse($response); $status = $this->adapter->getFinalStatus(); switch ($status) { case FinalStatus::COMPLETE: case FinalStatus::PENDING: $this->displayThankYouPage($status); return; } $this->logger->info("Displaying fail page for final status {$status}"); } else { $this->logger->error("Resultswitcher: Token Check Failed. Order ID: {$oid}"); } $this->displayFailPage(); }