Ejemplo n.º 1
0
 /**
  * Handles returning a JSON response, makes sure Content-Type header is set
  *
  * @param array $array
  * @param bool $isJson Is the passed string already a json string
  * @return SS_HTTPResponse
  */
 public function jsonResponse($array, $isJson = false)
 {
     $json = $array;
     if (!$isJson) {
         $json = Convert::raw2json($array);
     }
     $response = new SS_HTTPResponse($json);
     $response->addHeader('Content-Type', 'application/json');
     $response->addHeader('Vary', 'Accept');
     return $response;
 }
Ejemplo n.º 2
0
 public function getGoogleMapPin(SS_HTTPRequest $request)
 {
     $color = Convert::raw2sql($request->param('Color'));
     $path = ASSETS_PATH . '/maps/pins';
     // create folder on assets if does not exists ....
     if (!is_dir($path)) {
         mkdir($path, $mode = 0775, $recursive = true);
     }
     // if not get it from google (default)
     $ping_url = "http://chart.apis.google.com/chart?cht=mm&chs=32x32&chco=FFFFFF,{$color},000000&ext=.png";
     $write_2_disk = true;
     if (file_exists($path . '/pin_' . $color . '.jpg')) {
         // if we have the file on assets use it
         $ping_url = $path . '/pin_' . $color . '.jpg';
         $write_2_disk = false;
     }
     $body = file_get_contents($ping_url);
     if ($write_2_disk) {
         file_put_contents($path . '/pin_' . $color . '.jpg', $body);
     }
     $ext = 'jpg';
     $response = new SS_HTTPResponse($body, 200);
     $response->addHeader('Content-Type', 'image/' . $ext);
     return $response;
 }
Ejemplo n.º 3
0
 public function testAddCacheHeaders()
 {
     $body = "<html><head></head><body><h1>Mysite</h1></body></html>";
     $response = new SS_HTTPResponse($body, 200);
     $this->assertEmpty($response->getHeader('Cache-Control'));
     HTTP::set_cache_age(30);
     HTTP::add_cache_headers($response);
     $this->assertNotEmpty($response->getHeader('Cache-Control'));
     // Ensure max-age is zero for development.
     Config::inst()->update('Director', 'environment_type', 'dev');
     $response = new SS_HTTPResponse($body, 200);
     HTTP::add_cache_headers($response);
     $this->assertContains('max-age=0', $response->getHeader('Cache-Control'));
     // Ensure max-age setting is respected in production.
     Config::inst()->update('Director', 'environment_type', 'live');
     $response = new SS_HTTPResponse($body, 200);
     HTTP::add_cache_headers($response);
     $this->assertContains('max-age=30', explode(', ', $response->getHeader('Cache-Control')));
     $this->assertNotContains('max-age=0', $response->getHeader('Cache-Control'));
     // Still "live": Ensure header's aren't overridden if already set (using purposefully different values).
     $headers = array('Vary' => '*', 'Pragma' => 'no-cache', 'Cache-Control' => 'max-age=0, no-cache, no-store');
     $response = new SS_HTTPResponse($body, 200);
     foreach ($headers as $name => $value) {
         $response->addHeader($name, $value);
     }
     HTTP::add_cache_headers($response);
     foreach ($headers as $name => $value) {
         $this->assertEquals($value, $response->getHeader($name));
     }
 }
Ejemplo n.º 4
0
 public function httpError($code, $message = null)
 {
     $response = new SS_HTTPResponse();
     $response->setStatusCode($code);
     $response->addHeader('Content-Type', 'text/html');
     return $response;
 }
 /**
  * Action to handle upload of a single file
  *
  * @param SS_HTTPRequest $request
  * @return SS_HTTPResponse
  * @return SS_HTTPResponse
  */
 public function upload(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);
     }
     // Get form details
     $name = $this->getName();
     $postVars = $request->postVar($name);
     // Save the temporary file into a File object
     $uploadedFiles = $this->extractUploadedFileData($postVars);
     $firstFile = reset($uploadedFiles);
     $file = $this->saveTemporaryFile($firstFile, $error);
     if (empty($file)) {
         $return = array('error' => $error);
     } else {
         $return = $this->encodeFileAttributes($file);
     }
     // Format response with json
     $response = new SS_HTTPResponse(Convert::raw2json(array($return)));
     $response->addHeader('Content-Type', 'text/plain');
     if (!empty($return['error'])) {
         $response->setStatusCode(200);
     }
     return $response;
 }
 /**
  * Returns the unread count in a JSONobject
  * 
  * @return SS_HTTPResponse
  */
 public function count()
 {
     $notifications = TimelineEvent::get_unread(Member::currentUser());
     $response = new SS_HTTPResponse(json_encode(array('count' => $notifications->count())), 200);
     $response->addHeader('Content-Type', 'application/json');
     return $response;
 }
 public function load($request)
 {
     $response = new SS_HTTPResponse();
     $response->addHeader('Content-Type', 'application/json');
     $response->setBody(Convert::array2json(array("_memberID" => Member::currentUserID())));
     return $response;
 }
 public function load($request)
 {
     $response = new SS_HTTPResponse();
     $response->addHeader('Content-Type', 'application/json');
     $response->setBody(Convert::array2json(call_user_func($this->source, $request->getVar('val'))));
     return $response;
 }
Ejemplo n.º 9
0
 /**
  * Use cURL to request a URL, and return a SS_HTTPResponse object.
  */
 protected function curlRequest($url, $method, $data = null, $headers = null, $curlOptions = array())
 {
     $ch = curl_init();
     $timeout = 5;
     $ssInfo = new SapphireInfo();
     $useragent = 'SilverStripe/' . $ssInfo->version();
     curl_setopt($ch, CURLOPT_URL, $url);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
     curl_setopt($ch, CURLOPT_HEADER, 1);
     if ($headers) {
         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
     }
     // Add fields to POST and PUT requests
     if ($method == 'POST') {
         curl_setopt($ch, CURLOPT_POST, 1);
         curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
     } elseif ($method == 'PUT') {
         $put = fopen("php://temp", 'r+');
         fwrite($put, $data);
         fseek($put, 0);
         curl_setopt($ch, CURLOPT_PUT, 1);
         curl_setopt($ch, CURLOPT_INFILE, $put);
         curl_setopt($ch, CURLOPT_INFILESIZE, strlen($data));
     }
     // Follow redirects
     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
     // Set any custom options passed to the request() function
     curl_setopt_array($ch, $curlOptions);
     // Run request
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
     $fullResponseBody = curl_exec($ch);
     $curlError = curl_error($ch);
     list($responseHeaders, $responseBody) = preg_split('/(\\n\\r?){2}/', $fullResponseBody, 2);
     if (preg_match("#^HTTP/1.1 100#", $responseHeaders)) {
         list($responseHeaders, $responseBody) = preg_split('/(\\n\\r?){2}/', $responseBody, 2);
     }
     $responseHeaders = explode("\n", trim($responseHeaders));
     array_shift($responseHeaders);
     $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     if ($curlError !== '' || $statusCode == 0) {
         $statusCode = 500;
     }
     $response = new SS_HTTPResponse($responseBody, $statusCode);
     foreach ($responseHeaders as $headerLine) {
         if (strpos($headerLine, ":") !== false) {
             list($headerName, $headerVal) = explode(":", $headerLine, 2);
             // This header isn't relevant outside of curlRequest
             if (strtolower($headerName) == 'transfer-encoding') {
                 continue;
             }
             $response->addHeader(trim($headerName), trim($headerVal));
         }
     }
     curl_close($ch);
     return $response;
 }
 /**
  * Creates and return the editing interface
  * 
  * @return string Form's HTML
  */
 public function index()
 {
     $form = $this->listForm();
     $form->setTemplate('LeftAndMain_EditForm');
     $form->addExtraClass('center cms-content');
     $form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
     if ($this->request->isAjax()) {
         $response = new SS_HTTPResponse(Convert::raw2json(array('Content' => $form->forAjaxTemplate()->getValue())));
         $response->addHeader('X-Pjax', 'Content');
         $response->addHeader('Content-Type', 'text/json');
         $response->addHeader('X-Title', 'SilverStripe - Bulk ' . $this->gridField->list->dataClass . ' Editing');
         return $response;
     } else {
         $controller = $this->getToplevelController();
         return $controller->customise(array('Content' => $form));
     }
 }
Ejemplo n.º 11
0
 function Places()
 {
     $Places = DataObject::get("Place");
     $body = $this->owner->customise(array('Places' => $Places))->renderWith("KMLPlaces");
     $response = new SS_HTTPResponse($body, 200);
     $response->addHeader('Content-type', "application/vnd.google-earth.kml+xml");
     return $response;
 }
 /**
  * Unlink the selected records passed from the unlink bulk action.
  * 
  * @param SS_HTTPRequest $request
  *
  * @return SS_HTTPResponse List of affected records ID
  */
 public function unLink(SS_HTTPRequest $request)
 {
     $ids = $this->getRecordIDList();
     $this->gridField->list->removeMany($ids);
     $response = new SS_HTTPResponse(Convert::raw2json(array('done' => true, 'records' => $ids)));
     $response->addHeader('Content-Type', 'text/json');
     return $response;
 }
 /**
  * Returns a JSON string of tags, for lazy loading.
  *
  * @param SS_HTTPRequest $request
  *
  * @return SS_HTTPResponse
  */
 public function suggest(SS_HTTPRequest $request)
 {
     $members = $this->getMembers($request->getVar('term'));
     $response = new SS_HTTPResponse();
     $response->addHeader('Content-Type', 'application/json');
     $response->setBody(json_encode($members));
     return $response;
 }
Ejemplo n.º 14
0
 /**
  * @param Object $originator
  * @param SS_HTTPRequest $request
  * @param SS_HTTPResponse $response
  * @param DataModel $model
  */
 public function applyToResponse($originator, SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model)
 {
     foreach ($this->headers as $key => $value) {
         if ($value !== "") {
             $response->addHeader($key, $value);
         } else {
             $response->removeHeader($key);
         }
     }
 }
 public function postRequest(\SS_HTTPRequest $request, \SS_HTTPResponse $response, \DataModel $model)
 {
     $time = sprintf('%.3f ms', microtime(true) - $this->start);
     $response->addHeader('X-SilverStripe-Time', $time);
     $b = $response->getBody();
     if (strpos($b, '</html>')) {
         $b = str_replace('</html>', "\n<!-- Generated in {$time} -->\n</html>", $b);
         $response->setBody($b);
     }
 }
 /**
  * Require basic authentication.  Will request a username and password if none is given.
  *
  * Used by {@link Controller::init()}.
  *
  * @throws SS_HTTPResponse_Exception
  *
  * @param string $realm
  * @param string|array $permissionCode Optional
  * @param boolean $tryUsingSessionLogin If true, then the method with authenticate against the
  *  session log-in if those credentials are disabled.
  * @return Member $member
  */
 public static function requireLogin($realm, $permissionCode = null, $tryUsingSessionLogin = true)
 {
     $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
     if (!Security::database_is_ready() || Director::is_cli() && !$isRunningTests) {
         return true;
     }
     /*
      * Enable HTTP Basic authentication workaround for PHP running in CGI mode with Apache
      * Depending on server configuration the auth header may be in HTTP_AUTHORIZATION or
      * REDIRECT_HTTP_AUTHORIZATION
      *
      * The follow rewrite rule must be in the sites .htaccess file to enable this workaround
      * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
      */
     $authHeader = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) ? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] : null);
     $matches = array();
     if ($authHeader && preg_match('/Basic\\s+(.*)$/i', $authHeader, $matches)) {
         list($name, $password) = explode(':', base64_decode($matches[1]));
         $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
         $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
     }
     $member = null;
     if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
         $member = MoreAdminsAuthenticator::authenticate(array('Email' => $_SERVER['PHP_AUTH_USER'], 'Password' => $_SERVER['PHP_AUTH_PW']), null);
     }
     if (!$member && $tryUsingSessionLogin) {
         $member = Member::currentUser();
     }
     // If we've failed the authentication mechanism, then show the login form
     if (!$member) {
         $response = new SS_HTTPResponse(null, 401);
         $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\"");
         if (isset($_SERVER['PHP_AUTH_USER'])) {
             $response->setBody(_t('BasicAuth.ERRORNOTREC', "That username / password isn't recognised"));
         } else {
             $response->setBody(_t('BasicAuth.ENTERINFO', "Please enter a username and password."));
         }
         // Exception is caught by RequestHandler->handleRequest() and will halt further execution
         $e = new SS_HTTPResponse_Exception(null, 401);
         $e->setResponse($response);
         throw $e;
     }
     if ($permissionCode && !Permission::checkMember($member->ID, $permissionCode)) {
         $response = new SS_HTTPResponse(null, 401);
         $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\"");
         if (isset($_SERVER['PHP_AUTH_USER'])) {
             $response->setBody(_t('BasicAuth.ERRORNOTADMIN', "That user is not an administrator."));
         }
         // Exception is caught by RequestHandler->handleRequest() and will halt further execution
         $e = new SS_HTTPResponse_Exception(null, 401);
         $e->setResponse($response);
         throw $e;
     }
     return $member;
 }
 public function getAndroidAssetLinksFile(SS_HTTPRequest $request)
 {
     global $APP_LINKS_ANDROID_FILE_CONFIG;
     $file = [];
     foreach ($APP_LINKS_ANDROID_FILE_CONFIG as $package => $fingerprints) {
         $file[] = ["relation" => ["delegate_permission/common.handle_all_urls"], "target" => ["namespace" => "android_app", "package_name" => $package, "sha256_cert_fingerprints" => $fingerprints]];
     }
     $response = new SS_HTTPResponse(json_encode($file), 200);
     $response->addHeader('Content-Type', 'application/json; charset=utf-8');
     return $response;
 }
Ejemplo n.º 18
0
 /**
  * Generates the response containing the robots.txt content
  * 
  * @return SS_HTTPResponse
  */
 public function index()
 {
     $text = "";
     $text .= $this->renderSitemap();
     $text .= "User-agent: *\n";
     $text .= $this->renderDisallow();
     $text .= $this->renderAllow();
     $response = new SS_HTTPResponse($text, 200);
     $response->addHeader("Content-Type", "text/plain; charset=\"utf-8\"");
     return $response;
 }
 /**
  * Delete the selected records passed from the delete bulk action.
  * 
  * @param SS_HTTPRequest $request
  *
  * @return SS_HTTPResponse List of deleted records ID
  */
 public function delete(SS_HTTPRequest $request)
 {
     $ids = array();
     foreach ($this->getRecords() as $record) {
         array_push($ids, $record->ID);
         $record->delete();
     }
     $response = new SS_HTTPResponse(Convert::raw2json(array('done' => true, 'records' => $ids)));
     $response->addHeader('Content-Type', 'text/json');
     return $response;
 }
 public function handleAssignBulkAction($gridField, $request)
 {
     $entity_id = $request->param('EntityID');
     $controller = $gridField->getForm()->Controller();
     $this->gridField = $gridField;
     $ids = $this->getRecordIDList();
     $this->processRecordIds($ids, $entity_id, $gridField, $request);
     $response = new SS_HTTPResponse(Convert::raw2json(array('done' => true, 'records' => $ids)));
     $response->addHeader('Content-Type', 'text/json');
     $response->setStatusCode(200);
     return $response;
 }
 public function postRequest(\SS_HTTPRequest $request, \SS_HTTPResponse $response, \DataModel $model)
 {
     if ($request->getVar('clear') && Member::currentUserID() && Permission::check('ADMIN')) {
         $key = trim($request->getVar('url'), '/');
         $key = (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '') . '/' . $key;
         $item = $this->dynamicCache->get($key);
         if ($item) {
             $response->addHeader('X-SilverStripe-Cache', 'deleted ' . $key);
             $this->dynamicCache->delete($key);
         }
     }
 }
 /**
  * AJAX Json Response handler
  *
  * @param array|null $retVars
  * @param boolean $success
  * @return \SS_HTTPResponse
  */
 public function handleJsonResponse($success = false, $retVars = null)
 {
     $result = array();
     if ($success) {
         $result = array('success' => $success);
     }
     if ($retVars) {
         $result = array_merge($retVars, $result);
     }
     $response = new SS_HTTPResponse(json_encode($result));
     $response->addHeader('Content-Type', 'application/json');
     return $response;
 }
 /**
  * Unpublish the selected records passed from the unpublish bulk action
  *
  * @param SS_HTTPRequest $request
  * @return SS_HTTPResponse List of published record IDs
  */
 public function unpublish(SS_HTTPRequest $request)
 {
     $ids = array();
     foreach ($this->getRecords() as $record) {
         if ($record->hasExtension('Versioned')) {
             array_push($ids, $record->ID);
             $record->deleteFromStage(Versioned::get_live_stage());
         }
     }
     $response = new SS_HTTPResponse(Convert::raw2json(array('done' => true, 'records' => $ids)));
     $response->addHeader('Content-Type', 'text/json');
     return $response;
 }
Ejemplo n.º 24
0
 public function getMemberProfileImage(SS_HTTPRequest $request)
 {
     $member_id = intval($request->param('MemberID'));
     $member = Member::get()->byID($member_id);
     if (is_null($member)) {
         return $this->notFound();
     }
     $photo_url = $member->ProfilePhotoUrl($width = 100, $generic_photo_type = 'speaker');
     $body = file_get_contents($photo_url);
     $ext = 'jpg';
     $response = new SS_HTTPResponse($body, 200);
     $response->addHeader('Content-Type', 'image/' . $ext);
     return $response;
 }
 public function load($request)
 {
     $response = new SS_HTTPResponse();
     $response->addHeader('Content-Type', 'application/json');
     $items = call_user_func($this->source, $request->getVar('val'));
     $results = array();
     if ($items) {
         foreach ($items as $k => $v) {
             $results[] = array('k' => $k, 'v' => $v);
         }
     }
     $response->setBody(Convert::array2json($results));
     return $response;
 }
Ejemplo n.º 26
0
 public function returnToBrowser()
 {
     if ($this->ExternalLink) {
         return $this->ExternalLink;
     } else {
         if ($this->FileID) {
             if ($file = $this->File()) {
                 return $file->AbsoluteURL();
             }
         } else {
             $content = base64_decode($this->Content);
             $response = new SS_HTTPResponse($content, '200');
             $response->addHeader('Content-Description', 'File Transfer');
             $response->addHeader('Content-Type', $this->ContentType);
             if ($this->IsImage()) {
                 $response->addHeader('Content-Disposition', 'inline; filename="' . basename($this->FileName) . '"');
             } else {
                 $response->addHeader('Content-Disposition', 'download; filename="' . basename($this->FileName) . '"');
             }
             $response->addHeader('Content-Length', $this->Length);
             $response->output();
         }
     }
 }
Ejemplo n.º 27
0
 /**
  * Require basic authentication.  Will request a username and password if none is given.
  *
  * Used by {@link Controller::init()}.
  *
  * @throws SS_HTTPResponse_Exception
  *
  * @param string $realm
  * @param string|array $permissionCode Optional
  * @param boolean $tryUsingSessionLogin If true, then the method with authenticate against the
  *  session log-in if those credentials are disabled.
  * @return Member $member
  */
 public static function requireLogin($realm, $permissionCode = null, $tryUsingSessionLogin = true)
 {
     $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test();
     if (!Security::database_is_ready() || Director::is_cli() && !$isRunningTests) {
         return true;
     }
     $matches = array();
     if (isset($_SERVER['HTTP_AUTHORIZATION']) && preg_match('/Basic\\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches)) {
         list($name, $password) = explode(':', base64_decode($matches[1]));
         $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
         $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
     }
     $member = null;
     if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
         $member = MemberAuthenticator::authenticate(array('Email' => $_SERVER['PHP_AUTH_USER'], 'Password' => $_SERVER['PHP_AUTH_PW']), null);
     }
     if (!$member && $tryUsingSessionLogin) {
         $member = Member::currentUser();
     }
     // If we've failed the authentication mechanism, then show the login form
     if (!$member) {
         $response = new SS_HTTPResponse(null, 401);
         $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\"");
         if (isset($_SERVER['PHP_AUTH_USER'])) {
             $response->setBody(_t('BasicAuth.ERRORNOTREC', "That username / password isn't recognised"));
         } else {
             $response->setBody(_t('BasicAuth.ENTERINFO', "Please enter a username and password."));
         }
         // Exception is caught by RequestHandler->handleRequest() and will halt further execution
         $e = new SS_HTTPResponse_Exception(null, 401);
         $e->setResponse($response);
         throw $e;
     }
     if ($permissionCode && !Permission::checkMember($member->ID, $permissionCode)) {
         $response = new SS_HTTPResponse(null, 401);
         $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\"");
         if (isset($_SERVER['PHP_AUTH_USER'])) {
             $response->setBody(_t('BasicAuth.ERRORNOTADMIN', "That user is not an administrator."));
         }
         // Exception is caught by RequestHandler->handleRequest() and will halt further execution
         $e = new SS_HTTPResponse_Exception(null, 401);
         $e->setResponse($response);
         throw $e;
     }
     return $member;
 }
 public function index(SS_HTTPRequest $r)
 {
     $username = $r->postVar('username');
     $password = $r->postVar('password');
     if (!$username || !$password) {
         return $this->httpError(400, "You must provide 'username' and 'password' parameters in the request");
     }
     if ($member = Member::get()->filter('Email', $username)->first()) {
         if ($member->checkPassword($password)) {
             $member->assignToken();
             $member->write();
             $response = new SS_HTTPResponse(200);
             $response->addHeader('Content-type', 'application/json')->setBody(Convert::array2json(array('token' => $member->AuthenticationToken)));
             return $response;
         }
     }
     return $this->httpError(403, "Invalid login");
 }
 /**
  * Filter executed AFTER a request
  *
  * @param SS_HTTPRequest $request Request container object
  * @param SS_HTTPResponse $response Response output object
  * @param DataModel $model Current DataModel
  * @return boolean Whether to continue processing other filters. Null or true will continue processing (optional)
  */
 public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model)
 {
     $code = $response->getStatusCode();
     $error_page_path = Director::baseFolder() . "/errors_pages/ui/{$code}/index.html";
     if (!$request->isAjax() && file_exists($error_page_path)) {
         //clean buffer
         ob_clean();
         $page_file = fopen($error_page_path, "r") or die("Unable to open file!");
         $body = fread($page_file, filesize($error_page_path));
         fclose($page_file);
         // set content type
         $response->addHeader('Content-Type', 'text/html');
         $response->setBody($body);
         $response->setStatusCode(200);
         return true;
     }
     return true;
 }
 /**
  * Unlink the selected records by setting the foreign key to zero
  * in both Stage and Live tables.
  *
  * @param SS_HTTPRequest $request
  * @return SS_HTTPResponse List of published record IDs
  */
 public function versionedunlink(SS_HTTPRequest $request)
 {
     $ids = $this->getRecordIDList();
     // remove the selected entries from Stage.
     $this->gridField->list->removeMany($ids);
     // Unpublish the unlinked records.
     // This is potentially destructive, but there's no other "good" way to do this.
     // When a unlinked record gets added to another page, the only way to "activate" the
     // record is to publish it.. so the published version will be overwritten anyway!
     foreach ($this->getRecords() as $record) {
         if ($record->hasExtension('Versioned')) {
             $record->deleteFromStage(Versioned::get_live_stage());
         }
     }
     $response = new SS_HTTPResponse(Convert::raw2json(array('done' => true, 'records' => $ids)));
     $response->addHeader('Content-Type', 'text/json');
     return $response;
 }